In this topic, we will show you how to create a table in the database and manage it by creating a controller with a grid and menu item. In this case, we will create a blog with posts management.
Notice: Creating the module tutorial is here.
STEP 1. Create a controller file
First, you should create the controller file. In this example, there will be a controller with a blog index (grid).
The file should have path like this pattern:
app/code/[your_namespace]/[your_module]/Controller/Adminhtml/[your_controller_name]/[your_controller_action].php
In our case it’s:
app/code/PandaGroup/MyAdminController/Controller/Adminhtml/Blog/Index.php
The code inside:
namespace PandaGroup\MyAdminController\Controller\Adminhtml\Blog;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
/**
* Class Index
* @package PandaGroup\MyAdminController\Controller\Adminhtml\Blog
*/
class Index extends Action
{
protected $resultPageFactory = false;
/**
* Index constructor.
* @param Context $context
* @param PageFactory $resultPageFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
/**
* @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\View\Result\Page
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend((__('Blog')));
return $resultPage;
}
}
STEP 2. Create routes.xml file
Secondly, you should create an XML file where you define name, id, and module name.
The file should be like this example path:
app/code/[your_namespace]/[your_module]/etc/adminhtml/routes.xml
In our case it’s:
app/code/PandaGroup/MyAdminController/etc/adminhtml/routes.xml
The code inside:
<?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="pandagroup_myadmincontroller
" frontName="pandagroup_myadmincontroller
">
<module name="PandaGroup_MyAdminController"/>
</route>
</router>
</config>
Notice: Make sure that router id is admin.
STEP 3. Create Model, Resource, Collection
You can check it here. 🙂
STEP 4. Create menu.xml
Now it’s time to create a menu item with a proper link to get on the blog index page with a grid. To do that we have to create a file with the path:
app/code/[your_namespace]/[your_module]/etc/adminhtml/menu.xml
In our case it’s:
app/code/PandaGroup/MyAdminController/etc/adminhtml/menu.xml
The code inside:
<?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="PandaGroup_MyAdminController::index" title="Blog" module="PandaGroup_MyAdminController" sortOrder="10" resource="PandaGroup_MyAdminController::index"/>
<add id="PandaGroup_MyAdminController::blog" title="Manage Blog" module="PandaGroup_MyAdminController" sortOrder="20" action="pandagroup_myadmincontroller
/blog" resource="PandaGroup_MyAdminController::blog" parent="PandaGroup_MyAdminController::index"/>
</menu>
</config>
STEP 5. Create Admin Grid Dependency Injection.
Firstly we need to create the dependency injection file (here you can declare what and where you want to inject – class etc.). In this case, we will connect our grid model with data (resource). The path of this file should be like:
app/code/[your_namespace]/[your_module]/etc/di.xml
In our case it’s:
app/code/PandaGroup/MyAdminController/etc/di.xml
Content of the file:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="pandagroup_myadmincontroller_blog_listing_data_source" xsi:type="string">PandaGroup\MyAdminController\Model\ResourceModel\Blog\Grid\Collection</item>
</argument>
</arguments>
</type>
<virtualType name="PandaGroup\MyAdminController\Model\ResourceModel\Blog\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">pandagroup_myadmincontroller_blog</argument>
<argument name="resourceModel" xsi:type="string">PandaGroup\MyAdminController\Model\ResourceModel\Blog</argument>
</arguments>
</virtualType>
</config>
STEP 6. Create Layout File.
In this file, you can declare what component should be used in the layout of the page. We have the action declared in menu.xml and routes.xml (front name) like pandagroup_myadmincontroller/blog/index, so we need to create a file named: pandagroup_myadmincontroller_blog_index.xml. The file path should be like:
app/code/[your_namespace]/[your_module]/view/adminhtml/layout/pandagroup_myadmincontroller_blog_index.xml
In our case it’s:
app/code/PandaGroup/MyAdminController/view/adminhtml/layout/pandagroup_myadmincontroller_blog_index.xml
Here we don’t want to change header or footer. We need to change the body – add components with a grid. So here is the content of the file:
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<uiComponent name="pandagroup_myadmincontroller_blog_listing"/>
</referenceContainer>
</body>
</page>
STEP 6. Create a UI Component File.
In this file, you can build your component. There are 2 basic types of components: listing and form. In this case, we will create a listing (grid).
The name of this file should be exactly the same as we declare in the layout file. So here will be pandagroup_myadmincontroller_blog_listing.xml.
The file path should be like:
app/code/[your_namespace]/[your_module]/view/adminhtml/layout/pandagroup_myadmincontroller_blog_index.xml
In our case it’s:
app/code/PandaGroup/MyAdminController/view/adminhtml/layout/pandagroup_myadmincontroller_blog_index.xml
<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">pandagroup_myadmincontroller_blog_listing.pandagroup_myadmincontroller_blog_listing_data_source
</item>
<item name="deps"
xsi:type="string">pandagroup_myadmincontroller_blog_listing.pandagroup_myadmincontroller_blog_listing_data_source
</item>
</item>
<item name="spinner" xsi:type="string">spinner_columns</item>
<item name="buttons" xsi:type="array">
<item name="add" xsi:type="array">
<item name="name" xsi:type="string">add</item>
<item name="label" xsi:type="string" translate="true">New Post</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/new</item>
</item>
</item>
</argument>
<dataSource name="nameOfDataSource">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class"
xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
</argument>
<argument name="name" xsi:type="string">pandagroup_myadmincontroller_blog_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">post_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">post_id</item>
</item>
</item>
</argument>
</argument>
</dataSource>
<columns name="spinner_columns">
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="resizeEnabled" xsi:type="boolean">false</item>
<item name="resizeDefaultWidth" xsi:type="string">70</item>
<item name="indexField" xsi:type="string">post_id</item>
</item>
</argument>
</selectionsColumn>
<column name="post_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">textRange</item>
<item name="sorting" xsi:type="string">asc</item>
<item name="label" xsi:type="string" translate="true">Id</item>
</item>
</argument>
</column>
<column name="title">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Title</item>
</item>
</argument>
</column>
<column name="slug">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Slug</item>
</item>
</argument>
</column>
<column name="status">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Status</item>
</item>
</argument>
</column>
<column name="created_at" className="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Created At</item>
</item>
</argument>
</column>
</columns>
</listing>
So here we’ve added a “New Post” button (which doesn’t work now because there is no controller, layout, route, etc. for this page) columns with text & date. Here you can also declare filter & sorting type etc. More information about components you can find here:
https://devdocs.magento.com/guides/v2.4/ui_comp_guide/components/ui-listing-grid.html
And that’s it. Now you can clear & flush the cache and check if everything works.