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 atBlock/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"