Programmatically Set Product Position in a Category in Magento 2
The product position value determines the order of products on the category page. The product position value of new products in a category is preset to zero.
By default, Magento displays the products in a descending position on the category pages.
For example, 10, 9, 8… 0.
Therefore, all new products are displayed at the bottom of the list. You can manually change these product position values from the Edit Category > Products in the Category section.
category in Magento 2” width=”700″ height=”356″ />
But what if you want to programmatically set product position in a category in Magento 2?
You can do that by creating a custom module!
In this post, we’ll learn to assign product positions for a specific category of Magento 2.
Earlier, we showed you the method to sort products by quantity in Magento 2, do check it out!
Method to Programmatically Set Product Position on Category Page in Magento 2
You can programmatically set product positions on category pages in Magento 2 through a custom module. Here’s how to do it:
First, create a module.xml file at the vendor/module/etc/ directory.
1 2 3 4 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Meetanshi_PositionProducts" active="true" schema_version="1.0.1" setup_version="1.0.1"> </module> </config> |
Create registration.php file inside the vendor/module/ folder.
1 2 3 4 5 |
<MagentoFrameworkComponentComponentRegistrar::register( MagentoFrameworkComponentComponentRegistrar::MODULE, 'Meetanshi_PositionProducts', __DIR__ ); |
Add events.xml file at the vendor/module/etc directory.
1 2 3 4 5 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="catalog_product_save_after"> <observer name="meetanshi_set_product_position" instance="MeetanshiPositionProductsObserverSetProductPositions" /> </event> </config> |
Now, add the following code inside the vendor/module/Observer/SetProductPositions.php file for the observer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<namespace MeetanshiPositionProductsObserver; use MagentoFrameworkEventObserver; use MagentoFrameworkEventObserverInterface; use MagentoCatalogModelProduct; use MagentoCatalogModelResourceModelProductCollectionFactory as ProductCollectionFactory; use MagentoStoreModelStoreManagerInterface; use MagentoCatalogModelCategoryFactory; use MagentoCatalogModelResourceModelCategory as CategoryResource; class SetProductPositions implements ObserverInterface { /** * @var ProductCollectionFactory */ private $productCollectionFactory; /** * @var StoreManagerInterface */ protected $storeManager; /** * @var CategoryFactory */ protected $categoryFactory; /** * @var CategoryResource */ protected $categoryResource; public function __construct(ProductCollectionFactory $productCollectionFactory, StoreManagerInterface $storeManager, CategoryFactory $categoryFactory, CategoryResource $categoryResource) { $this->productCollectionFactory = $productCollectionFactory; $this->categoryFactory = $categoryFactory; $this->categoryResource = $categoryResource; $this->storeManager = $storeManager; } public function execute(Observer $observer) { $product = $observer->getEvent()->getProduct(); // Get the category ID of the new product. $categoryIds = $product->getCategoryIds(); MagentoFrameworkAppObjectManager::getInstance() ->get(PsrLogLoggerInterface::class)->info(print_r($categoryIds,true)); // Get the new product position. $newPosition = 500; // Change the product position. if ($product->isObjectNew()) { MagentoFrameworkAppObjectManager::getInstance() ->get(PsrLogLoggerInterface::class)->info('New product'); $this->changeProductPosition($categoryIds, $product->getId(), $newPosition); } else { MagentoFrameworkAppObjectManager::getInstance() ->get(PsrLogLoggerInterface::class)->info('Old product'); } } private function changeProductPosition($categoryIds, $productId, $newPosition) { foreach($categoryIds as $categoryId) { MagentoFrameworkAppObjectManager::getInstance() ->get(PsrLogLoggerInterface::class)->info(print_r($categoryId,true)); $category = $this->categoryFactory->create()->load($categoryId); $products = $category->getProductsPosition(); $products[$productId] = $newPosition; $category->setPostedProducts($products); $category->save(); } } } |
Tweak the $newPosition
value per your needs.
In the above module, the event is triggered when a new product is saved in the category. Then the position of the newly added product is changed to the defined value.
That’s it! This is how you can programmatically set product position in a category in Magento 2.
Found this solution helpful? Share it with your friends.
Feel free to comment your thoughts on this.
Thank You! 🍀
Jignesh Parmar
An expert in his field, Jignesh is the team leader at Meetanshi and a certified Magento developer. His passion for Magento has inspired others in the team too. Apart from work, he is a cricket lover.
Prev
How to Implement Dynamic Pricing in Shopify
15+ Best Ebay Alternatives in 2024 (Websites Like Ebay)
Next