Страница в панели управления
Страница панели управления устроена так же, как страница витрины: маршрут, действие, макет, шаблон. Отличий три: файлы лежат в папках adminhtml, страницу защищает право доступа, а попадают на неё через пункт меню. Создадим страницу «Отзывы».
app/code/Acme/Hello/
├── Controller/
│ └── Adminhtml/
│ └── Review/
│ └── Index.php новый файл
├── etc/
│ ├── acl.xml новый файл
│ └── adminhtml/
│ ├── menu.xml новый файл
│ └── routes.xml новый файл
└── view/
└── adminhtml/
├── layout/
│ └── hello_review_index.xml новый файл
└── templates/
└── reviews.phtml новый файлПраво доступа
Права описывают в файле etc/acl.xml. Администратор отмечает их для ролей сотрудников в разделе «Система → Роли пользователей».
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/acl.xml -->
<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="Acme_Hello::reviews" title="Отзывы Hello" sortOrder="100"/>
</resource>
</resources>
</acl>
</config>Файл объявляет право Acme_Hello::reviews. Идентификатор права состоит из имени модуля и слова после двух двоеточий.
Маршрут панели
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/adminhtml/routes.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="hello" frontName="hello">
<module name="Acme_Hello" before="Magento_Backend"/>
</route>
</router>
</config>От маршрута витрины он отличается папкой adminhtml и значением router id="admin". Адрес страницы будет /admin/hello/review/index.
Действие
Действия панели лежат в папке Controller/Adminhtml и наследуются от Magento\Backend\App\Action:
// app/code/Acme/Hello/Controller/Adminhtml/Review/Index.php
namespace Acme\Hello\Controller\Adminhtml\Review;
use Magento\Backend\App\Action;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
class Index extends Action implements HttpGetActionInterface
{
public const ADMIN_RESOURCE = 'Acme_Hello::reviews';
public function execute()
{
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$page->setActiveMenu('Acme_Hello::reviews');
$page->getConfig()->getTitle()->prepend(__('Отзывы'));
return $page;
}
}Константа ADMIN_RESOURCE закрывает страницу от сотрудников без нужного права: проверку выполняет родительский класс. Свойство resultFactory тоже достаётся от него. Метод setActiveMenu() подсвечивает пункт меню.
Пункт меню
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/adminhtml/menu.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Acme_Hello::reviews" title="Отзывы Hello" module="Acme_Hello" sortOrder="50"
parent="Magento_Catalog::catalog" action="hello/review/index" resource="Acme_Hello::reviews"/>
</menu>
</config>Пункт появится в меню «Каталог». Атрибут action — адрес страницы без /admin, а resource — право, без которого пункт не виден.
Макет и шаблон
Имя макета строится так же, как на витрине, но файл лежит в view/adminhtml/layout:
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/view/adminhtml/layout/hello_review_index.xml -->
<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">
<block name="hello.reviews" template="Acme_Hello::reviews.phtml"/>
</referenceContainer>
</body>
</page><!-- app/code/Acme/Hello/view/adminhtml/templates/reviews.phtml -->
<p>Здесь будет список отзывов.</p>Проверка
bin/magento cache:cleanВойдите в панель заново и откройте «Каталог → Отзывы Hello»: появится страница с заголовком «Отзывы» и текстом из шаблона. В следующем уроке текст заменит таблица.
Право для настроек
Теперь можно защитить и раздел настроек из прошлого урока: добавьте в acl.xml право Acme_Hello::config и укажите его в теге resource файла system.xml.
Частая ошибка
Адрес страницы вводят в браузере вручную и получают перенаправление на главную страницу панели. Адреса панели защищены секретным ключом — он добавляется в конец адреса, и без него запрос отклоняется. На свои страницы переходите через меню или стройте ссылки методом getUrl().