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:
1 2 3 4 5 6 7 8 9 | <?php use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register( ComponentRegistrar::MODULE, 'Magelearn_CategoryProductEdit' , __DIR__ ); |
Add composer.json file in it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | { "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:
1 2 3 4 5 6 7 8 | <? 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
1 2 3 4 5 6 7 | <? 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
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 | <?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.
1 2 3 4 | <? 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
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 | <?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 ; } } |
Block/Adminhtml/Category/Tab/Product/Grid/Renderer/Image.php
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | <?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"