Folding menu for WordPress pages using jQuery

jQuery folding menu for WordPress

Let’s talk about a simple technique to create folding or collapsible menus for the WordPress Pages widget. A while ago I was doing some coding for a IT Solutions site and they had a large ‘Services’ page with an introduction and 6 sections. They needed a parent page for the intro and 6 child pages and they didn’t wanted to show all the pages and subpages at once. I thought this would be an excellent job for jQuery and a collapsible or folding menu.

We’ll be creating here a folding menu using only jQuery, no CSS no special markup, and enqueueing the script with the recommended technique for WordPress.  Keep reading to see the solution…
This is what is going to happen after we enable our folding menu when someone clicks on a page that has subpages:

folding

Let’s start by looking at the structure and see which selectors we could use. WordPress assigns a current_page_item class to the current page and a page_item class to any other page. When a page has children, the nesting is ‘.page_item ul‘ and ‘.current_page_item ul‘. We can start writing this:

jQuery(document).ready(function(){

jQuery(".page_item ul").hide();

jQuery(".current_page_item ul").slideDown();

});

After the document is ready we hide every instance of children pages, and then, if the current page has children, we slideDown the list. That’s it, but wait, what happens if we click in one of the children? now we’re in trouble, we’re inside the ‘.current_page_item ul‘ nesting so jQuery won’t find it and therefore it won’t slide down the menu. Luckily, WordPress adds another class, which is current_page_ancestor, so we nest it with ul, the list that holds the current page, and now we can trigger the slide down effect.

jQuery(document).ready(function(){

jQuery(".page_item ul").hide();

jQuery(".current_page_item ul, .current_page_ancestor ul").slideDown();

});

Enough for the jQuery code. Let’s enqueue it using the proper technique. WordPress has a function named wp_enqueue_script that will enqueue our script and it will test if it is already enqueued. If it depends on a library, like jQuery in this case, it will check to see if it’s already enqueued too.


function ilc_addFolding_init(){
wp_enqueue_script('jquery_folding', '/wp-content/themes/default/js/folding.js', array('jquery'));
}
add_action('init', 'ilc_addFolding_init');

The first parameter is a handle name and the second is the path to the script. The third parameter is an array of handles that this script depends on. In this case, we only need jQuery, but for example, your script could depend on jQuery and jQuery UI. So, when do we ask WP to call the enqueue? you should call it from an ‘init‘ action. A wp_head hook is too late to enqueue. A template_redirect could work too but I’d rather stick to the action hook recommended in the reference. That’s all, you can now test it. You will see the parent pages visible with their children pages hidden. As soon as you click on the parent pages and the page loads, the children pages list will be shown.

Now, one more thing before we end. In the third caption there’s a Page 4 > Page 4.2 title, the parent page and the child page. We can easily display the parent using this code within the loop instead of the typical the_title:


<h2>
<?php
if ( is_page() && $post->post_parent ) {
$page = get_page($post->post_parent);
echo get_the_title($page->ID);
echo ' > ';
} else {
// This is not a subpage
}
the_title(); ?>
</h2>

If this is a page, we grab the post_parent. Then we get the page, and from that page, we retrieve the_title. We render it, add a separator ‘>’ or ” could work, and we end the conditional. Now we can display the current page title using the_title as usual.

Final thoughts

This collapsible menu is in no way perfect. Both jQuery script and parent page title display will only work for one level of nesting. Most of the times this will be enough but you can always extend the script and the php code to display more levels of nesting, to animate the children pages when they are displayed, for example, with fadeIn, or move them from right to left. jQuery always delivers a bit more.

UPDATE: March 11, 2009

Thanks to Kretzschmar bug reports I’ve modified the script so it will work on all levels of a Pages widget hierarchy. Download the WordPress plugin in the ILC Folding Menu page.

Posted on Monday, February 23rd, 2009 in .

“Folding menu for WordPress pages using jQuery” received 27 comments! Add yours.

  1. Mike February 25th, 2009

    Very interesting. I was looking for a way to do this. Thanks for sharing.

  2. Ann Hyung February 26th, 2009

    Now I know why my wp_enqueue_script doesn’t work, I was using wp_head as the hook. I changed it to init and it’s working.
    Thanks for sharing this, I was looking for something completely unrelated to this post but thanks to it now I’ve the answer.

  3. Kretzschmar March 11th, 2009

    Thanks for this one. But I just can’t get it to work with more than one level of nesting.

  4. Elliot March 11th, 2009

    This will work for all levels:
    jQuery(document).ready(function(){

    jQuery(".page_item ul").hide();

    jQuery(".current_page_item ul:first, .current_page_ancestor ul").slideDown();

    });
    in fact, I think I will be coding a quick plugin. I will let you know when it’s posted.

  5. Kretzschmar^ March 11th, 2009

    Thanks Elliot. This works better but still doesn’t work 100%.

    For example:
    1. page
    1.1 subpage1
    1.1.1 subsubpage 1
    1.1.2 subsubpage 2
    1.2 subpage2

    Clicking on subpage2 opens all subsubpages of subpage1 too.

  6. Elliot March 11th, 2009

    Ok, I think it’s done now. Check the post, I’ve updated it with the plugin download. The code is:

    jQuery(document).ready(function(){
    jQuery(".page_item ul").hide();
    jQuery(".current_page_item").parents("ul, li")
    .map(function () {
    jQuery(this).slideDown();
    });
    jQuery(".current_page_item ul:first").slideDown();
    });

    Download the WordPress pages folding plugin.

  7. Michael Castilla March 11th, 2009

    Do you have a demo?

  8. Kretzschmar March 12th, 2009

    Looks like you really did it. Fantastic.
    Thank you very much.

  9. Elliot March 12th, 2009

    Michael, I don’t have a demo at the moment.
    Kretzschmar, thanks. Maybe this would have ended in a box if you hadn’t asked for a two level feature. Now it’s multilevel. Grab the wordpress plugin here
    http://www.ilovecolors.com.ar/folding-menu-plugin-wordpress/

  10. :: Folding menu for WordPress pages using jQuery :: July 4th, 2009

    [...] :: Folding menu for WordPress pages using jQuery :: Tags: Comments0 Leave a Reply Click here to cancel [...]

  11. James July 30th, 2009

    Nice work sir!

    Question – could it remember it’s state – so that if you already have children visible, and you click another child from that branch, the menu doesn’t collapse and open again needlessly?

    Cheers.

  12. Elliot August 4th, 2009

    I haven’t worked on this since I have last published them. It could be, but I really don’t have time right now :P I remember there was a guy that created another plugin based on this one and wrote me an email, you can see the pingback here at the updated plugin at the bottom of the comment list.

  13. Digital Nomad September 13th, 2009

    I am gonna try this folding menu! Thanks for sharing!

  14. Elliot September 13th, 2009

    Go ahead and try it. Let me know if you have any issues.

  15. rhinoplasty September 24th, 2009

    Nice site!

  16. Cla-ude September 29th, 2009

    Thanks for this article.
    I’ve used it to hide my subcategories in a menu using the Shopp e-commerce plugin.
    As my usual plugin wasn’t working (Shopp don’t use the normal WP categories, posts or pages but has it’s own menu), I’ve customized your code and it’s working great :-)
    Thanks one more time.

  17. Dkulagin December 2nd, 2009

    Hi! You have a good style description.

  18. ostrov December 2nd, 2009

    Thank you,
    very interesting article

  19. Rob December 21st, 2009

    I’m looking for exactly this feature but for Categories

    Have tried FoCal but it’s not working as it shouold

  20. admic January 4th, 2010

    Տղերք էս Concerned Armenian-ը ԿԳԲ-ի գործակալ է Սովետի ժամանակից, մենք գիտենք նա ով է, ամերիկայում ապրող մի պարսկահայ է, ով հիմա էլ էնտեղից է ԿԳԲ-ի համար տվյալներ ուղարկում: Այնպես որ շատ բանի տեղ մի դրեք, նրա նմանները մեր պատմության մեջ միշտ էլ եղել են, մեկ թուրքերին են ծառայել, մեկ պարսիկներին, մեկ ռուսներին:

  21. admic January 4th, 2010

    rAKkpl =))))))))))))))))))))))))))))))))))))))))))))))

  22. admic January 4th, 2010

    =))))))))))))))))))))))))))))))))))))))

  23. asd January 4th, 2010

    asd ffff

  24. chips zynga March 20th, 2010

    i might not have contemplated this had been trendy a couple of years in the past and yet its interesting precisely how time switches the way you see a variety of creative ideas, thank you for the article it truly is nice to read something sensible now and then in lieu of the normal rubbish mascarading as blogs on the net, i’m off to take up a smattering of rounds of facebook poker, cheers

  25. Xrumer Blast March 22nd, 2010

    We will blast your site to 450,000+ Forums, Blogs etc..

  26. world cup 2010 betting odds June 13th, 2010

    Very nice, I would send this page to my friend.

  27. Justin Campbell June 20th, 2010

    my cousin broke her nose on a bad bike accident and he got a nose job.~`~

Leave a comment