WordPress: How to style wp_list_pages

September 25, 2008


Applying styling to dynamically generated lists (or any content) in WordPress.
Recently, I was in a need of changing the default outcome of the <?php wp_list_pages(‘arguments’); ?> tag in WordPress – as you’ll see, it’s a really simple procedure. I needed to change the wp_list_pages outcome, but this technique can be applied to other tags as well.

On default, after calling this script, we recieve something along these lines:


On some ocasions you will probably wish to add a <class> or a <span> to each link. Too bad that the wp_list_pages() tag doesn’t take as arguments strings to go before and after each link.

So, this is the way that you can go around this problem:

  • Find your wp_list_pages() tag in the template
  • Change the <?php wp_list_pages(‘arguments’); ?> into the following:
  • The above looks for strings $var1 and $var3 and changes them with $var2 and $var4, respectively in the $my_pages variable (which is the outcome of the wp_list_pages() tag)
  • It is important to pass echo=0&title_li= as arguments because the output would be otherwise not stored as the &my_pages variable (echo=0) and the list would have a title – typically “Pages” (title_li=)
  • After this operation the previous code looks like this:

And this is it! Simple yet powerful. This litlle trick can have many applications (like, for example, creating a hover effect with some script on the menu) and it is up to you what to do with it next. If you are going to use it for something – it’s always appreciated if you could share your ideas.

Update! I’ve noticed that a lot of interest is paid to this post. If some of you would like me to explain something in more detail, then ask for it in a comment. I hope that I will be able to help :)
Update 2! I have written a new post about modifying the outcome of the wp_list_pages tag – have a look here: WordPress: how to dynamically modify the output of the wp_list_pages tag
Take care!

Maciek

Q1: How would one style an element inside a link?
Here is a little modification of the script to include styling of parts of a link, as suggested by Ben, although Ben’s problem was a little more complex.
The problem is how to style one part of a link, for example: The link is “WordPress Rocks!” and we want to apply style only to the word “WordPress”, to be… mmmm…. bold and green! That’s how to do it:

As you can see, I have wrapped the word “WordPress” in <h10> tag. Why not <span>? Because for what I know it creates a bunch of gibberish as outcome (try it and you’ll know it). <h10>, or any <h> tag which is not being used, is a simpler solution.
Don’t forget to style it in your CSS file. If the <h> tag breaks your line, use “display:inline;” in your style sheet to fix it.

h10 {
    font-weight: bold;
    color: Green;
    display: inline;
}

Oh, and I am assuming that the word “WordPress” is a constant output from the wp_list_pages(). This means, that wp_list_pages() always outputs the word “WordPress”.

Q1: How to add a line between to <li> elements?
Here’s how:

UPDATED!!! 25.04.2009


Q2: How do you create a dynamic submenu?
Marc Wiest was kind to share wit us a solution to this problem, based on the above hack and work by Gabriel Svennerberg.
Here is how to create a dynamic submenu:

ID.'&echo=0');  
    if($children) {  
        $has_subpages = true;  
    }  
    // Reseting $children  
    $children = "";  
    // Fetching the right thing depending on if we're on a subpage or on a parent page (that has subpages)  
    if(is_page() && $post->post_parent) {  
        // This is a subpage  
        $children = wp_list_pages("title_li=&include=".$post->post_parent ."&echo=0");  
        $children .= wp_list_pages("title_li=&child_of=".$post->post_parent ."&echo=0");  
    } else if($has_subpages) {  
        // This is a parent page that have subpages  
        $children = wp_list_pages("title_li=&include=".$post->ID ."&echo=0");  
        $children .= wp_list_pages("title_li=&child_of=".$post->ID ."&echo=0");  
    }  
?>  
  
  
      

I didn’t get a chance to test out this code (but it looks alright to me and it works for Marc), so if you run into any problems, let me know in the comment.
Also you are welcome to share your problems and solutions.
Again, thanks Marc!

If you found this post interesting, have a look at the one about dynamically modifying the wp_list_pages output

33 Comments

  1. Ben says:

    What if I have a link to a page with two words and I want to assign a class to only 1 word? For example, the page name is “magic tricks” and I want to apply some CSS styling only to the word “magic” but not the word trick. Yet, with wp_list_pages they will be sent from WordPress as 1 item. This is pretty tricky and I haven’t had any luck yet with getting it to work. Any ideas?

  2. Ben says:

    In my above comment, I wanted the to look like code, but I think I did it wrong. Can you edit it? Sorry. Thanks!

  3. rocksea says:

    great tip on styling the wp_list_pages function! thanks a lot :)

  4. RaiulBaztepo says:

    Hello!
    Very Interesting post! Thank you for such interesting resource!
    PS: Sorry for my bad english, I’v just started to learn this language ;)
    See you!
    Your, Raiul Baztepo

  5. marc says:

    wassup,

    nice post! i wandering though! how do i hack the children in the same way? (my children a separate from the the wp_list_pages tag) thanks!

    marc

  6. marc says:

    hey dude,

    i found a nice solution for my question above. i’d like to post it here but wp would eat up the code snippet i have worked it out with the help of this tutorial (code snippet) http://tiny.cc/svennerberg. contact me if you are interested.

    greetz marc

  7. Rick says:

    I want to have a selected parent page not link to anything but the children in the drop down actually be links (no anchor text). I have seen a lot of people asking for this but have not found any answers even after extensive searching.

    Someone has said that it can’t be done with wp_list_pages(). You need to use get_pages instead. Either way, this is beyond my abilities. Any suggestions? Thanks.

  8. I’m away for couple of days, but I’ll look into it when I’m back… In the mean time maybe someone else will have a solution?

  9. Rick says:

    Clarification of my request: I am trying to have a selected parent page in the menu not link to its page so that the user has to select one of the child pages in the drop down menu for that item.

  10. marc says:

    @rick,

    i don’t quite understand your question. but if your question is about the submenu update from the 25th of april, it would be best to look for help at http://www.svennerberg.com/2009/02/creating-a-submenu-in-wordpress/comment-page-1/#comment-3602 that’s where i got the submenu snippet from. i don’t know much about php, so i can’t help you. i just got lucky playing around with these two snippets. good luck.

  11. Jessicajelo says:

    I love it! That is way cool man! The steps weren’t that complicated too, which is great.

  12. ArianaVent says:

    Great! Thank you very much! I always wanted to write in my blog something like that. Can I take part of your post to my site? Of course, I will add backlink? Regards

  13. Muham says:

    Part2 doesn’t work. It doesn’t give you a completely serparated menu/submenu. The menu only shows the parent of the submenu when either the parent is selected or the child is selected. Horribly broken code it is.

    You need to show the main nav 100% of the time and the children only if they exist. Then when a child is selected, both menu need to still appear (not disappear).

  14. Muham,
    Thanks for sharing this with us. I won’t get a chance to check this code and try to find a solution for at least a week, so in the mean time, if you find an answer, would you mind sharing it with others?
    Cheers!

  15. zezinozen says:

    Hello,

    Thanks very much for this tut!.. a nooby question.. how can I output the list in two columns, I have 56 pages and it is a lot of scroll.. I would like to limit and then go to another column.. any help really appreciate and please I am learning :)

  16. Hmmm… Depending on how you want to divide the list (in half, or after a certain number of positions) I would try to write a script that divides the output of wp_list_pages into an array (split at every < li > ), so you know instantly the amount of the entries, and output them one by one, inserting a closure of the first column and opening of the second one after a certain number of outputs.
    Check out my other post on this subject: http://www.wantusiak.com/wordpress/wordpress-modify-wp_list_pages – there I describe how to divide an output into an array

  17. Marcy Sutton says:

    The first example for re-outputting wp_list_pages(‘args’) does not affect my sidebar at all. I tried it first with my code, and then yours — and it has no effect on the Pages child . I am putting it in sidebar.php, do not have a dynamic sidebar enabled, so it should work but doesn’t. I am running WordPress 2.8.4.


    $my_pages = wp_list_pages('title_li=Pages');
    $var1 = '<a';
    $var2 = '» <a';
    $my_pages = str_replace($var1, $var2, $my_pages);

  18. JohnnyPea says:

    When I am using:
    whatever you want to add here

    How can I avoid it between the subpages?

  19. Hi Johnny,
    Can you clarify what exactly do you want to avoid between the subpages?
    Thanks

  20. Edward Rpss says:

    Useful post – worth noting that since WordPress 2.7 there are parameters to the wp_list_pages to do this:
    link_before and link_after

  21. Maciek says:

    Thanks!
    At least it was worth something for some time :)

  22. Andre Lima says:

    Very thanks my friend!

    []´s

  23. cposada says:

    Thank you for this write up. I used its methods to change the markup for a site I was working on. Unfortunately, the link_before and link_after do not work for my needs. I needed to change the markup within the anchor tag itself. I was then able to use the code at http://www.cssplay.co.uk/menus/snazzymenu.html in order to create rounded corners without images. I still need to tidy up my code a bit but it works flawlessly. Thank you for the direction you turned me to.

  24. Maciek says:

    I am glad that I could be helpful! :)
    Good luck with your design!
    All the best,
    Maciek

  25. Ronny says:

    Thanks man! That just saved me. :-)

  26. Thanks! Plenty of great solutions!

  27. Maciek says:

    You are welcome :)

  28. Abid Ali says:

    how to mix pages and categories in the menu.

  29. flutch says:

    hi,

    thanks, your trick helped me a lot !

    i have to say, anyway, that for Q1 example to work for me, i had to add a unix line feed (LF) between ‘/li>’ and ‘<li' within $var1.
    if i didn't, no replacement was done.
    a classic line break couldn't work…

    thanks again for it, your method will be very useful for any menu customization !

    alex

  30. Maciek says:

    Hi Alex!
    I’m glad that I could help :)
    This post is so old, that I am still surprised that this little hack works.
    Thanks for your input.
    All the best,
    Maciek

  31. PAul says:

    Is anyone else having an issue with the child page that you are viewing won’t display in the menu as active?

Leave a Comment