Search and Ordering of Records

When you search for a term, you get a list of results on the item browse page, and the term you searched is displayed in the search box. When you view an individual item of this search, and then click next or previous links, you do not get the next or previous item in the search. Instead you get the next or previous item ID in the entire collection. Also the search term is gone from the search box.

However I noticed if I added the search string from the url of the item browse page to the item show page the search term appears in the search box.

So omeka/items/show/123 is now omeka/items/show/123?search=search+term&submit_search=Search

Would it be possible to create a conditional statement on the item browse page so that if the results are generated by a search to append the search url info in the link to the item. Then on the item page create a loop through the searched items, and have the next and previous links work off that loop.

Is there some glaring error to my line of thinking, or would this be possible and not too complicated to implement?

This is probably going to be a little more complicated than you're thinking.

You can definitely get the items/browse page to output links with the GET parameters appended, but I'm not totally sure that those parameters wouldn't affect how the item show pages get displayed.

Even so, that would really only handle getting the search string into the search box. To make the Next and Previous links work over the search results in the way you're describing, you'd have to re-do the search on every item show page and look through the results to figure out where you are now. You probably don't want to add all those extra searches to the load on your site.

There's another route you could take, by storing the current search data in the user's session, so you wouldn't have to re-do the search to figure out what the next and previous items should be. Even this is a simplification because Omeka only retrieves the information about one page of items, so you'd have to know when to re-do the search to get the next page of results.

It's definitely a little more complicated than you're thinking.

I figured it would be more complicated, but I've pushed on anyway. On my show.php page I have the following:

<?php if($search=$_GET['search']):
$current=item('id');
$list=get_items(array('search'=>$search),total_results());
foreach ($list as &$value){
set_current_item($value);
$value=item('id');
}
$key = array_search($current, $list);
if ($key>0) $key=$key-1;
$output = array_slice($list, $key, 3);
$previous=current($output);
set_current_item(get_item_by_id($previous));
$previous=item_uri().'?search=';
$previous.=$_GET['search'].'&submit_search=Search';
echo '<a href="'.$previous.'">Previous</a><br />';
$next=next($output);
$next=next($output);
set_current_item(get_item_by_id($next));
$next=item_uri().'?search=';
$next.=$_GET['search'].'&submit_search=Search';
echo '<a href="'.$next.'">Next</a>';
set_current_item(get_item_by_id($current));
endif;
?>

So on omeka/items/show/123?search=search+term&submit_search=Search, I now have previous and next links that are search based. It needs to be cleaned up, and a few things fixed, but it seems to work. Currently this site is not live, so there are only a handful of people using it. In your post, you mention not wanting to add extra searches to the load of the site. Do you think what I have currently would create problems in that regard? Also if you have any suggestions for more succinct code, I would appreciate it.

I've modified the code above so that it works at the first and last record of a search.

<?php if($search=$_GET['search']):
$current=item('id');
$list=get_items(array('search'=>$search),total_results());
foreach ($list as &$value){
set_current_item($value);
$value=item('id');
}
$key = array_search($current, $list);
$lastkey=count($list)-1;

if ($key>0 && $key<$lastkey):
$newkey =$key-1;
$output = array_slice($list, $newkey, 3);
set_current_item(get_item_by_id($output[2]));
$next=item_uri().'?search='.$_GET['search'].'&submit_search=Search';
set_current_item(get_item_by_id($output[0]));
$previous=item_uri().'?search='.$_GET['search'].'&submit_search=Search';
echo '<ul class="item-pagination navigation"><li><a href="'.$previous.'">Previous Item</a></li>';
endif;

if ($key==0):
$output =array_slice ($list, $key, 3);
set_current_item(get_item_by_id($output[1]));
$next=item_uri().'?search='.$_GET['search'].'&submit_search=Search';
echo '<ul class="item-pagination navigation"><li></li>';
endif;

if($key<$lastkey):
echo '<li class="next"><a href="'.$next.'">Next Item</a></li></ul>';
endif;

if($key==$lastkey):
$newkey=$key-1;
$output = array_slice($list, $newkey, 3);
set_current_item(get_item_by_id($output[0]));
$previous=item_uri().'?search='.$_GET['search'].'&submit_search=Search';
echo '<ul class="item-pagination navigation"><li><a href="'.$previous.'">Previous Item</a></li></ul>';
endif;

set_current_item(get_item_by_id($current));
endif;
?>

Have you considered posting this (or any of your other tweaks) on the documentation wiki as recipes?

We're trying to collect these kinds of concrete pieces of code that might not work to be included in Omeka, but lots of people could find useful for their installations.

Moving to the wiki would also allow you (and others) to simply edit your code, without having to make multiple postings.

I've posted my solution under Using Search Results to Create Custom Next and Previous Links. Also is there a way to wrap code in the window, instead of having to scroll horizontally?

Thanks! Really appreciate it!

Unfortunately, I don't think that there's a way to make the code wrap. I agree that it'd be nice to adjust the UI to make it easier to read long lines of code.

The only way to wrap would be to break lines manually, but I wouldn't recommend it.

I've made some big changes to your code that should get rid of a lot of extra database calls and generally shorten the code quite a bit.

I still have concerns about scaling, particularly if you have a lot of search results, that first line that gets all the result items could easily start to consume lots of memory. For small-to-medium sites, it'll probably be fine though.

Thanks for cleaning up the code. However, I noticed it works for the first item chosen, but not items after selecting next or previous.

$previousLink = link_to_item('Previous Item', array(), 'show', $previousItem); does not include ?search='.$_GET['search'].'&submit_search=Search'; so it loses the search term after selecting Next or Previous.

I've made some changes that incorporated my code into yours. It now allows you to keep clicking next/previous and stay within the search results. Thanks again.

Ah, good catch. I knew there was a portion of your code I had lost in the translation.

I made an alternate change that should keep the search string (as well as any other part of the query string) there when going between the next/previous links.

The one thing my code really tries to avoid are the set_current_item and the get_item_by_id calls.

set_current_item is basically costless, but almost all the functions that deal with items let you pass the item you want to operate on as an argument, so you can avoid having to set and re-set the current item.

get_item_by_id isn't costless though. For every call to get_item_by_id, Omeka makes another database request to pull the data for that item. The get_items call already gets all the items in the results, so they can be directly accessed from the resulting array.

Doesn't seem to work, the search string is lost once you click next or previous.

Ack, ok now it should work.

The link_to function has an attractive parameter that lets you set the link's query string, but it doesn't work when you pass in something like an item.

Now it's back to making the link manually, just appending whatever query string is already there (and I actually tested it this time).

Thanks it works. I'll have to see if any of my other Omeka tweaks would make good recipes.