Main frontend menu generation in Magento 2
If you are familiar with Magento 1.x menu generation, you will be surprised how similar is the appropriate Magento 2 process. There are 9 steps of menu generation.
Table of contents
- 1 magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Theme/view/frontend/templates/html/topmenu.phtml#L18
- 2 magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Theme/Block/Html/Topmenu.php#L72-L75
- 3 magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Helper/Category.php#L115
- 4 magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Model/Category.php#L947
- 5 magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Model/ResourceModel/Category.php#L628-L640
- 6 magento/magento2/blob/487f5f45/app/code/Magento/Theme/view/frontend/requirejs-config.js#L27-L27
- 7 magento/magento2/blob/487f5f45/app/code/Magento/Theme/view/frontend/templates/html/topmenu.phtml#L21-L24
- 8 magento/magento2/blob/487f5f45/lib/web/mage/menu.js#L14-L17
- 9 magento/magento2/blob/487f5f45/lib/web/jquery/jquery-ui.js#L11439-L11439
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
?> <?php /** * Top menu for store * * @see \Magento\Theme\Block\Html\Topmenu */ ?> <?php $columnsLimit = $block->getColumnsLimit() ?: 0; ?> <?php $_menu = $block->getHtml('level-top', 'submenu', $columnsLimit) ?> <nav class="navigation" role="navigation"> <ul data-mage-init='{"menu":{"responsive":true, "expanded":true, "position":{"my":"left top","at":"left bottom"}}}'> <?php /* @escapeNotVerified */ echo $_menu; ?> </ul> </nav> |
1 2 3 4 |
$this->_eventManager->dispatch( 'page_block_html_topmenu_gethtml_before', ['menu' => $this->_menu, 'block' => $this] ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * Checking whether the using static urls in WYSIWYG allowed event * * @param \Magento\Framework\Event\Observer $observer * @return void */ public function execute(\Magento\Framework\Event\Observer $observer) { $block = $observer->getEvent()->getBlock(); $block->addIdentity(\Magento\Catalog\Model\Category::CACHE_TAG); $this->_addCategoriesToMenu($this->catalogCategory->getStoreCategories(), $observer->getMenu(), $block); } /** * Recursively adds categories to top menu * * @param \Magento\Framework\Data\Tree\Node\Collection|array $categories * @param \Magento\Framework\Data\Tree\Node $parentCategoryNode * @param \Magento\Theme\Block\Html\Topmenu $block * @return void */ |
magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Helper/Category.php#L115
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
return []; } $recursionLevel = max( 0, (int)$this->scopeConfig->getValue( 'catalog/navigation/max_depth', \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ); $storeCategories = $category->getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad); $this->_storeCategories[$cacheKey] = $storeCategories; return $storeCategories; } /** * Retrieve category url * * @param ModelCategory $category * @return string |
magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Model/Category.php#L947
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
* * @param int $parent * @param int $recursionLevel * @param bool $sorted * @param bool $asCollection * @param bool $toLoad * @return \Magento\Framework\Data\Tree\Node\Collection|\Magento\Catalog\Model\ResourceModel\Category\Collection */ public function getCategories($parent, $recursionLevel = 0, $sorted = false, $asCollection = false, $toLoad = true) { $categories = $this->getResource()->getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad); return $categories; } /** * Return parent categories of current category * * @return \Magento\Framework\DataObject[]|\Magento\Catalog\Model\Category[] */ public function getParentCategories() { |
magento/magento2/blob/22629abe10f9c640fe47b6081d57fedccdea8e0f/app/code/Magento/Catalog/Model/ResourceModel/Category.php#L628-L640
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public function getCategories($parent, $recursionLevel = 0, $sorted = false, $asCollection = false, $toLoad = true) { $tree = $this->_categoryTreeFactory->create(); /* @var $tree \Magento\Catalog\Model\ResourceModel\Category\Tree */ $nodes = $tree->loadNode($parent)->loadChildren($recursionLevel)->getChildren(); $tree->addCollectionData(null, $sorted, $parent, $toLoad, true); if ($asCollection) { return $tree->getCollection(); } return $nodes; } |
magento/magento2/blob/487f5f45/app/code/Magento/Theme/view/frontend/requirejs-config.js#L27-L27
1 |
"menu": "mage/menu", |
1 2 3 4 |
<ul data-mage-init='{"menu":{"responsive":true, "expanded":true, "position":{"my":"left top","at":"left bottom"}}}'> <?php /* @escapeNotVerified */ echo $_menu; ?> <?php /* @escapeNotVerified */ echo $block->getChildHtml(); ?> </ul> |
1 2 3 4 |
/** * Menu Widget - this widget is a wrapper for the jQuery UI Menu */ $.widget('mage.menu', $.ui.menu, { |
magento/magento2/blob/487f5f45/lib/web/jquery/jquery-ui.js#L11439-L11439
1 |
$.widget( "ui.menu", { |
More tips from Magento 2 cookbook