Jump to content

Sorting page array containing pages without the sort field


pogidude
 Share

Recommended Posts

This is my selector:

$items = $pages->find("template=talk|video,limit=10,categories={$page->categories},sort=speaker,sort=title");

echo renderItems($items);

echo $items->renderPager();

the "speaker" field is a page type field and it is not required, so some pages won't have a value - null, or whatever it is for pages type fields.

Now, the result would be sorted first by speaker - alphabetically - then by title. If the page doesn't have speaker, then it'll go on top of the array.

Unfortunately, that's not what I want. I'd like the pages without the speaker field to go after the pages with speaker fields... Sorted by title.

Is this possible with the api?

p.s. I'm totally loving the api and the selectors. I love how I don't need to specify page ids or have to be very specific on my selectors.. it just freakin' works! :D

Link to comment
Share on other sites

Hi pogidude,

Have you tried to reverse the sorting of speaker?

sort=-speaker

yes.. it now shows the pages with speaker field from Z-A (which unfortunately is not what I want), then the pages without the speaker field..

If not, you can always find first the pages with speaker, then the pages without speaker, and then merge them.

hmmmm.. how that *may* work.. how do I deal with the pagination? do it manually? can I feed a PageArray to renderPager() method?

Link to comment
Share on other sites

Allrighty,

then I'd go with diogos solution, though maybe soma or another pro comes up with a better idea ;)

$itemsWithSpeaker = $pages->find("template=talk|video,limit=10,categories={$page->categories},speaker.count>0,sort=speaker,sort=title");
if (count($itemsWithSpeaker) < 10) {
  $limit = 10 - count($itemsWithSpeaker);
  $itemsWithoutSpeaker = $pages->find("template=talk|video,limit={$limit},categories={$page->categories},speaker.count=0,sort=title");
  $itemsWithSpeaker->import($itemsWithoutSpeaker);
}
  • Like 1
Link to comment
Share on other sites

Solved the problem.

@wanze's and @diogo's ideas helped and I'm putting these below for anyone that might be looking :) of course improvements are welcome.

$limit = 10;

//we look for our desired pages with limit. this is to help with pagination later on.
$items = $pages->find("template=talk|video,limit={$limit},categories={$page->categories},sort=speaker,sort=title");

/**
 * Get all items without setting limit. query will put items WITHOUT speaker in beginning of array.
 * But, we want items WITHOUT speaker to go to end of array after all the items WITH speaker field.
 */
$all_items = $pages->find("template=talk|video,categories={$page->categories},sort=speaker,sort=title");

//get items without speaker from $all_items
$without_speaker = $all_items->find('speaker<1');

//filter out items without speaker from $all_items
$all_items->filter("speaker>0");

//append $without_speaker to $all_items so that items without speaker go to the end of array
$all_items->append($without_speaker);

/**
 * Now we deal with pagination. Since we're showing $limit items at a time, we need to know which
 * page number we are and slice a PageArray of new items from $all_items accordingly
 */
$start = ($input->pageNum - 1) * $limit;
$final_items = $all_items->slice($start,$limit);

/** NOTE: Count of $final_items should match count of $items **/

/**
 * Replace the original items with our new items.
 * We do this because we want to use renderPosts() - from Blog Profile which outputs pagination 
 * based on the given PageArray fed to the function. Otherwise, we could have just done the ff:
 *
 * $content = $final_items->render(); //or whatever render function
 * $content .= $items->renderPager(); //the pager is based off $items since that's the one with the limit
 */
foreach($items as $key => $item){
   $items[$key] = $final_items[$key];
}

//$content = renderMediaIndex($items);
$content = renderPosts($items,true);

include('./default-archive.inc');

one thing that could be improved is that double query in the beginning. I dunno.. just saying..

Link to comment
Share on other sites

by the way, you may notice that I'm doing this:

$without_speaker = $all_items->find('speaker<1');

instead of this:

$without_speaker = $all_items->find('speaker.count=0');

I'm doing that because using count selectors (speaker.count) doesn't seem to work on PageArrays that have already been set.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...