In this post we will check how to Add Category Product Edit Link and Display Category Products thumbnail image at Admin for Magento 2 Category Products Grid.
You can find complete module on Github at Magelearn_CategoryProductEdit
Let's start it by creating custom module.
Create folder inside app/code/Magelearn/CategoryProductEdit
Add registration.php file in it:
<?php use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Magelearn_CategoryProductEdit', __DIR__ );
Add composer.json file in it:
{ "name": "magelearn/module-category-product-edit", "description": "Provide Category Product Edit Link at Admin for Magento 2", "type": "magento2-module", "require": {}, "authors": [ { "name": "vijay rami", "email": "vijaymrami@gmail.com" } ], "license": "proprietary", "minimum-stability": "dev", "autoload": { "files": [ "registration.php" ], "psr-4": { "Magelearn\\CategoryProductEdit\\": "" } } }
Add etc/module.xml file in it:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magelearn_CategoryProductEdit"> <sequence> <module name="Magento_Catalog"/> </sequence> </module> </config>
We will provide Category Product edit link at admin by calling Admin event/observer. (adminhtml_block_html_before)
Create file at etc/adminhtml/events.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="adminhtml_block_html_before"> <observer name="admin_category_product_edit_link_html_block_html_before_observer" instance="Magelearn\CategoryProductEdit\Observer\AdminhtmlBlockHtmlBeforeObserver" /> </event> </config>
Call the observer file at Observer/AdminhtmlBlockHtmlBeforeObserver.php
<?php declare(strict_types=1); namespace Magelearn\CategoryProductEdit\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\Event\Observer; use Magento\Catalog\Block\Adminhtml\Category\Tab\Product; class AdminhtmlBlockHtmlBeforeObserver implements ObserverInterface { /** * Request instance * * @var RequestInterface */ protected $request; /** * @param RequestInterface $request */ public function __construct( RequestInterface $request ) { $this->request = $request; } /** * Add edit product column * * @param Observer $observer * @return void * @throws \Exception */ public function execute(Observer $observer) { $block = $observer->getEvent()->getBlock(); if (false === ($block instanceof Product)) { return; } $block->addColumn( 'action', [ 'header' => __('Action'), 'type' => 'action', 'getter' => 'getId', 'actions' => [ [ 'caption' => __('Edit'), 'url' => [ 'base' => 'catalog/product/edit', 'params' => ['store' => $this->request->getParam('store')] ], 'field' => 'id' ] ], 'filter' => false, 'sortable' => false, 'index' => 'stores', 'header_css_class' => 'col-action', 'column_css_class' => 'col-action' ] ); } }
Now to provide the Category Products Thumbnail Image,
We will add etc/adminhtml/di.xml file and Override Category Product Tab class and add code to display category products image.
We will add etc/adminhtml/di.xml file and Override Category Product Tab class and add code to display category products image.
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Catalog\Block\Adminhtml\Category\Tab\Product" type="Magelearn\CategoryProductEdit\Block\Adminhtml\Category\Tab\Product" /> </config>
Block/Adminhtml/Category/Tab/Product.php
<?php declare(strict_types=1); namespace Magelearn\CategoryProductEdit\Block\Adminhtml\Category\Tab; use Magento\Framework\Data\Collection; use Magelearn\CategoryProductEdit\Block\Adminhtml\Category\Tab\Product\Grid\Renderer\Image; use Magento\Framework\Exception\LocalizedException; class Product extends \Magento\Catalog\Block\Adminhtml\Category\Tab\Product { /** * @var array */ private array $thumbnailAttributes = ['thumbnail', 'small_image', 'image']; /** * Set collection object adding product thumbnail * * @param Collection $collection * @return void */ public function setCollection($collection): void { // Add multiple image attributes for better fallback foreach ($this->thumbnailAttributes as $attribute) { $collection->addAttributeToSelect($attribute); } $this->_collection = $collection; } /** * Add column image with a custom renderer and after column entity_id * * @return Product * @throws LocalizedException */ protected function _prepareColumns(): Product { parent::_prepareColumns(); $this->addColumnAfter( 'product_thumbnail', // Changed from 'image' to be more specific [ 'header' => __('Thumbnail'), 'index' => 'thumbnail', 'renderer' => Image::class, 'filter' => false, 'sortable' => false, 'column_css_class' => 'data-grid-thumbnail-cell', 'header_css_class' => 'col-thumbnail' ], 'entity_id' ); $this->sortColumnsByOrder(); return $this; } }Now as per the highlighted code above add our Image Renderer class at
Block/Adminhtml/Category/Tab/Product/Grid/Renderer/Image.php
<?php declare(strict_types=1); namespace Magelearn\CategoryProductEdit\Block\Adminhtml\Category\Tab\Product\Grid\Renderer; use Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer; use Magento\Catalog\Helper\Image as ImageHelper; use Magento\Framework\DataObject; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Escaper; class Image extends AbstractRenderer { /** * @var ImageHelper */ private ImageHelper $imageHelper; /** * @var StoreManagerInterface */ private StoreManagerInterface $storeManager; /** * @var Escaper */ private Escaper $escaper; /** * @param \Magento\Backend\Block\Context $context * @param ImageHelper $imageHelper * @param StoreManagerInterface $storeManager * @param Escaper $escaper * @param array $data */ public function __construct( \Magento\Backend\Block\Context $context, ImageHelper $imageHelper, StoreManagerInterface $storeManager, Escaper $escaper, array $data = [] ) { parent::__construct($context, $data); $this->imageHelper = $imageHelper; $this->storeManager = $storeManager; $this->escaper = $escaper; } /** * Render product thumbnail with fallback logic * * @param DataObject $row * @return string */ public function render(DataObject $row): string { $imageUrl = $this->getProductImageUrl($row); $altText = $this->escaper->escapeHtmlAttr($row->getName()); return sprintf( '<img src="%s" alt="%s" width="50" height="50" loading="lazy" class="admin__control-thumbnail"/>', $this->escaper->escapeUrl($imageUrl), $altText ); } /** * Get product image URL with fallback logic * * @param DataObject $row * @return string */ private function getProductImageUrl(DataObject $row): string { // Try thumbnail first if ($row->getThumbnail() && $row->getThumbnail() !== 'no_selection') { return $this->imageHelper->init($row, 'product_listing_thumbnail') ->setImageFile($row->getThumbnail()) ->getUrl(); } // Try small_image as fallback if ($row->getSmallImage() && $row->getSmallImage() !== 'no_selection') { return $this->imageHelper->init($row, 'product_listing_thumbnail') ->setImageFile($row->getSmallImage()) ->getUrl(); } // Try base image as last resort if ($row->getImage() && $row->getImage() !== 'no_selection') { return $this->imageHelper->init($row, 'product_listing_thumbnail') ->setImageFile($row->getImage()) ->getUrl(); } // Return placeholder if no images found return $this->imageHelper->getDefaultPlaceholderUrl('small_image'); } }
0 Comments On "Provide Category Product Edit Link and Category Product Thumbnail Image at Admin for Magento 2"