Skip to content

Instantly share code, notes, and snippets.

@Dan0sz
Last active August 13, 2019 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dan0sz/a2219954b0e3894f361b7a37fe97d65b to your computer and use it in GitHub Desktop.
Save Dan0sz/a2219954b0e3894f361b7a37fe97d65b to your computer and use it in GitHub Desktop.
A module to add products to Magento 2's topmenu
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author: Daan van den Bergh
* @url: https://daan.dev
* @package: Dan0sz/TopmenuProducts
* @copyright: (c) 2019 Daan van den Bergh
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="page_block_html_topmenu_gethtml_before">
<observer name="dan0sz_topmenu_products_gethtml_before" instance="Dan0sz\TopmenuProducts\Observer\TopmenuGetHtmlBefore" />
</event>
</config>
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author: Daan van den Bergh
* @url: https://daan.dev
* @package: Dan0sz/TopmenuProducts
* @copyright: (c) 2019 Daan van den Bergh
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Dan0sz_TopmenuProducts" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog" />
</sequence>
</module>
</config>
<?php
/**
* @author : Daan van den Bergh
* @url : https://daan.dev
* @package : Dan0sz/TopmenuProducts
* @copyright: (c) 2019 Daan van den Bergh
*/
namespace Dan0sz\TopmenuProducts\Observer;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\Framework\App\Request\Http as Request;
use Magento\Framework\Data\Tree\Node;
use Magento\Framework\Data\Tree\NodeFactory;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class TopmenuGetHtmlBefore implements ObserverInterface
{
/** @var ProductCollection $productCollection */
private $productCollection;
/** @var Node $node */
private $node;
/** @var Request $request */
private $request;
/**
* TopmenuGetHtmlBefore constructor.
*
* @param ProductCollectionFactory $productCollection
* @param NodeFactory $node
*/
public function __construct(
ProductCollectionFactory $productCollection,
NodeFactory $node
) {
$this->productCollection = $productCollection;
$this->node = $node;
}
/**
* @param Observer $observer
*
* @return $this|void
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function execute(Observer $observer)
{
/** @var Node $menu */
$menu = $observer->getData('menu');
/** @var Request request */
$this->request = $observer->getData('request');
$products = $this->getTopmenuProducts();
$this->addProductsToMenu($products, $menu);
return $this;
}
/**
* @return ProductCollection
*/
private function getTopmenuProducts()
{
/** @var ProductCollection $productCollection */
$productCollection = $this->productCollection->create();
$productCollection->addAttributeToSelect(
[
'status',
'entity_id',
'name',
'url_key'
]
);
// This is where you add the entity_id's of the products you want to add to your menu.
$productCollection
->addAttributeToFilter('entity_id', ['in' => [1, 2, 3, 4]]);
// And perhaps another attribute by which you want to sort?
$productCollection->addAttributeToSort('entity_id');
return $productCollection;
}
/**
* @param ProductCollection $products
* @param Node $menu
*
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function addProductsToMenu(ProductCollection $products, Node $menu)
{
foreach ($products as $product) {
$node = $this->node->create(
[
'data' => $this->getProductAsArray($product),
'idField' => 'id',
'tree' => $menu->getTree()
]
);
$menu->addChild($node);
}
}
/**
* @param Product $product
*
* @return array
*/
private function getProductAsArray(Product $product)
{
return [
'name' => $product->getName(),
'id' => 'product-node-' . $product->getId(),
'url' => $product->getProductUrl(),
'has_active' => false,
'is_active' => $this->checkIsActive($product),
'is_category' => false,
'is_parent_active' => true
];
}
/**
* @param Product $product
*
* @return bool
*/
private function checkIsActive(Product $product)
{
return $product->getId() == $this->request->getParam('id');
}
}
<?php
/**
* @author: Daan van den Bergh
* @url: https://daan.dev
* @package: Dan0sz/TopmenuProducts
* @copyright: (c) 2019 Daan van den Bergh
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Dan0sz_TopmenuProducts',
__DIR__
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment