Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

The listing.xml Skeleton: DataSource, Columns, Toolbar

The listing.xml Skeleton: DataSource, Columns, Toolbar

~8 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026

The grid itself is declared in an XML file under view/adminhtml/ui_component/, named after the name the Layout XML will reference later - here mironsoft_announcement_listing.xml. This chapter builds the skeleton: an empty but functioning table with a single column.

Controller and Layout XML

First we need an index controller that calls the matching layout handle:

app/code/Mironsoft/Announcement/Controller/Adminhtml/Announcement/Index.php
<?php

declare(strict_types=1);

namespace Mironsoft\Announcement\Controller\Adminhtml\Announcement;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;

/**
 * Renders the announcement grid page.
 */
class Index extends Action
{
    public const ADMIN_RESOURCE = 'Mironsoft_Announcement::announcement';

    /**
     * @param Context $context Backend action context.
     * @param PageFactory $resultPageFactory Factory for the page result.
     */
    public function __construct(
        Context $context,
        private readonly PageFactory $resultPageFactory,
    ) {
        parent::__construct($context);
    }

    /**
     * Builds the grid page result.
     *
     * @return Page
     */
    public function execute(): Page
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Mironsoft_Announcement::announcement');
        $resultPage->getConfig()->getTitle()->prepend('Announcements');

        return $resultPage;
    }
}
app/code/Mironsoft/Announcement/view/adminhtml/layout/mironsoft_announcement_announcement_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">
    <body>
        <referenceContainer name="content">
            <uiComponent name="mironsoft_announcement_listing"/>
        </referenceContainer>
    </body>
</page>

The layout file name follows the pattern {frontName}_{controllerFolder}_{action} in lowercase; the <uiComponent name="..."/> element references exactly the listing XML's file name (without extension).

The listing.xml skeleton

A minimal but complete listing declaration has four parts: the argument configuration (namespace, buttons), the dataSource (reference to the DataProvider, chapter 5), the columns section, and optionally listingToolbar for search, filters, mass actions, and an export button.

app/code/Mironsoft/Announcement/view/adminhtml/ui_component/mironsoft_announcement_listing.xml
<?xml version="1.0"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_components.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">mironsoft_announcement_listing.mironsoft_announcement_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">announcement_columns</item>
        <item name="deps" xsi:type="string">mironsoft_announcement_listing.mironsoft_announcement_listing_data_source</item>
    </argument>

    <dataSource name="mironsoft_announcement_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Mironsoft\Announcement\Ui\DataProvider\Listing\AnnouncementDataProvider</argument>
            <argument name="name" xsi:type="string">mironsoft_announcement_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">announcement_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
            </item>
        </argument>
    </dataSource>

    <columns name="announcement_columns">
        <column name="announcement_id">
            <settings>
                <filter>text</filter>
                <label translate="true">ID</label>
                <sorting>desc</sorting>
            </settings>
        </column>
    </columns>
</listing>

The provider chain ({listing_name}.{listing_name}_data_source) is the most common cause of an empty page: the listing name, the dataSource name, and the provider value inside js_config must match exactly, or the JavaScript won't find any data (chapter 26 covers exactly this symptom).

Making it visible

bin/magento setup:upgrade
bin/cache-clean

Tipp: In local development, bin/cache-clean is usually enough to make changes to listing.xml/form.xml visible - these files land in the UI Component and layout cache, not in pub/static, so no static content deploy is needed here.

The grid is now reachable at mironsoft_announcement/announcement/index - but still without real data, because the referenced DataProvider class doesn't exist yet. Chapter 5 builds exactly that.