WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Thumbnail as menu item (14 posts)

  1. Huw Tyler
    Member
    Posted 3 years ago #

    As far as I know, this isn't a standard bit of wordpress coding...

    I have set up a custom menu and populated it. This is displayed as a list of
    LI's.
    It's a great feature and I've used it a lot now for CMS sites.

    I wondered if it's possible to generate any other information from the <?php wp_nav_menu('menu={name}'); ?> code.

    For example, I'm trying to get the post thumbnail of each item that's in the menu. Although just the ID would do as I could then use it to grab the thumbnail.

    This would also need to be clean (ie. no <li>s etc)
    I saw that the wp_get_nav_menu_item() has been deleted.

    Any ideas? - would love to some thoughts or possible other ways to do this?

  2. Michael Fields
    Themer
    Posted 3 years ago #

    This should be rather easy by defining your own Walker class that extends the built-in Walker class. I would suggest copying the code in Walker_Nav_Menu and then change it to work how you want. Something like:

    class MyTheme_Walker_Nav_Menu extends Walker {
      /* Paste code from Walker_Nav_Menu here. */
    }

    You can then create an object of your custom class and pass it to wp_nav_menu(). Something like the following should work:

    $mytheme_walker = new MyTheme_Walker_Nav_Menu();
    wp_nav_menu( array(
    	'walker' => $mytheme_walker
    ) );
  3. Huw Tyler
    Member
    Posted 3 years ago #

    Thanks for this Michael. Thanks for getting back to me.
    Could you clarify this, where I should put these items and how I then call the post_thumbnail... ?

    I'm not familiar with the walker class

  4. Michael Fields
    Themer
    Posted 3 years ago #

    The first bit would go in functions.php of your theme. The second bit should go where ever you want the menu displayed in your theme. You will want to call the post thumbnail from within the walk() method of you custom walker class.

  5. Huw Tyler
    Member
    Posted 3 years ago #

    I'm guessing this is the section I need to borrow and edit for my use:?

    class Walker_Nav_Menu extends Walker {
    	/**
    	 * @see Walker::$tree_type
    	 * @since 3.0.0
    	 * @var string
    	 */
    	var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    
    	/**
    	 * @see Walker::$db_fields
    	 * @since 3.0.0
    	 * @todo Decouple this.
    	 * @var array
    	 */
    	var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );
    
    	/**
    	 * @see Walker::start_lvl()
    	 * @since 3.0.0
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param int $depth Depth of page. Used for padding.
    	 */
    	function start_lvl(&$output, $depth) {
    		$indent = str_repeat("\t", $depth);
    		$output .= "\n$indent<ul class=\"sub-menu\">\n";
    	}
    
    	/**
    	 * @see Walker::end_lvl()
    	 * @since 3.0.0
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param int $depth Depth of page. Used for padding.
    	 */
    	function end_lvl(&$output, $depth) {
    		$indent = str_repeat("\t", $depth);
    		$output .= "$indent</ul>\n";
    	}
    
    	/**
    	 * @see Walker::start_el()
    	 * @since 3.0.0
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param object $item Menu item data object.
    	 * @param int $depth Depth of menu item. Used for padding.
    	 * @param int $current_page Menu item ID.
    	 * @param object $args
    	 */
    	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>';
    		$item_output .= $args->after;
    
    		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    	}
    
    	/**
    	 * @see Walker::end_el()
    	 * @since 3.0.0
    	 *
    	 * @param string $output Passed by reference. Used to append additional content.
    	 * @param object $item Page data object. Not used.
    	 * @param int $depth Depth of page. Not Used.
    	 */
    	function end_el(&$output, $item, $depth) {
    		$output .= "</li>\n";
    	}
    }

    If so, is it this following section I would need to edit...

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

    If so, how do I call the thumbnail. I ask because things like the_title() don't get used so will post_thumbnail() work here?

    What do you mean by the walk() method, don't know where you're finding this?

    Sorry to keep asking. I think I'm closer, very much appreciate your spoon feeding!!

  6. Huw Tyler
    Member
    Posted 3 years ago #

    Still trying to work this out, it's been days of trawling through code chasing variables.
    Does anyone know where the info about the post/page/CPT is passed into the menu. It seems the menu uses a whole different set of variables and getting any post/page information is next to impossible... any help?

  7. Michael Fields
    Themer
    Posted 3 years ago #

    Most everything should be in the $item object. Try to run var_dump( $item ) and see if what you need is in there. If you cannot find it, try

    print '<pre>' . print_r( get_defined_vars(), true ). '</pre>';
  8. Michael Fields
    Themer
    Posted 3 years ago #

    I'm guessing this is the section I need to borrow and edit for my use:?

    Yep!

    If so, is it this following section I would need to edit...

    Yes. I would suggest modifying the $item_output variable.

    If so, how do I call the thumbnail. I ask because things like the_title() don't get used so will post_thumbnail() work here?

    Something like:

    $thumbnail = get_the_post_thumbnail( $id );

    What do you mean by the walk() method, don't know where you're finding this?

    My bad, please disregard this.

  9. Huw Tyler
    Member
    Posted 3 years ago #

    Nice tip, definitely got me closer.
    It's currently struggling to use get_the_post_thumbnail()

    I've currently got this:

    $thumbnailid = (int)$item->object_id;
    $thumbnail = get_the_post_thumbnail($thumbnailid);

    $thumbnailid works well, it gets what I need.
    $thumbnail returns a NULL.

    Even get_the_post_thumbnail(6) returns nothing.

    It seems every time I try to define the specific item I need, it closes up on me!
    It's wierd that get_the_post_thumbnail() without anything in brackets returns a thumbnail!

    Weird!

    Any clues?

  10. Michael Fields
    Themer
    Posted 3 years ago #

    Maybe something like this:

    $thumbnail = '';
    if( $id = has_post_thumbnail( (int)$item->object_id ) ) {
    	$thumbnail = get_the_post_thumbnail( $id )
    }
  11. Huw Tyler
    Member
    Posted 3 years ago #

    GOT IT!
    Thanks so much for all your help... a true expert.
    The effect is exactly what I wanted and I've spend literally days trying to figure this out. Tempted to export that section of code as a plugin. Could be really useful. I've not seen it done before.

  12. Michael Fields
    Themer
    Posted 3 years ago #

    No problem, always willing to help out with interesting functionality :) Glad you got it to work!

  13. Ti_na
    Member
    Posted 3 years ago #

    I'm also trying to get this to work but unfortunately this:

    $thumbnail = '';
    if( $id = has_post_thumbnail( (int)$item->object_id ) ) {
    	$thumbnail = get_the_post_thumbnail( $id )
    }

    is not returning anything and I'm not sure what I'm missing. (I tested the $thumbnail = ''; and filled with text and it appeared so I'm not sure why it's not returning the thumbnails.)

    I would so greatly appreciate if a clear example could be shown of where it's inserted (with the walker class).

  14. javiermatosdes
    Member
    Posted 3 years ago #

    I have the same issue as Ti_na, I've tried to insert the $thumbnail code above but am having no success in getting my images to show. My code is below:

    $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        ) .'"' : '';
    
    		$thumbnail = '';
    		if( $id = has_post_thumbnail( (int)$item->object_id ) ) {	$thumbnail = get_the_post_thumbnail( $id );
    
    		$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;
    
    		}

Topic Closed

This topic has been closed to new replies.

About this Topic