Контроллер, представление и макет
Страницу компонента выводят три файла. Контроллер принимает запрос и выбирает представление. Представление (view) готовит данные. Макет превращает их в HTML. Сделаем первую страницу сайта — список записей блога.
Файлы
Создайте вручную три файла в части для сайта:
components/com_hello/
├── src/
│ ├── Controller/
│ │ └── DisplayController.php
│ └── View/
│ └── Posts/
│ └── HtmlView.php
└── tmpl/
└── posts/
└── default.phpКонтроллер
// components/com_hello/src/Controller/DisplayController.php
namespace My\Component\Hello\Site\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
class DisplayController extends BaseController
{
protected $default_view = 'posts';
}DisplayController — контроллер, который Joomla вызывает, когда в запросе не указано другое действие. Его метод display() уже написан в родительском классе: он читает параметр view из адреса и выводит представление с таким именем. Если параметра нет, берётся $default_view.
Представление
// components/com_hello/src/View/Posts/HtmlView.php
namespace My\Component\Hello\Site\View\Posts;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
class HtmlView extends BaseHtmlView
{
public array $posts = [];
public function display($tpl = null): void
{
$this->posts = ['Первая запись', 'Вторая запись'];
parent::display($tpl);
}
}Представление кладёт данные в свои свойства и вызывает parent::display() — тот подключает макет. Пока записи заданы прямо в коде; в следующем уроке их даст модель.
Макет
<?php
// components/com_hello/tmpl/posts/default.php
defined('_JEXEC') or die;
?>
<h1>Блог</h1>
<ul>
<?php foreach ($this->posts as $title) : ?>
<li><?php echo $this->escape($title); ?></li>
<?php endforeach; ?>
</ul>В макете компонента $this — объект представления: его свойства доступны как $this->posts. Метод escape() экранирует вывод.
Результат
Откройте на сайте адрес:
http://joomla.test/index.php?option=com_hello&view=postsВнутри шаблона сайта появился заголовок «Блог» и список из двух записей. Адрес без view — index.php?option=com_hello — покажет ту же страницу благодаря $default_view.
Как адрес связан с файлами
| В адресе | Что ищет Joomla |
|---|---|
option=com_hello | Компонент и его провайдер |
view=posts | Класс View\Posts\HtmlView |
layout=default (по умолчанию) | Макет tmpl/posts/default.php |
format=html (по умолчанию) | Класс HtmlView; для format=json — JsonView |
task=post.save | Метод save() класса Controller\PostController |
Чтобы добавить вторую страницу, создают ещё одну папку в View и ещё одну — в tmpl. Новый контроллер для этого не нужен.
Действия контроллера
Параметр task вызывает метод контроллера. Так оформляют всё, что меняет данные: сохранение, удаление, публикацию. Запись task=post.save означает «контроллер PostController, метод save». После работы такой метод не выводит страницу, а перенаправляет на неё вызовом $this->setRedirect(). Готовые контроллеры с действиями появятся в уроке о сохранении данных.
Панель управления
Административная часть устроена точно так же, меняются только пути и слово в пространстве имён:
| Файл на сайте | Файл в панели |
|---|---|
components/com_hello/src/... | administrator/components/com_hello/src/... |
My\Component\Hello\Site\... | My\Component\Hello\Administrator\... |
Частая ошибка
Имена классов и папок связаны жёстко: представление posts — это папка View/Posts и макет tmpl/posts/default.php. При несовпадении Joomla сообщает «View not found». На Windows регистр букв в именах папок не важен, а на сервере с Linux View/posts и View/Posts — разные папки: в src пишите с заглавной буквы, в tmpl — строчными.