A brief memo on how to create grids in the Magento 2 admin panel. As an example, I took a simple three-column grid, the data for which (country codes for ISO 3166) come from the array specified in the code. In order to focus on the main aspects of building a grid, I dropped the maximum of the possible from the UI component descriptor (additional buttons, filters, sorting, bookmarks, ...) and transferred some of the settings to the data provider for the grid. If you can make it even shorter without losing readability, I will make the appropriate edits with maximum satisfaction (UPD: thanks to Oxidant's colleague for the controller). Example code on github'e .
Create an ACL entry ( ./etc/acl.xml
) to control access to the grid:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd"> <acl> <resources> <resource id="Magento_Backend::admin"> <resource id="Flancer32_Sample::sample" title="Samples" sortOrder="10"> <resource id="Flancer32_Sample::sample_grid" title="Grid" sortOrder="100"/> </resource> </resource> </resources> </acl> </config>
Add to the admin menu ( ./etc/adminhtml/menu.xml
) additional items:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd"> <menu> <add id="Flancer32_Sample::sample" title="Sample" translate="title" module="Flancer32_Sample" sortOrder="15" resource="Flancer32_Sample::sample"/> <add id="Flancer32_Sample::sample_grid" title="Grid" translate="title" module="Flancer32_Sample" sortOrder="100" parent="Flancer32_Sample::sample" action="sample/grid" resource="Flancer32_Sample::sample_grid"/> </menu> </config>
The redirect address is defined in action="..."
, access to menu items is in resource="..."
.
In the ./etc/adminhtml/routes.xml
file, ./etc/adminhtml/routes.xml
register a route fl32_sample_route
(internal identifier) with the name sample
(visible identifier, part of the URL):
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin"> <route id="fl32_sample_route" frontName="sample"> <module name="Flancer32_Sample"/> </route> </router> </config>
Request handlers at .../index.php/admin/sample/grid/*
located in the ./src/Controller/Adminhtml/Grid/
directory. Default handler: Index.php
:
namespace Flancer32\Sample\Controller\Adminhtml\Grid; class Index extends \Magento\Backend\App\Action { const ACL_RESOURCE = 'Flancer32_Sample::sample_grid'; const MENU_ITEM = 'Flancer32_Sample::sample_grid'; const TITLE = 'Sample Grid'; protected function _isAllowed() { $result = parent::_isAllowed(); $result = $result && $this->_authorization->isAllowed(self::ACL_RESOURCE); return $result; } public function execute() { /** @var \Magento\Backend\Model\View\Result\Page $resultPage */ $resultPage = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_PAGE); $resultPage->setActiveMenu(self::MENU_ITEM); $resultPage->getConfig()->getTitle()->prepend(__(self::TITLE)); return $resultPage; } }
All that the handler does is check the user's rights to access the grid and form the page according to the laout set for this route.
The layout description is located in the ./src/view/adminhtml/layout/
directory in the ./src/view/adminhtml/layout/
file, the name of which consists of three parts:
<?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> <referenceContainer name="content"> <uiComponent name="sample_grid"/> </referenceContainer> </body> </page>
In the description it is set that as the content on the page you need to display a UI component named sample_grid
.
The component descriptor is in the file ./src/view/adminhtml/ui_component/sample_grid.xml
<?xml version="1.0" encoding="UTF-8"?> <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <argument name="data" xsi:type="array"> <item name="js_config" xsi:type="array"> <item name="provider" xsi:type="string">sample_grid.sample_grid_data_source</item> <item name="deps" xsi:type="string">sample_grid.sample_grid_data_source</item> </item> <item name="spinner" xsi:type="string">sample_grid_columns</item> </argument> <dataSource name="sample_grid_data_source"> <argument name="dataProvider" xsi:type="configurableObject"> <argument name="class" xsi:type="string">Flancer32\Sample\Ui\Component\DataProvider\Grid</argument> <argument name="name" xsi:type="string">sample_grid_data_source</argument> </argument> </dataSource> <columns name="sample_grid_columns"> <column name="code2"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="sorting" xsi:type="string">asc</item> <item name="label" xsi:type="string" translate="true">Alpha-2</item> </item> </argument> </column> <column name="code3"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="label" xsi:type="string" translate="true">Alpha-3</item> </item> </argument> </column> <column name="code_num"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="label" xsi:type="string" translate="true">Numeric</item> </item> </argument> </column> </columns> </listing>
I tried to make the component code as small as possible (compare with that for CMS Pages ).
What you should pay attention to:
The class \Flancer32\Sample\Ui\Component\DataProvider\Grid
is responsible for the delivery of data. The constructor takes only one parameter ( name
) from the component descriptor, all the others are either injected by the Object Manager when creating the data provider, or are created in it. The data does not depend on filters / sorting and always returns the same (zakardkozheny in the provider itself).
namespace Flancer32\Sample\Ui\Component\DataProvider; class Grid extends \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider { public function __construct( $name, \Magento\Framework\Api\Search\ReportingInterface $reporting, \Magento\Framework\Api\Search\SearchCriteriaBuilder $searchCriteriaBuilder, \Magento\Framework\App\RequestInterface $request, \Magento\Framework\Api\FilterBuilder $filterBuilder, \Magento\Framework\UrlInterface $url ) { $primaryFieldName = 'id'; $requestFieldName = 'id'; $meta = []; $updateUrl = $url->getUrl('mui/index/render'); $data = [ 'config' => [ 'component' => 'Magento_Ui/js/grid/provider', 'update_url' => $updateUrl ] ]; parent::__construct($name, $primaryFieldName, $requestFieldName, $reporting, $searchCriteriaBuilder, $request, $filterBuilder, $meta, $data); } public function getData() { $result = [ 'items' => [ ['code2' => 'AU', 'code3' => 'AUS', 'code_num' => '036'], ['code2' => 'AT', 'code3' => 'AUT', 'code_num' => '040'], ['code2' => 'AZ', 'code3' => 'AZE', 'code_num' => '031'] ], 'totalRecords' => 3 ]; return $result; } }
Creating grids in Magento 2 is an exciting activity that you can devote not only free hours, but days, and maybe even weeks. Of course, over time, it will become less exciting and more mundane, but for now there is still an opportunity to add your own grid to the admin panel not in a couple of clicks, but by thoughtful and painstaking changes, if not a dozen files, then about zaharkodil data in the provider - would definitely reach this level, and maybe even exceeded). Maybe someone will be more courageous and want to use the built-in \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
and register for it in ./src/etc/di.xml
corresponding collection:
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory"> <arguments> <argument name="collections" xsi:type="array"> <item name="sample_grid_data_source" xsi:type="string">Vendor\Module\Model\ResourceModel\Grid\Collection</item> </argument> </arguments> </type>
I wish him good luck in this. I, unfortunately, have now exhausted my fascination limit.
All happy Magento 2 coding'a!
Source: https://habr.com/ru/post/310098/
All Articles