Next Item in Collection

I see how to use the link_to_next_item or link_to_previous_item can be used to link to the next/previous item in the entire archive. But, is there a way to link to the next/previous item in the collection and avoid items that aren't in that particular collection? I'm pretty weak at php so any guidance would be much appreciated. Thanks!!

Right now, link_to_next_item() and link_to_previous_item() don't know about how you found a particular item. Which is to say, next/previous runs through the whole archive and isn't based on a particular collection or tag, etc. That might be a good thing to add in a future release, but it would also work as a plugin.

I am building a theme for Omeka that relies on this concept of knowing how an item is found. I have added a title that reflect the query i.e. the items/browse/tag page would say something like "Items tagged with yourTag"

However on the items/show page I want 'link_next_item()' to link to the next item in the "Items tagged with yourTag" subset. I achieved this in 0.9 with some nasty hacks which were ok for my small install but far from scalable or maintainable.

0.10 looks like I can achieve the same result by using 'set_items_for_loop()'. I notice a comment to this effect in NewThemeFunctions line 921? However using 'set_items_for_loop()' to return the same set from, for example, items/browse/tag/yourTag/page/2 page runs into the problem that the first item does not have a previous item in the loop yet does have one for the entire set.

I have an idea on how to approach this but my first question is how much of a load does 'set_items_for_loop()' put on the db / server? If the answer is not much then the per_page parameter could be set to total_results - this would return to full set and be pretty easy to deal with.

Otherwise my plan B involves a bit of messing around. My plan would be to get an array using 'set_items_for_loop()' where per_page = n and merge it with the "pages" either side, ie 'set_items_for_loop()' where per_page = n+1, and n-1. I hope I have explained this OK.

Can you give me some guidance on how to approach this problem.


Actually, I'm not sure that I understand your proposed solution, but maybe I can help.

set_items_for_loop() takes as an argument a set of Item objects that have been retrieved from the database somehow and used for the loop (primarily on the items/browse page, but it can also be on the home page or anywhere else you would see a list of items). Since you are only displaying one item (and to a certain extent, the one before and after it) you don't need to use this function.

In order to customize the behavior of link_to_next_item()/link_to_previous_item(), you should write your own custom helper functions, which you can then put in the custom.php file of your theme so you don't worry about having to hack your solution into the application/helpers/ files.

As you figured out, link_to_next_item() only retrieves the very next item in the database, and you need it to retrieve the next one with a certain tag. The function current looks like this:

function link_to_next_item($text="Next Item -->", $props=array())
    $item = get_current_item();
	if($next = $item->next()) {
		return link_to($next, 'show', $text, $props);

You need some custom code in place of $next = $item->next() that will retrieve the next item based on a set of tags. It looks like you can use some of the existing code in the ItemTable class. Try something like this (may require some tweaking):

$table = get_db()->getTable('Item');
$select = $table->getSelect();
$table->filterByTags($select, array('one tag', 'another tag'));
$select->where(' > ?', get_current_item()->id);
$nextItem = $table->fetchObject($select);

Let me know how that works for you.

Thanks. This works fine. To find the previous item I used the following

table = get_db()->getTable('Item');
$select = $table->getSelect();
$table->filterByTags($select, array('one tag', 'another tag'));
$select->where(' < ?', get_current_item()->id);
$select->order(' DESC');
$previousItem = $table->fetchObject($select);