Although this sounds really straight forward I can't work it out. All the existing methods seem to be for Magento 1.x
I would like to have all my CMS pages in the top menu.
Although this sounds really straight forward I can't work it out. All the existing methods seem to be for Magento 1.x
I would like to have all my CMS pages in the top menu.
I've done it in the following way without any changes in the code:
That's it!
In case you still need PageA just delete content from it and add CMS Block (BlockA) as a widget.
You can create a static block with a list of your pages, then add it to your <Magento>/app/design/frontend/<Vendor>/<theme>/web/etc/default.xml file.
The CMS block would look something like:
<li class="level0 level-top"><a class="level-top ui-corner-all" href="{{store direct_url="about-us"}}">About Us</a></li>
<li class="level0 level-top"><a class="level-top ui-corner-all" href="{{store direct_url="contact-us"}}">Contact Us</a></li>
And the code in default.xml would be placed within the block:
<body>
...
<referenceContainer name="catalog.topnav">
<block class="Magento\Cms\Block\Block" name="your_block_id">
<arguments>
<argument name="block_id" xsi:type="string">your_block_id</argument>
</arguments>
</block>
</referenceContainer>
...
</body>
Additional styling may be needed, but with the blank theme using the classes level0 and level-top in your CMS block should match up.
Without any extension,it's not possible.
Basically, we use cms page for cms content management.
As per my knowledge, there is a process in category system where you can manage cms content.
Just create a cms static block and assign that static block
to the category from Display setting tab.
Then,set Display Mode as Static block only. Do not assign any products to that category.
Free extension available at Github
Or build the module yourself as per below steps:
Then create plugin for class Magento\Theme\Block\Html\Topmenu
and
and use before
plugin on getHtml()
First, create a module.
Second: create di.xml
where we will define plugin.
<?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>
Third: Now create the plugin class where we will add a cms page link to the menu.
and also in this way we can add a cms page link at navigation.
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;
}
}
self promotion
We made an OpenSource Module where you can link a category to a specific CMS page. So you have to create a Category for each CMS page and adjust the link via the module. In case you want to do it yourself, just have a look at the module :-)
Note that if you have Magento Enterprise Edition, you can use the Hierarchy feature. That's precisely what it's intended to allow you to do (among other things).
You can create a plugin for the Magento\Theme\Block\Html\Topmenu
block's getHtml method and use it to iterate through the CMS pages, inserting the links into the html.
Do you mean the top.links or the main navigation that's populated by categories?
Cause if you want page links in top.links (header.links for Luma), then just create the page and add to default.xml
<referenceContainer name="header.links">
<block class="Magento\Framework\View\Element\Html\Link\Current" name="about-us" before="-">
<arguments>
<argument name="label" xsi:type="string">About Us</argument>
<argument name="path" xsi:type="string">about-us</argument>
</arguments>
</block>
</referenceContainer>
That should link to your static pages.
Want to add a link to the top navigation within <header>
Adding a link to CMS page, Gallery
Edit/Place default.xml here:
app/design/frontend/Vendor/theme/Magento_Theme/layout/default.xml
Add the following code:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="catalog.topnav">
<block class="Magento\Framework\View\Element\Html\Link\Current" name="gallery.link">
<arguments>
<argument name="label" xsi:type="string">Gallery</argument>
<argument name="path" xsi:type="string">gallery</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
This adds a link to CMS page, Gallery, with the following settings:
Title = Gallery
Url Key = gallery
Link = https://example.com/gallery/
Add the following styling to ensure the new link aligns correctly:
.navigation .nav.item {
margin: 0 10px 0 0;
display: inline-block;
position: relative;
}