Adding a page to the backend requires, just like the frontend, a configured route, controller, and layout file. In order to display a grid page to show data from a table, there are currently three ways available:
Page
module:MagentoCmsBlockAdminhtmlPage
MagentoCmsBlockAdminhtmlPageGrid
Block
class created. The grid fields and options are defined in the layout XML file. This makes it possible to extend the grid easily by adding extra fields to the XML. An example of this can be found in the Customer Group code in the following:MagentoCustomerviewadminhtmllayoutcustomer_group_index.xml
In this example, we will use the last option to build a grid. As this option uses quite a large set of files and long XML listings, the complete code can be found on GitHub (https://github.com/Genmato/M2_Sample).
The following steps will describe how to add a backend data grid:
adminhtml
area:etc/adminhtml/routes.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin
"> <route id="sample" frontName="sample
"> <module name="Genmato_Sample" before="Magento_Backend" /> </route> </router> </config>
Controller/Adminhtml/Demolist/Index.php
<?php namespace GenmatoSampleControllerAdminhtmlDemolist; use MagentoBackendAppActionContext; use MagentoFrameworkViewResultPageFactory; use MagentoBackendAppAction as BackendAction; class Index extends BackendAction { /** * @var PageFactory */ protected $resultPageFactory; /** * @param Context $context * @param PageFactory $resultPageFactory */ public function __construct( Context $context, PageFactory $resultPageFactory ) { parent::__construct($context); $this->resultPageFactory = $resultPageFactory; } /** * Check the permission to run it * * @return bool */ protected function _isAllowed() { return $this->_authorization->isAllowed('Genmato_Sample::demolist'); } /** * Index action * * @return MagentoBackendModelViewResultPage */ public function execute() { /** @var MagentoBackendModelViewResultPage $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->setActiveMenu('Genmato_Sample::demolist'); $resultPage->addBreadcrumb(__('CMS'), __('CMS')); $resultPage->addBreadcrumb(__('Demo List'), __('Demo List')); $resultPage->getConfig()->getTitle()->prepend(__('Demo List')); return $resultPage; } }
etc/acl.xml
<?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="Magento_Backend::content">
<resource id="Magento_Backend::content_elements">
<resource id="Genmato_Sample::demolist" title="Demo List" sortOrder="10" />
</resource>
</resource>
</resource>
</resources>
</acl>
</config>
layout
file to specify the grid uiComponent
used:view/adminhtml/layout/sample_demolist_index.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">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<uiComponent name="sample_demolist_listing"/>
</referenceContainer>
</body>
</page>
uiComponent
configuration:The referenced
uiComponent
configuration is quite large. In the sample code (on GitHub), this file can be found at the following:
uiComponent
to the dependency injection configuration:etc/di.xml
<?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="GenmatoSampleModelDemoInterface" type="GenmatoSampleModelDemo" /> <type name="MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory"> <arguments> <argument name="collections" xsi:type="array"> <item name="sample_demolist_listing_data_source" xsi:type="string">GenmatoSampleModelResourceModelDemoGridCollection</item> </argument> </arguments> </type> <type name="GenmatoSampleModelResourceModelDemoGridCollection"> <arguments> <argument name="mainTable" xsi:type="string">genmato_demo</argument> <argument name="eventPrefix" xsi:type="string">sample_demolist_grid_collection</argument> <argument name="eventObject" xsi:type="string">sample_demolist_collection</argument> <argument name="resourceModel" xsi:type="string">GenmatoSampleModelResourceModelDemo</argument> </arguments> </type> <virtualType name="DemoGridFilterPool" type="MagentoFrameworkViewElementUiComponentDataProviderFilterPool"> <arguments> <argument name="appliers" xsi:type="array"> <item name="regular" xsi:type="object">MagentoFrameworkViewElementUiComponentDataProviderRegularFilter</item> <item name="fulltext" xsi:type="object">MagentoFrameworkViewElementUiComponentDataProviderFulltextFilter</item> </argument> </arguments> </virtualType> <virtualType name="DemoGridDataProvider" type="MagentoFrameworkViewElementUiComponentDataProviderDataProvider"> <arguments> <argument name="collection" xsi:type="object" shared="false">GenmatoSampleModelResourceModelDemoCollection</argument> <argument name="filterPool" xsi:type="object" shared="false">DemoGridFilterPool</argument> </arguments> </virtualType> </config>
Controller/Adminhtml/Demolist/MassDelete.php
<?php namespace GenmatoSampleControllerAdminhtmlDemolist; use MagentoFrameworkControllerResultFactory; use MagentoBackendAppActionContext; use MagentoUiComponentMassActionFilter; use GenmatoSampleModelResourceModelDemoCollectionFactory; use MagentoBackendAppAction; class MassDelete extends Action { /** * @var CollectionFactory */ protected $collectionFactory; /** * @param Context $context * @param Filter $filter * @param CollectionFactory $collectionFactory */ public function __construct(Context $context, Filter $filter, CollectionFactory $collectionFactory) { $this->filter = $filter; $this->collectionFactory = $collectionFactory; parent::__construct($context); } /** * Execute action * * @return MagentoBackendModelViewResultRedirect */ public function execute() { $collection = $this->filter->getCollection($this->collectionFactory->create()); $collectionSize = $collection->getSize(); foreach ($collection as $item) { $item->delete(); } $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize)); /** @var MagentoBackendModelViewResultRedirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); return $resultRedirect->setPath('*/*/'); } }
etc/adminhtml/menu.xml
<?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="Genmato_Sample::demolist" title="Demo List" module="Genmato_Sample" sortOrder="10" parent="Magento_Backend::content_elements" action="sample/demolist" resource="Genmato_Sample::demolist"/> </menu> </config>
The controller and layout file are the same for the frontend, only the backend is protected through an ACL. This allows administrators to create specific user rules and allow access only to the selected pages.
The resource access is checked in the controller in the following function:
protected function _isAllowed()
As the complete configuration through uiComponent results in a large XML file, we will explain some parts on how they are configured and hook in to the system.
The data source is specified through the XML node:
<listing>
<dataSource name="sample_demolist_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">DemoGridDataProvider</argument>
The specified data class, DemoGridDataProvider
, is configured through dependency injection and specified in the etc/di.xml
file. Here, DemoGridDataProvider
corresponds to the GenmatoSampleModelResourceModelDemoCollection
collection. Additionally, DemoGridFilterPool
and the collection are configured through this file to load the data.
It is also easy to specify multiple mass actions to be used in the grid; you can specify the title, action to execute, and optional message alert box:
<massaction name="listing_massaction"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="selectProvider" xsi:type="string">sample_demolist_listing.sample_demolist_listing.sample_demolist_columns.ids</item> <item name="indexField" xsi:type="string">demo_id</item> </item> </argument> <action name="delete"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="type" xsi:type="string">delete</item> <item name="label" xsi:type="string" translate="true">Delete</item> <item name="url" xsi:type="url" path="sample/demolist/massDelete"/> <item name="confirm" xsi:type="array"> <item name="title" xsi:type="string" translate="true">Delete items</item> <item name="message" xsi:type="string" translate="true">Are you sure you want to delete selected items?</item> </item> </item> </argument> </action> </massaction>
In this example, we add an option to delete records from the database. In order to delete the records from the database, you need to create a controller that handles the removal of the records. You need to create a Controller
class for every action you specify, this controller contains your custom code to be executed.
By adding the menu option in the Content menu below the Pages menu item, the page can be accessed through the backend. This link action will go to the specified sample/demolist
URL that will result in the full URL:
http://example.com/admin/sample/demolist/
The resource
argument defines the ACL that is used to show/hide the menu option depending on the user rights:
When clicking on the menu option, the resulting page will look as follows:
For more information about uiComponents that are available, you can refer to the following:
http://devdocs.magento.com/guides/v2.0/ui-components/ui-component.html
3.148.144.228