There are 2 ways to achieve this:
Lets start by creating a module Vendor_RowCounter
, with the required files, and shared files for both solutions:
- Add
registration.php
:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Vendor_RowCounter',
__DIR__
);
- Add
etc/module.xml
:
<?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="Vendor_RowCounter"/>
</config>
- Create a block file,
Block/Adminhtml/Items/Column/Row.php
:
<?php
declare(strict_types=1);
namespace Vendor\RowCounter\Block\Adminhtml\Items\Column;
use Magento\Sales\Block\Adminhtml\Items\Column\DefaultColumn;
class Row extends DefaultColumn
{
/** @var int */
private int $row = 1;
/**
* @return int
*/
public function getRow(): int
{
return $this->row++;
}
}
- Create template file,
view/adminhtml/templates/items/column/row.phtml
:
<?php
use Vendor\RowCounter\Block\Adminhtml\Items\Column\Row;
/** @var Row $block */
?>
<?php if ($_item = $block->getItem()): ?>
<div id="order_item_<?= (int) $_item->getId() ?>_row">
<?= $block->getRow(); ?>
</div>
<?php endif; ?>
Solution #1 (By adding a column via sales_order_view.xml
):
- Create
view/adminhtml/layout/sales_order_view.xml
:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="order_items">
<arguments>
<argument name="columns" xsi:type="array">
<item name="row" xsi:type="string" translate="true">#</item>
</argument>
</arguments>
<block class="Vendor\RowCounter\Block\Adminhtml\Items\Column\Row" name="column_row" template="Vendor_RowCounter::items/column/row.phtml" group="column"/>
</referenceBlock>
<referenceBlock name="default_order_items_renderer">
<arguments>
<argument name="columns" xsi:type="array">
<item name="row" xsi:type="string" translate="true">col-row</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
The drawback with this approach is you won't have control over the order of columns and a new column will be added at the end:
Solution #2 (By adding a column via plugins):
To take more control over the column order, we can add column via plugin instead of sales_order_view.xml
.
- Add
view/adminhtml/layout/sales_order_view.xml
:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="order_items">
<block class="Vendor\RowCounter\Block\Adminhtml\Items\Column\Row" name="column_row" template="Vendor_RowCounter::items/column/row.phtml" group="column"/>
</referenceBlock>
</body>
</page>
- Add
etc/adminhtml/di.xml
for the plugins:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Sales\Block\Adminhtml\Order\View\Items">
<plugin name="Vendor_RowCounter::OrderViewItems" type="Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items"/>
</type>
<type name="Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer">
<plugin name="Vendor_RowCounter::OrderViewItemsDefaultRenderer" type="Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer"/>
</type>
</config>
- Add first plugin class,
Plugin/Block/Adminhtml/Order/View/Items.php
<?php
declare(strict_types=1);
namespace Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View;
use Magento\Sales\Block\Adminhtml\Order\View\Items as BaseItems;
class Items
{
/**
* @param BaseItems $subject
* @param array $result
*
* @return array
*/
public function afterGetColumns(
BaseItems $subject,
array $result
): array {
return [
'row' => __('#'),
...$result,
];
}
}
- Add the other plugin,
Plugin/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
<?php
declare(strict_types=1);
namespace Vendor\RowCounter\Plugin\Block\Adminhtml\Order\View\Items\Renderer;
use Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer as BaseDefaultRenderer;
class DefaultRenderer
{
/**
* @param BaseDefaultRenderer $subject
* @param array $result
*
* @return array
*/
public function afterGetColumns(
BaseDefaultRenderer $subject,
array $result
): array {
return [
'row' => 'col-row',
...$result,
];
}
}
Result of Solution #2: