1

I have a wordpress site, currently locally hosted with xampp.

Context Structure:

Child of Twenty Twenty-Five theme (block-based, doesn't support menus in Appearance-> Menu). In the site I have a "Products" page with a child "Product Details" page. In products I have a shortcode to display content (a title and a paragraph) dynamically based on a custom table "product_list" in the database. Clicking on a product title I pass a query to "product-detail" page, in this child page I have another shortcode to dynamically display the product details using the query as key. Everything works wonderfully.

The Problem:

This results in a general page structure: Products page (parent) and Product Details page (child), which in the navigation menu shows as a dropdown menu from Products. Example:Navigation Example. I can't seem to find a way to either enter the navigation arbitrarily, replace blocks in it, or pinpoint a shortcode. (See later what I tried).

What I want:

I want to be able to access the navigation menu to dynamically add links in the Products dropdown, so I can add an entry for each product and/or group them by properties, for example each product has a "size" property, and I can group the products based on that property.

What I tried:

I tried to rebuild the entire navigation block, but I just couldn't even intercept it and super messy code. Then I tried to loop blocks in from the rendered page, but that didn't work either.

The approach I wanted to use was to search for the <li> <a> Product Details </a> </li> in the navigation menu and replace it with my own content, probably a shortcode. Right now I was able to add a shortcode to the navigation menu, but only at the end with offsetSet:

function theme_render_shortcode_block() {
    return do_shortcode( '[navigation_product_list]' );
}

function theme_register_shortcode_block() {
    if ( function_exists( 'register_block_type' ) ) {
        register_block_type( 'theme/products-shortcode-block', array(
            'title' => 'Products Shortcode Block',
            'icon' => 'shortcode',
            'render_callback' => 'theme_render_shortcode_block'
        ) );
    }
}
add_action( 'init', 'theme_register_shortcode_block' );

add_filter( 'block_core_navigation_render_inner_blocks', function( $inner_blocks ) {
    $menu_item = new WP_Block( array(
        'blockName' => 'theme/products-shortcode-block'
    ) );

    $inner_blocks->offsetSet( null, $menu_item );

    return $inner_blocks;
} );

This makes me put a shortcode into the navigation block, into ALL navigation blocks, even the other ones I use in the footer for example, that don't use the wp-block-page-list. I want it to put it inside the wp-block-page-list block too, so I tried something like this to replace the Detail Product page link with the shortcode:

add_filter( 'block_core_navigation_render_inner_blocks', function( $inner_blocks ) {
    $target_menu_item_label = 'Product Details';

    foreach ( $inner_blocks as $index => $block ) {
        // Find the block with "Product Details" label.
        if ( isset($block->parsed_block['attrs']['label']) && $block->parsed_block['attrs']['label'] === $target_menu_item_label ) {

            // Replace it with shortcode block.
            $replacement_block = new WP_Block( array(
                'blockName' => 'theme/products-shortcode-block'
            ) );

            $inner_blocks[ $index ] = $replacement_block;

            break;
        }
    }
    return $inner_blocks;
} );

I tried to target the "Product Details" label but it doesn't do anything. For context the products-shortcode-block runs a shortcode that creates a with dynamic content based on the database table. I want to place it in the right spot.

2
  • Could you please be more specific about the plugins you're using on your WordPress site? Which page builder do you use? Is it Elementor Pro, Gutenberg, or something else? Screenshots would also be helpful. Commented Aug 28 at 20:32
  • @Maria Right now I'm only using a SEO and a form plugin. I'm not using any designed page builder beside the basic installation of wordpress. I saw that there were "shortcode in menu" plugins but menus are not supported in block-based-themes like the twenty twenty-five theme. Screenshot would be an empty page with a horizontal navigation menu, see the Navigation Example I provided Commented Aug 29 at 13:27

1 Answer 1

0

to add dynamically elements in the menu, you start by identifying the parent element. in my example, I add a css class parent_products_link for this element.

then you can add children elements like that :

add_filter("block_core_navigation_render_inner_blocks", function ($inner_blocks) {
    
    foreach ($inner_blocks as $index => $block) {
        
        // searching the special css class
        
        $class = $block->parsed_block["attrs"]["className"] ?? NULL;
        
        if ("parent_products_link" !== $class) {
            // not the searched element
            continue;
        }
        
        
        // add the child element
        
        $block->parsed_block["innerBlocks"][] = [
            "blockName" => "core/navigation-link",
            "attrs" => [
                "label" => "label of the link",
                "url" => home_url("/special/url"),
            ]
        ];
        
        
        // refresh the block after adding children
        $block->refresh_parsed_block_dependents();
        
    }
    
    
    return $inner_blocks;
    
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your straightforward answer! I was able to easily add my db search into the function, I wonder how much it impacts performance though. Only nitpick is that by adding a class I apply a modification to the navigation menu, which is therefore not the automatic "Pages List" block anymore. It's not a big deal though, at least for me

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.