• WordPress’ menu system loads objects called $item for every menu link. The $item object contains the title from the post or page it links to. I’m wondering if I can make the $item contain other stuff, like a value from a custom field on the post?

    I realize that I can enter a value in the ‘description’ field on the link, when I edit the menu. But it would save much repetitive editing if I could enter a value on custom field on the page or post, and have that value display on the menu?

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    Yes you can. There’s a pile of different filters in wp_nav_menu() you can use, one of those would surely allow you access to the individual objects. I don’t think that’s really necessary though because the default code to generate the menu HTML wouldn’t know what to do with the extra data. Thus you need to write your own nav_menu_walker function that does know what to do with the data.

    If you do that, the data can be pulled directly from post meta, you don’t really need to pass it through $item, though you may if you like.

    Thread Starter photocurio

    (@photocurio)

    Its true that the default code generated by wp_nav_menu wouldn’t know what to do with the extra data. A custom walker is needed for that. The reference for wp_nav_menu has all the info needed to create a walker. But I can’t find anything about retrieving fields from the post object.

    I think the reason the custom field needs to go through $item is because that’s how the walker works.

    I’m going to all this trouble because I want different navigation labels on different views, for example an acronym that displays on the mobile view instead of the full title. And the desktop view does display the full title.

    The acronym is not used only on the menus—it also appears on other places in the theme. That’s why I want to get it from the post object.

    Moderator bcworkz

    (@bcworkz)

    You don’t really need the post object itself (the source post or page object, not the nav_menu_item object), you really just need the post ID so you can get the custom field out of postmeta. How to get that is variable, depending on how the menu item was added to the menu.

    For posts manually added as links, $menu_item->post_name (title slug) is the only useful reference to the source post, but you can get the ID using get_page_by_title(). This works for other post types as well. In this case you do end up with a post object. You can be a little more efficient by getting just the ID with $wpdb->get_var().

    For pages that the menu system adds on its own, the source post ID is in postmeta of the nav_menu_item under the key ‘_menu_item_object_id’. You script can verify this is an actual post ID and not what the key indicates it is when the value does not equal the nav_menu_item ID taken from the nav_menu_item object.

    There may be other variations of getting post IDs depending on how the menu item was added, there should be a way to get back to the source post in each case, though it may take some creativity to get there.

    The initial information in the nav_menu_item you need is available in the walker, so I don’t see the need to place the value in the item itself. You may if you like using the ‘wp_nav_menu_objects’ filter.

    Thread Starter photocurio

    (@photocurio)

    interesting. I’ll try to work up some code and post it..

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Can menu items get custom field values from the post they link to?’ is closed to new replies.