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

Admin-Grid für Prämien

Admin-Grid für Prämien

~6 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Mit Model, ResourceModel und einer filterbaren Collection fehlt nur noch eine sichtbare Verwaltungsoberfläche im Admin, unter der Prämien angelegt, bearbeitet und gelöscht werden können. Dieses Kapitel zeigt die minimale Verdrahtung - die vollständige Erklärung von UI Components, Listing- und Formular-XML liefert die eigene, dedizierte Tutorial-Serie "Admin-Grids & Formulare in Magento 2" dieses Katalogs (Serie tutorial-admin-grids-forms-*, Identifier admin-grids-formulare) - wer UI Components noch nicht kennt, findet dort die vollständige Grundlage.

ACL und Menüpunkt

Die Prämien-Verwaltung bekommt eine eigene ACL-Ressource, als Kind der Top-Level-Ressource Mironsoft_Loyalty::loyalty aus Kapitel 7.

app/code/Mironsoft/Loyalty/etc/acl.xml (Ausschnitt, erweitert um Kapitel 16)
<acl>
    <resources>
        <resource id="Magento_Backend::admin">
            <resource id="Mironsoft_Loyalty::loyalty" title="Mironsoft Loyalty">
                <resource id="Mironsoft_Loyalty::rewards" title="Rewards"/>
                <!-- Mironsoft_Loyalty::config_section aus Kapitel 7 bleibt unveraendert -->
            </resource>
        </resource>
    </resources>
</acl>
app/code/Mironsoft/Loyalty/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="Mironsoft_Loyalty::rewards" title="Rewards"
             module="Mironsoft_Loyalty" sortOrder="10"
             parent="Mironsoft_Loyalty::loyalty"
             action="mironsoft_loyalty/reward/index"
             resource="Mironsoft_Loyalty::rewards"/>
    </menu>
</config>

Controller und UI Component

Der Index-Controller rendert nur das Layout-Handle, die eigentliche Grid-Logik steckt vollständig in der UI-Component-XML - dasselbe Muster wie bei jedem anderen Magento-Admin-Grid.

app/code/Mironsoft/Loyalty/Controller/Adminhtml/Reward/Index.php
<?php

declare(strict_types=1);

namespace Mironsoft\Loyalty\Controller\Adminhtml\Reward;

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

/**
 * Renders the reward admin grid.
 */
class Index extends Action
{
    /**
     * @var string
     */
    public const ADMIN_RESOURCE = 'Mironsoft_Loyalty::rewards';

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

    /**
     * Builds the admin page holding the reward_listing UI component.
     *
     * @return Page
     */
    public function execute(): Page
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu(self::ADMIN_RESOURCE);
        $resultPage->getConfig()->getTitle()->prepend(__('Rewards'));

        return $resultPage;
    }
}
<!-- app/code/Mironsoft/Loyalty/view/adminhtml/ui_component/reward_listing.xml (Ausschnitt) -->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <dataSource name="reward_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Magento\Ui\DataProvider\AbstractDataProvider</argument>
            <argument name="name" xsi:type="string">reward_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
        </argument>
    </dataSource>
    <!-- columns: entity_id, title, points_cost, reward_type, is_active, actions ->
         siehe die dedizierte Admin-Grids-Serie für die vollständige Erklärung -->
</listing>

Der dataProvider braucht eine di.xml-Verdrahtung, die den collection-Konstruktor-Parameter auf Mironsoft\Loyalty\Model\ResourceModel\Reward\CollectionFactory aus Kapitel 15 zeigen lässt - dieselbe Collection, die auch der Prämienkatalog im Frontend (Block 6) verwendet, hier ohne addActiveFilter(), damit auch inaktive Prämien im Admin sichtbar bleiben.

EAV-Collection direkt im Grid: ein bewusster Kompromiss

Magento\Eav\Model\Entity\Collection\AbstractCollection stellt addFieldToFilter() als Alias für addAttributeToFilter() bereit (Kapitel 15) und lässt sich dadurch technisch direkt als Datenquelle für AbstractDataProvider verwenden - ohne zusätzlichen Umweg.

Achtung: Magentos eigene Admin-Grids für Kunden und Produkte greifen trotzdem nicht direkt auf die rohe EAV-Collection zu, sondern auf eigene, per Indexer befüllte, flache Grid-Tabellen (customer_grid_flat, die Produktindizes) - genau aus den Performance-Gründen, die Kapitel 18 im Detail behandelt. Für den Prämienkatalog dieser Serie, mit erwartungsgemäß niedriger Zeilenzahl im zweistelligen bis niedrigen dreistelligen Bereich, ist die direkte EAV-Collection ein pragmatischer, vertretbarer Kompromiss. Wächst der Katalog signifikant, gilt dieselbe Guideline wie für Magentos eigene Grids: über einen flachen Index nachdenken.

Damit steht ein funktionsfähiges Admin-Grid - Kapitel 17 kümmert sich um das Gegenstück auf der Formularseite: Pflichtfelder und Validierung.