Magento2 add a cms page link to menu
Magento 2

Magento2 add a cms page link to menu

Magento2 add a cms page link to menu or add a link to the menu, Magento2 add a cms page link to the menu.

If you are store owner/ developer then sometimes, you want to add a cms page link to menu of your Magento 2 store.

Magento 2 does not provide any feature like add a Cms page to your existing menu. At default Magento, you can only add the categories to its menu.

So, today I am writing this blog for how you add a cms page link to the menu. For this, you need some coding also. If you do not want to wish to do any coding then use Magento free extension.

FREE Extension & Source code avaliable at GitHub https://github.com/devamitbera/magento2-add-cms-pages-to-menu

How to Create that module at magento

Here, I have used Magento before plugin.

Create a plugin on class Magento\Theme\Block\Html\Topmenu as the menu is rendered from this class and use before plugin on getHtml().

menu is rendered from this class and use before plugin on getHtml().

First, create a module.module should have minimum below files:

  • app/code/{VendorName}/{ModuleName}/etc/module.xml
  • app/code/{VendorName}/{ModuleName}/composer.json
  • app/code/{VendorName}/{ModuleName}/registration.php

2: create di.xml where we will define the plugin.

location: app\code{VendorName}{ModuleName}\etc\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Theme\Block\Html\Topmenu">
        <plugin name="add_cms_menu" type="{VendorName}{ModuleName}\Plugin\Topmenu" sortOrder="1" />
    </type>
</config>

3.Now create the plugin class where we will add a cms page link to the menu.

File Path: app\code{VendorName}{ModuleName}\Plugin\Topmenu.php

<?php 
namespace {VendorName}\{ModuleName}\Plugin;
use Magento\Framework\Data\Tree\NodeFactory;
class Topmenu
{
    protected $nodeFactory;
    protected $_storeManager;
    protected $_pageFactory;
    protected $_urlBuilder;
 
    public function __construct(
        NodeFactory $nodeFactory,
        \Magento\Cms\Model\PageFactory $pageFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\UrlInterface $urlBuilder
    ) {
        $this->nodeFactory = $nodeFactory;
        $this->_pageFactory = $pageFactory;
        $this->_storeManager = $storeManager;
        $this->_urlBuilder = $urlBuilder;
    }
    public function beforeGetHtml(
        \Magento\Theme\Block\Html\Topmenu $subject,
        $outermostClass = '',
        $childrenWrapClass = '',
        $limit = 0
    ) {
        /* Showing  Cms page About us at menu */
        $page = $this->getCmspage('about-us');
        if($page == null){
            return;
        }
 
 
        $node = $this->nodeFactory->create(
            [
                'data' => [
                    'name' => $page->getTitle(),
                    'id' => $page->getIdentifier(),
                    'url' =>  $this->_urlBuilder->getUrl(null, ['_direct' => $page->getIdentifier()]),
                    'has_active' => false,
                    'is_active' => false // (expression to determine if menu item is selected or not)
                ],
                'idField' => 'id',
                'tree' => $subject->getMenu()->getTree()
            ]
        );
        $subject->getMenu()->addChild($node);
    }
    protected function getCmspage($identifier){
 
        $page = $this->_pageFactory->create();
        $pageId = $page->checkIdentifier($identifier, $this->_storeManager->getStore()->getId());
 
        if (!$pageId) {
            return null;
        }
        $page->setStoreId($this->_storeManager->getStore()->getId());
        if (!$page->load($pageId)) {
            return null;
        }
 
        if (!$page->getId()) {
            return null;
        }
 
        return $page;
    }
 
}

Here, some classes used for adding new items to the menu.

Magento\Framework\Data\Tree\NodeFactory

NodeFactory this class is responsible for adding a new item to the existing menu. Magento rendered the menu as Tree object using This class.

And here $subject->getMenu()->addChild() is used for add new item exisitwhere $subject is instead or Object of class Magento\Theme\Block\Html\Topmenu.