Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using get_pages() function to get all subpages from a page like this:

$childrens = get_pages(array('child_of' => 7, 
                             'sort_column' => 'post_date', 
                             'sort_order' => 'DESC', 
                             'depth' => -1));

This is supossed to get me a list of all pages (no matter if direct children, children of children, etc) orderen by the date they were created, but instead its showing me the list of pages in a strange order, here's the output when I run a foreach on the $childrens array and output the post_date on each:

2011-05-10 15:37:03
2011-05-10 15:35:59
2011-05-10 15:01:18
2011-05-10 17:12:32
2011-05-10 15:00:47
2011-05-10 14:00:14
2011-05-11 04:19:08
2011-05-10 23:52:54
2011-05-10 15:20:12
2011-05-10 15:05:10

As you can see they're not ordered by date descending, I tried using other options in the sort_column key but none seemed to e working correctly, does anyone know what could be wrong?

Thanks in advance!

share|improve this question
add comment

5 Answers

This is indeed an error, and probably caused by the child_of argument.

Because child_of requests the whole subtree of the given page (not only the direct children, but also children of those children and so on), WordPress first queries for all the pages and then selects a subset of those pages. The first query respects the order, but the second subselection messes this up by just using array_merge().

I have created a Trac ticket for this.

share|improve this answer
    
Beat me by seconds :) - Glad, you found it! +1 –  kaiser May 11 '11 at 10:08
    
I see thanks I hope there's a workaround for this at least –  javiervd May 11 '11 at 14:19
add comment

Some sidenotes while searching for a solution:

  • Reading through this ticket at trac, the arguments will change with a coming version to align with the get_posts() arguments.
  • You can find the function at /core-root/wp-includes/post.php line 3.284

Questions:

  • Are you sure, you're not using 'include' as argument? This sets 'child_of' to zero.

Try this and tell me about the result you get. Maybe you can re-order them there until you got a satisfying solution:

function wpse16921_get_pages( $pages, $r )
{
    echo '<pre>'; print_r($pages); echo '</pre>';
}
add_filter( 'get_pages', 'wpse16921_get_pages' );

Edit

Here you got a set of functions that help you working around until the patch has gone into a wp release:

// First: Loop through your pages inside the filter
function wpse16921_get_pages_filter( $pages, $r )
{
    # echo '<pre>'; 
        foreach ( $pages as $page )
        {
            $page = (array) $page;
            $pages_temp[$page['post_date']] = $page;
        } 
        # echo 'Before manipulation: '; print_r($pages_temp);
        $pages_temp = '/* handle sorting of your new date keys over here */';
        # echo 'After manipulation: '; print_r($pages_temp);
    # echo '</pre>';

    return $pages = $pages_temp;
}

// Second: Attach the filter to the appropriate hook
function wpse16921_get_pages_filter_hook()
{
    add_filter( 'get_pages', 'wpse16921_get_pages_filter', 10, 2 );
}
add_action( 'after_setup_theme', 'wpse16921_get_pages_filter_hook', 0 );

// Call your pages
function wpse16921_get_pages_call() 
{
    $pages = get_pages();

    # >>>> start modifying/preparing the output
    echo '<pre>'; 
        foreach ( $pages as $date => $page )
            echo $date.'<br />';     
    echo '</pre>';
    # <<<< end modifying/preparing the output
} 
add_action( 'after_setup_theme', 'wpse16921_get_pages_call' );
share|improve this answer
    
I'm not using include, in fact the pages I'm getting are all childrens of my page with ID "7" this part works fine, the problem is just the ordering. I have no idea how to order them "manually" after :( –  javiervd May 11 '11 at 14:26
    
@javiervd - i showed you the filter. Try to drop this into your functions.php file and take a look at the output. Then you can re-order it without a problem using the native php array sort functions. Just modify $pages in there to your needs. Sidenote: The filter runs before the output of the get_pages() function, so you can interact with the result before retrieving it. Should get you the desired result. –  kaiser May 11 '11 at 15:05
    
@javiervd - See Edit for a tested work around. –  kaiser May 11 '11 at 15:28
add comment

Im not sure how to remedy the problem with WordPress - im getting the same results as you are, but this can be achieved using the PHP functions sort() and rsort() and a little bit of dirty work using foreach.

rsort() would sort an array in reverse order and sort() from lowest to highest.

Try this:

<?php 
    $children = get_pages( array( 'child_of' => 7 ) );

    foreach ( $children as $child ) {
        // get post date of each page/child
        $post_date = $child->post_date;
        // populate the array with the post dates
        $dates[] = $post_date;

    }

    // Sort the array in reverse order
    rsort( $dates ); // or sort( $dates ) for the lowest to highest

    foreach ( $dates as $date ) {

        echo $date;
        echo '<br />';

   }
?>
share|improve this answer
    
That seems it'd work, the only problem is that I need all the page's data not only the date (I printed the date in my question so you could better see what I meant) How can I tweak your answer to get all the pages data ordered by date? –  javiervd May 11 '11 at 14:21
    
If you still need it to be tweaked, let me know. I believe your latest answer accomplishes it in a much orderly fashion. –  VicePrez May 11 '11 at 15:20
    
You could simple use keys and values $dates[$post_date] = $child; to get the date & the data. See my filter example above. –  kaiser May 11 '11 at 16:00
1  
@kaiser looks more robust. I'm adding it as a snippet +1. –  VicePrez May 11 '11 at 19:08
    
Any solution? Please mark something as solved or add your own answer and mark this one as solution. –  kaiser Oct 24 '11 at 12:58
add comment
up vote 3 down vote accepted

after looking around a bit I managed it to make it work using the following:

function sort_pages_by_date($a, $b){
    if ($a->post_date == $b->post_date)
        return 0;
    if ($a->post_date < $b->post_date)
        return -1;
    return 1;
}

function get_filtered_news($pages) {
    usort($pages, 'sort_pages_by_date');
    rsort($pages);

    return $output;
}

add_filter('get_pages', 'get_filtered_news');

I'm using the usort function to sort the array by the objects' date, and the reversing it to get it ordered from newest to oldest, thanks all for pointing me in the right direction I voted all you guys up.

share|improve this answer
1  
Indeed, usort() is your friend. I thought you needed to convert the date back to a Unix timestamp, but of course a string comparison works too. Why do you do the extra rsort() instead of switching the -1 and 1 outputs in your comparison function? –  Jan Fabry May 11 '11 at 14:48
    
Yeah that works too, I never used usort() before so I used a similar example I found online, but I'm changing it now thanks! –  javiervd May 11 '11 at 14:52
add comment

use get_children instead - replace child_of with post_parent / sort_column / sort_order - ie.:

$nav_args = array(
'sort_column' => 'date', 
'sort_order' => 'desc', 
'post_parent' => get_the_ID(),
);

$list = get_children( $nav_args ); // list results ##
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.