Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Контроллер, представление и макет

Страницу компонента выводят три файла. Контроллер принимает запрос и выбирает представление. Представление (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 — строчными.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.