Rendering Menus in Code
For developers integrating menus into a theme or module, Menu Builder menus can be rendered with widget shortcodes, layout XML, or directly in phtml templates. For the no-code admin methods, see Displaying Menus.
Widget Shortcodes
Widget shortcodes let you embed Menu Builder menus directly in CMS content, static blocks, or anywhere else that processes Magento widget directives. This is handy when editing content and you want to quickly drop in a menu without creating a formal widget.
Here's the shortcode syntax for rendering a Menu Builder menu:
Replace my_menu with your menu's identifier. You can paste this shortcode into any CMS page or block content.
Layout XML
Layout XML gives you precise control over where menus appear and how they integrate with your theme's structure. Use this method when you need to add a menu to a specific container or position it relative to other blocks.
This example adds a Menu Builder menu to the main content container:
<referenceContainer name="content">
<block class="Hyva\MenuBuilder\Block\Menu">
<arguments>
<argument name="menu_identifier" xsi:type="string">my_menu</argument>
</arguments>
</block>
</referenceContainer>
The menu_identifier argument specifies which menu to render. Replace my_menu with your menu's identifier, and change the container reference to match where you want the menu to appear.
phtml Templates
When you're building custom templates, you can render Menu Builder menus directly in your phtml files. You have two approaches: define the menu block in layout XML and reference it in your template, or create the block dynamically in the template itself.
Approach 1: Define in Layout XML
This is the cleaner approach when you want to render a menu in a custom template. Define the menu block in your layout XML file:
<block class="Hyva\MenuBuilder\Block\Menu" name="hyva_menu_block">
<arguments>
<argument name="menu_identifier" xsi:type="string">my_menu</argument>
</arguments>
</block>
Then reference the child block in your phtml template:
This keeps your layout structure visible in XML and makes the template code simpler.
Enable shared menu block caching across pages
Add ttl when you want shared ESI/Varnish block caching across pages. If you do not want shared block caching, the menu is still cached as part of each page.
Add ttl on the Menu block itself, for example:
<block class="Hyva\MenuBuilder\Block\Menu" name="hyva_menu_block" ttl="3600">
<arguments>
<argument name="menu_identifier" xsi:type="string">my_menu</argument>
</arguments>
</block>
If you add shared ESI/Varnish caching, use getChildHtml() in the template to render the block. This ensures Magento renders through the layout pipeline (renderElement), where PageCache can process ESI placeholders. Calling getChildBlock(...)->toHtml() bypasses that ESI processing path.
Approach 2: Create Block Dynamically
If you need to create a menu block on the fly without layout XML, do it directly in your phtml template:
<?= $block->getLayout()
->createBlock(\Hyva\MenuBuilder\Block\Menu::class)
->setMenuIdentifier('my_menu')
->toHtml(); ?>
This approach is useful when the menu identifier is dynamic or determined at runtime. Replace my_menu with your menu's identifier or a variable containing it.
Related Topics
- Displaying Menus: the no-code ways to place a menu, through Design Configuration, the CMS editor, or Magento widgets.
- Creating Custom Menu Components: build your own menu components instead of using the built-in ones.