logo
Ask your WordPress questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$50
Dynamic listing of child-categories in twentyten menu?

Hi,
I am working on a site where I need to list all the child categories of one category, in the menu, as a dropdown of the parent category's menu item. Adding them manually through the menu editor will not work for long, it must be dynamic.

I have tried adding wp_list_categories(child_of="8"&.....) into the #access in the header template, just behind wp_nav_menu(), but i can not figure out how to make the output work with the twentyten dropdowns, and neither the other way round - how to change the output to what would work.

Ideally, I would also like to place this "inbetween" some of the other menu choices.

Anyone?

This question has been answered.

Torstein Opperud | 01/18/11 at 11:52am Edit


(4) Possible Answers Submitted...

See a chronological view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    01/18/11
    12:00pm
    Andrzej Zglobica says:

    This can be done easily by replacing default Wordpress nav system by Menubar Plugin. If you wish me to implement it for you, pls contact me here.
    Cheers,
    Andrzej

    • 01/18/11 12:17pm

      Torstein Opperud says:

      I would prefer not to be dependent on yet another plugin, we are already a bit heavy on queries, so I would rather have a snippet of code that does only this one thing.

      But it is a possible solution if I dont get anything else, thanks :)

      (and to think of how I have searched both wp.org and googled every possible combination of "menu" "categories" and similar words for hours and hours without finding that plugin... argh!!)

    • 01/18/11 12:19pm

      Andrzej Zglobica says:

      It still can be done via wp_nav_menu() if you want stick to it, by some sort of PHP str_replace hacks. I'm availiable now and can fix it for you that way - I just need your website address and ftp details. (contact link)

    • 01/18/11 12:55pm

      Andrzej Zglobica says:

      if you do not want to send ftp, pls paste here you code around wp_nav_menu() function and html output of the site (can be done via zipped attachment) or just post a link to the website?

  • avatar
    Last edited:
    01/18/11
    12:21pm
    Nilesh shiragave says:

    Do you want to use the wp_nav_menu() ?

    or you can achieve it by using the wp_list_pages() just add following code inside the #access div


    <div class="menu">
    <ul>
    <?php wp_list_pages('title_li=&sort_column=menu_order');?>
    <?php wp_list_categories('child_of=8'); ?>
    </ul>

    </div>

    Previous versions of this answer: 01/18/11 at 12:21pm

  • avatar
    Last edited:
    01/19/11
    7:13am
    Maor Barazany says:

    Well, this is a more or less known issue with WordPress nav menu system.
    In short: They cannot be dynamic.
    The advantage of it is only for letting your user build and change the menu for needs.
    If you have a lot of sub categories, you have to use the wp_list_categories() function with parameters to auto show child cats.

    In general, you have two possible solutions (if you count only code solutions and not want to base on a plugin).

    The first one depends on that that the category that has childs is in known position in the menu. Then, you can build the code in general like this -
    Create two nav menu and show them in separate and insert another call to list the category between them. Something like this: (See specific functions' parameters in the codex)

    <?php 
    wp_nav_menu('menu' = > '1'); //the first menu
    wp_list_categories($your_needed_args); //dynamic builld the category item with its children
    wp_nav_menu('menu' => '2'); //the second menu - continuing the menu
    ?>


    This solution is good only if the location of the category (with its childs) is known inside the menu order that needed, and is not needed to be changed by the end user.

    Second option, is building yourself a Custom Walker for custom output of the Walker (which created the output for all nav'ing functions such as wp_list_pages, wp_list_categories_, wp_nav_menu ), and insert code that will buld it as you wish.
    Here's a post explaining how to create a custom walker


    Hope it helps

    Previous versions of this answer: 01/18/11 at 1:50pm | 01/18/11 at 1:55pm

    • 01/18/11 7:16pm

      Maor Barazany says:

      Nick had a little mistake in his code, since $args is for the whole menu and not for the item itself.

      Take this function instead, based on Nick's code with my changes:


      add_action('wp_loaded','register_nav_menu_class');

      function register_nav_menu_class(){
      class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {

      function start_el(&$output, $item, $depth, $args) {
      global $wp_query;
      $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
      $class_names = $value = '';
      $classes = empty( $item->classes ) ? array() : (array) $item->classes;
      $classes[] = 'menu-item-' . $item->ID;

      $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
      $class_names = ' class="' . esc_attr( $class_names ) . '"';

      $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
      $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

      $output .= $indent . '<li' . $id . $value . $class_names .'>';

      $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
      $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
      $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
      $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';

      $item_output = $args->before;
      $item_output .= '<a'. $attributes .'>';
      $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
      $item_output .= '</a>';

      if($item->object == 'category'){
      $child_cats = wp_list_categories('title_li=&echo=0&child_of='.$item->object_id);
      if( $child_cats ){
      $item_output .= '<ul class="sub-menu">' .$child_cats. '</ul>';;
      }
      }

      $item_output .= $args->after;
      $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

      }
      }
      }

    • 01/19/11 2:29am

      Torstein Opperud says:

      Sorry Maor, the problem is still there, same problem with both yours and Nick's new code :(

      (its your code that is in functions.php at the moment)

    • 01/19/11 5:11am

      Maor Barazany says:

      Check again carefully , since I have tested my code in a local site and after making this change, it was fixed in my site. If you want, send me your wp-admin's user and password, and login to your FTP so I could see the functions.php file also and I can check. This code does work, you might have mistaken in something.

    • 01/19/11 7:03am

      Torstein Opperud says:

      Argh,
      found it, totally silly mistake (as they often are). Yep, now its working, thanks!

      Actually, since both you and Nick contributed a lot here, I think you both deserve the reward, so if you would send me a pm with your paypal-address, I'll make sure you get 50$ each, and I'll add a little bonus for you since you seem to have been first with the bugfix :)

      Also - if you are interested: I often have smaller jobs (mostly regarding wordpress, both smaller and larger than this) I need done, so if you use a different address from your paypal-address, please include that, and I'll get in touch when I need something :)

      Again, thanks!
      Torstein

  • avatar
    Last edited:
    01/19/11
    7:13am
    Nick Parsons says:

    Here's the code for implementing a custom walker like Mr. Barazany suggested:

    add_action('wp_loaded','register_nav_menu_class');


    function register_nav_menu_class(){
    class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth, $args) {
    if($item->object == 'category'){
    $child_cats = wp_list_categories('title_li=&echo=0&child_of='.$item->object_id);
    if( $child_cats ){
    $args->after .= '<ul class="sub-menu">' .$child_cats. '</ul>';
    }
    }
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $class_names = $value = '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = 'menu-item-' . $item->ID;

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    $class_names = ' class="' . esc_attr( $class_names ) . '"';

    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
    $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

    $output .= $indent . '<li' . $id . $value . $class_names .'>';

    $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
    $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
    $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
    $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;

    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
    }
    }


    That's all you need to add child categories menu support to 2010, you can now simply use this:
    <?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'walker' => new Custom_Walker_Nav_Menu() ) ); ?>

    in the header to spit out the menu.

    • 01/18/11 6:24pm

      Torstein Opperud says:

      Hi Nick!
      I think you are really onto something! There is just one small problem, if you look at http://stikk.opperud.com, your walker tries to add subcategories also on other menu items, such as pages ("about"), and custom links ("Logg ut" and "Skriv nytt innlegg").

      If you fix this the cash is yours :)

      T.

    • 01/18/11 9:42pm

      Nick Parsons says:

      Great, thanks! Here's the new register_nav_menu_class function that will fix the bug you mentioned:

      function register_nav_menu_class(){
      class Custom_Walker_Nav_Menu extends Walker_Nav_Menu {
      function start_el(&$output, $item, $depth, $args) {
      global $wp_query;
      $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

      $class_names = $value = '';

      $classes = empty( $item->classes ) ? array() : (array) $item->classes;
      $classes[] = 'menu-item-' . $item->ID;

      $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
      $class_names = ' class="' . esc_attr( $class_names ) . '"';

      $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
      $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

      $output .= $indent . '<li' . $id . $value . $class_names .'>';

      $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
      $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
      $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
      $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';

      $item_output = $args->before;
      $item_output .= '<a'. $attributes .'>';
      $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
      $item_output .= '</a>';

      if($item->object == 'category'){
      $child_cats = wp_list_categories('title_li=&echo=0&hide_empty=0&child_of='.$item->object_id);
      if( $child_cats ){
      $item_output .= '<ul class="sub-menu">' .$child_cats. '</ul>';
      }
      }

      $item_output .= $args->after;

      $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
      }
      }
      }

    • 01/19/11 2:26am

      Torstein Opperud says:

      Sorry Nick, the problem is still there, both in your new code and in Maor Barazany's code :(

    • 01/19/11 6:50am

      Nick Parsons says:

      Hmm,

      When I went to your demo site (http://stikk.opperud.com/) the 'About', 'Logg ut', and 'Skriv nytt innlegg' items no longer have the categories listed under them - isn't that the bug you described?

    • 01/19/11 7:06am

      Torstein Opperud says:

      I found the mistake, it was mine and it was totally silly, fixed it just an hour ago or so :)

      But, since both you and Maor contributed a lot here, I think you both deserve the reward, so if you would send me a pm with your paypal-address, I'll make sure you get 50$ each :)

      And - if you are interested: I often have smaller jobs (mostly regarding wordpress, both smaller and larger than this) I need done, so if you use a different address from your paypal-address for workrelated mail, please include that, and I'll get in touch when I need something :)

This question has expired.





Current status of this question: Completed



Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.