WordPress: How to style wp_list_pages

Posted on: 09.25.08

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:

<ul>
    <li class="page_item current_page_parent"> 
        <a href="#">Link</a>
    </li>
    <li class="page_item"> 
        <a href="#">Link2</a>
    </li>
</ul>


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:

1
2
3
4
5
6
7
8
9
10
<?php
    $my_pages = wp_list_pages('echo=0&title_li=');
    $var1 = '<a';
    $var2 = '<span class="testClass"><a';
    $var3 = '</a';
    $var4 = '</a></span>;';
    $my_pages = str_replace($var1, $var2, $my_pages);
    $my_pages = str_replace($var3, $var4, $my_pages);
    echo $my_pages;
?>
1
2
3
4
5
6
7
8
9
10
11
12
<ul>
    <li class="page_item current_page_parent"> 
        <span class="testClass">
            <a href="#">Link</a>
        </span>
    </li>
    <li class="page_item">
        <span class="testClass">
            <a href="#">Link2</a>
        </span>
    </li>
</ul>

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
    $my_pages = wp_list_pages('echo=0&title_li=');
    $var1 = '<a';
    $var2 = '<span class="testClass"><a';
    $var3 = '</a';
    $var4 = '</a></span>;';
    $var5 = 'Wordpress';
    $var6 = '<h10>Wordpress</h10>';
    $my_pages = str_replace($var1, $var2, $my_pages);
    $my_pages = str_replace($var3, $var4, $my_pages);
    $my_pages = str_replace($var5, $var6, $my_pages);
    echo $my_pages;
?>

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:

1
2
3
4
5
6
7
<?php
    $my_pages = wp_list_pages('echo=0&title_li=');
    $var1 = '/li><li';
    $var2 = '/li> whatever you want to add here <li';
    $my_pages = str_replace($var1, $var2, $my_pages);
    echo $my_pages;
?>

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php  
    $has_subpages = false;  
    // Check to see if the current page has any subpages  
    $children = wp_list_pages('&child_of='.$post->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");  
    }  
?>  
<!--Check to see if we have anything to output-->  
<?php if ($children) { ?>  
    <div class="subNav">
	<ul>
    	    <li>
            <!--modified wp_list_pages-->
	        <?php
                    $var1 = '<a';
                    $var2 = '<span class="testClass"><a';
                    $var3 = '</a>';
                    $var4 = '</a></span>';
                    $children = str_replace($var1, $var2, $children);
                    $children = str_replace($var3, $var4, $children);
                   echo $children;
                ?>
                <!--end of modified wp_list_pages-->
            </li>
        </ul>  
    </div><!--subNav-->  
<?php } ?>

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

 
 
 

Comments (30)

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?

Ben added these words on Feb 04 09 at 06:19

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

Ben added these words on Feb 04 09 at 06:21

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

rocksea added these words on Feb 23 09 at 11:55

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

RaiulBaztepo added these words on Mar 30 09 at 11:25

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

marc added these words on Apr 24 09 at 15:10

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

marc added these words on Apr 24 09 at 16:06

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.

Rick added these words on Apr 26 09 at 10:45

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?

Maciej Wantusiak added these words on Apr 26 09 at 11:57

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.

Rick added these words on Apr 26 09 at 12:15

@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.

marc added these words on Apr 28 09 at 10:38

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

Jessicajelo added these words on May 10 09 at 17:40

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

ArianaVent added these words on May 13 09 at 12:39

Sure :)

Maciej Wantusiak added these words on May 13 09 at 22:00

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).

Muham added these words on Aug 14 09 at 14:52

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!

Maciej Wantusiak added these words on Aug 14 09 at 18:53

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 :)

zezinozen added these words on Sep 16 09 at 21:28

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

Maciej Wantusiak added these words on Sep 17 09 at 12:52

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);

Marcy Sutton added these words on Sep 29 09 at 23:18

When I am using:
whatever you want to add here

How can I avoid it between the subpages?

JohnnyPea added these words on Oct 27 09 at 09:33

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

Maciej Wantusiak added these words on Oct 27 09 at 12:24

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

Edward Rpss added these words on Feb 08 10 at 18:02

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

Maciek added these words on Feb 08 10 at 20:49

Very thanks my friend!

[]´s

Andre Lima added these words on Feb 11 10 at 14:48

Welcome :)

Maciek added these words on Feb 11 10 at 14:55

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.

cposada added these words on Apr 02 10 at 18:09

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

Maciek added these words on Apr 03 10 at 20:02

Thanks man! That just saved me. :-)

Ronny added these words on Apr 03 10 at 23:40

Thanks! Plenty of great solutions!

יחסי ציבור added these words on Apr 10 10 at 17:06

You are welcome :)

Maciek added these words on Apr 10 10 at 23:58

how to mix pages and categories in the menu.

Abid Ali added these words on Apr 12 10 at 08:59
Add a Comment




XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">