0

I'm trying to show child-pages in a certain order, in a list.

This is my code to output the pages as a list:

$parent = $wp_query->post->ID;
wp_list_pages("title_li=&child_of=$parent&echo=1&sort_column=post_title" );

Now I want to show the first four of the pages in a particular order:


  1. Summary
  2. Info
  3. Groups
  4. Entries
  5. Other Page
  6. Another Page

In other words, Summary, Info, Groups, Entries should be shown in that order (providing they exist), and other pages below. How would I achieve that? I've noticed there are parameters to include and exclude pages using wp_list_pages. These parameters take page ID numbers as variables, so I perhaps the pseudo-code is:


  1. make a array of the IDs of child pages which include Summary, Info, Groups, Entries in their titles, and order these correctly
  2. make a array of the IDs of child pages which don't include the 4 pages
  3. join these arrays together
  4. print out the html of the array of page IDs

4 Answers 4

5

Based on your comments here is another option , using wp_list_pages and without having to work with arrays and pulling content manually, I'm leaving out a bunch of the options, just the bare essentials.

<ul>
<?php
  $priority_pages = '5,1,3,7';
  wp_list_pages(array('include' => $priority_pages);
  wp_list_pages(array('exclude' => $priority_pages);
?>
</ul>

since, wp_list_pages, just gives you the <li> elements, you can use this function a couple of times to pull all the pages you need. So now you can only get the pages you want out the top, and then pull in the rest. You can use all the rest of the options to sort and filter the tree like normal (Note, I like using arrays instead of the string, code looks cleaner IMO).

Read the codex page for wp_list_pages for more options

To get a list of ID's with what you want.

<?php
  $my_wp_query = new WP_Query();
  $all_wp_pages = $my_wp_query->query(array('post_type' => 'page'));

  $parent = $wp_query->$post-ID;
  $children = $get_page_children($parent, $all_wp_pages);
?>

What we have now is an array in $children with the information we need. What I would at this point is loop through $children looking for the filed post_title to equal what you want, and store that ID. With these store as an array, you would be able to use those with the include, exclude functions of wp_list_pages

So not 100% complete, but it will get you started

<?php
  $priority_pages_a = array();
  foreach($children as $child) {
    if(strpos($child->post_title,"Summary") {
      $priority_pages_a[0] = $child->ID;
    } elseif (strpos($child->post_title,"Info") {
      $priority_pages_a[1] = $child->ID;
    }
  }

  $priority_pages = implode(",",$priority_pages_a);

?>

What we've done is created an array that puts the ID into the array order that you want. Then implodes that into a comma separated string, for which you can use the wp_list_pages to get the ones you want / need.

The get_page_children doesn't touch the database, but the get all pages does :/ so it's a wash.

I haven't tested this code altogether, but it should work.

Also note there is a get_page_by_title, so if your titles are exactly 'Summary' then you can use it to get the ID, but in your question you said contains, so I went with this route instead.

5
  • Thanks, but how do I build the list of priority_pages IDs?
    – cannyboy
    Commented Sep 2, 2010 at 15:24
  • The priority page IDs are just the IDs of the four pages you want listed first. You can figure out the IDs when you're editing the page: it is in the URL as "?post=..."
    – Doug
    Commented Sep 2, 2010 at 15:40
  • It's just a comma separated string. The ID's are assigned when the pages are created. And unless those pages are deleted they will never change. So since you want the 4 or 5 pages on top, I'm assuming those 4 or 5 will never change. You could though, create a custom attribute on the parent page, holding the ID's so a semi-competent person working the backend, could add ID's to move to the top of the list. Commented Sep 2, 2010 at 15:41
  • what I meant was that I want to generate the list of IDs dynamically, since I don't want the user who is creating content to worry about such things... in other words I would need to grab the IDs for pages whose titles contain Summary, Info, Groups, & Entries .. which are child pages of the page in questions.. and then do the include and exclude thing with wp_list_pages..
    – cannyboy
    Commented Sep 2, 2010 at 16:32
  • Not a clean way of doing , since you want to do it if it can contain, but I think I've hacked something up, adding it to answer Commented Sep 2, 2010 at 17:23
2

The wp_list_pages() function accepts an argument for 'sort_column', this defaults to menu_order then post_title. If you quick_edit the pages, you can set the order for each page.

1
  • Thanks. Is there a way to do it in code only, so the order does not rely on the order in page's order attributes? menu_order and page_title are just for alphabetical...?
    – cannyboy
    Commented Sep 1, 2010 at 19:48
1

If this is for a menu, I would suggest you you look at the new Nav Menu system in Wordpress 3.0. You can create a menu from any group of pages, posts, or even external links.

You can get to it in the admin section at Appearance → Menus

2
  • That's close to a solution, but as far as I can see that still means that it is not automated. For the people adding content to the site - I don't want them to have to create menus each time thay add a few pages.
    – cannyboy
    Commented Sep 1, 2010 at 21:47
  • Might want to add that requirement to the question, if pages are going to be updated a lot. 90% of the sites I build, the pages aren't added or deleted after the content is in there. At least not on a regular basis Commented Sep 2, 2010 at 14:55
0

You could have 2 separate menus, as you already mention yourself.

Use the list_pages twice. Once including your fixed pages and using the menu order as a parameter. And once using exclude as a parameter, excluding the items you use in your first menu. Just make sure to get them in one UL.

Alternatively, you could decide to make a list_pages for each separate page of the first four pages. Not sure if this is considered a neat or clean solution, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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