Support » Plugin: Relevanssi - A Better Search » Indexing menu items

  • Resolved JacobTheDev

    (@revxx14)


    My client has asked me to figure out a way to include menu items in to search results, as they want certain external links that only appear in the menu to appear when you search for them. I see there’s an option for wp_navigation in Relevanssi’s indexing settings, but enabling that (and disabling Respect exclude_from_search, and re-indexing) does not include menu items.

    Is there a way to include menu items in search results?

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author Mikko Saari

    (@msaari)

    The post type for menu items is nav_menu_item and it’s on the black list of post types Relevanssi doesn’t even show in the settings screen (looks like I need to add wp_navigation to that list in the next version).

    You can force Relevanssi to index the navigation menu items:

    add_filter( 'pre_option_relevanssi_index_post_types', function( $value ) {
        return array( 'post', 'page', 'nav_menu_item' );
    } );

    This will make Relevanssi index posts, pages, and nav_menu_items. That’ll make the menu items show up in the search results (as long as exclude_from_search is ignored).

    You’ll then need to modify the search results template so that it does something sensible with the menu items because by default the permalink to the menu item does not work. For custom link items the link is stored in wp_postmeta in the custom field _menu_item_url, so you probably want to fetch that and use it instead of the normal permalink.

    Thread Starter JacobTheDev

    (@revxx14)

    Ah! That’s perfect, thanks. I ended up doing it with the following:

    /**
     * Add nav_menu_item to indexed Relevanssi post types
     *
     * @param array|bool $post_types
     * @return array
     */
    function mytheme_relevanssi_index_nav_menu_items(): array {
        return ["post", "page", "nav_menu_item"];
    }
    add_filter("pre_option_relevanssi_index_post_types", "mytheme_relevanssi_index_nav_menu_items", 10, 0);
    
    /**
     * Only allow "custom link" nav_menu_items to be indexed
     *
     * @param  array<array<mixed>> $hits Array of Relevnassi hits
     * @return array<array<mixed>>
     */
    function mytheme_relevanssi_filter_nav_menu_items(array $hits = []): array {
        $hits_filtered = [];
    
        foreach ($hits[0] as $hit) {
            if ($hit->post_type !== "nav_menu_item" XOR (($url = get_post_meta($hit->ID, "_menu_item_url", true)) && $url !== "#")) {
                $hits_filtered[] = $hit;
            }
        }
    
        $hits[0] = $hits_filtered;
    
        return $hits;
    }
    add_filter("relevanssi_hits_filter", "mytheme_relevanssi_filter_nav_menu_items", 10, 1);

    The second filter removes any menu item that *isn’t* a custom link to prevent duplicate listings, seems to be working perfectly!

    Quick question for the first filter: Is there a way to *append* my new post type instead of having specify all of the ones I want? Would be nice to “import” the settings from the back-end and just tack on this extra one, but not a huge deal if it’s not possible.

    • This reply was modified 5 months, 2 weeks ago by JacobTheDev.
    • This reply was modified 5 months, 2 weeks ago by JacobTheDev.
    • This reply was modified 5 months, 2 weeks ago by JacobTheDev.
    • This reply was modified 5 months, 2 weeks ago by JacobTheDev.
    Plugin Author Mikko Saari

    (@msaari)

    That’s how the pre_option_ hook works, it overrides the value completely. You can replace that with option_relevanssi_index_post_types, which filters the existing value.

    Thread Starter JacobTheDev

    (@revxx14)

    Aha! Perfect, thank you so much for your help!

Viewing 4 replies - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.