Создание компонента для Joomla

Часть 5 - интерфейс администратора

Joomla

Часть 5 - интерфейс администратора

Интерфейс администратора

Для интерфейса администратора потребуется создать практически такую же MVC структуру, как и для публичной части. Сначала изменим точку входа администраторской части нашего компонента admin/helloworld.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Устанавливаем обработку ошибок в режим использования Exception.
JError::$legacy = false;
 
// Подключаем библиотеку контроллера Joomla.
jimport('joomla.application.component.controller');
 
// Получаем экземпляр контроллера с префиксом HelloWorld.
$controller = JControllerLegacy::getInstance('HelloWorld');
 
// Исполняем задачу task из Запроса.
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd('task', 'display'));

// Перенаправляем, если перенаправление установлено в контроллере.
$controller->redirect();

Создаем общий контроллер

Теперь точка входа получает экземпляр класса контроллера с префиксом HelloWorld. Давайте создадим базовый контроллер admin/controller.php для административной части:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем библиотеку контроллера Joomla.
jimport('joomla.application.component.controller');
 
/**
 * Общий контроллер компонента Hello World.
 */
class HelloWorldController extends JControllerLegacy
{
    /**
     * Задача по отображению.
     *
     * @param   boolean  $cachable   Если true, то представление будет закешировано.
     * @param   array    $urlparams  Массив безопасных url-параметров и их валидных типов переменных.
     *
     * @return  void
     */
    public function display($cachable = false, $urlparams = array()) 
    {
        // Устанавливаем представление по умолчанию, если оно не было установлено.
        $input = JFactory::getApplication()->input;
        $input->set('view', $input->getCmd('view', 'HelloWorlds'));
 
        parent::display($cachable);
    }
}

По умолчанию этот контроллер будет отображать представление HelloWorlds, которое будет выводить список сообщений.

Создаем представление

Создаем представление для списка сообщений admin/views/helloworlds/view.html.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;

 
// Подключаем библиотеку представления Joomla.
jimport('joomla.application.component.view');
 
/**
 * HTML представление списка сообщений компонента HelloWorld.
 */
class HelloWorldViewHelloWorlds extends JViewLegacy
{
    /**
     * Сообщения.
     *
     * @var  array 
     */
    protected $items;
 
    /**
     * Постраничная навигация.
     *
     * @var  object
     */
    protected $pagination;
 
    /**
     * Отображаем список сообщений.
     *
     * @param   string  $tpl  Имя файла шаблона.
     *
     * @return  void
     *
     * @throws  Exception
     */
    public function display($tpl = null)
    {
        try
        {
            // Получаем данные из модели.
            $this->items = $this->get('Items');
 
            // Получаем объект постраничной навигации.
            $this->pagination = $this->get('Pagination');
 
            // Отображаем представление.
            parent::display($tpl);
        }
        catch (Exception $e)
        {
            throw new Exception($e->getMessage());
        }
    }
}

Обратите внимание, что в случае ошибок при получении данных из модели, мы не логируем их (как это делалось для публичной части), а генерируем исключение. И опять же, тут выбор за вами: выводить на экран, логировать или генерировать исключения.

Настало время вывести данные, поэтому создаем шаблон admin/views/helloworlds/tmpl/default.php с кодом:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Загружаем тултипы.
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm" id="adminForm">
    <table class="adminlist">
        <thead><?php echo $this->loadTemplate('head');?></thead>
        <tbody><?php echo $this->loadTemplate('body');?></tbody>
        <tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
    </table>
</form>

Этот шаблон вызывает несколько суб-шаблонов (head, body и foot). Каждый суб-шаблон хранится в файле, префикс названия которого состоит из названия главного шаблона (в нашем случае default) и нижнего подчеркивания. То есть в нашем случае названия будут: default_head, default_body и default_foot.

Создаем файл admin/views/helloworlds/tmpl/default_head.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
?>
<tr>
    <th width="1%">
        <input type="checkbox" name="checkall-toggle" value="" title="<?php echo JText::_('JGLOBAL_CHECK_ALL'); ?>" onclick="Joomla.checkAll(this)" />
    </th>
    <th>
        <?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING'); ?>
    </th>
    <th width="1%">
        <?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_ID'); ?>
    </th>
</tr>

В этом файле мы выводим заголовки списка. checkAll - это javascript функция, которая позволяет выбрать все записи.

Создаем файл admin/views/helloworlds/tmpl/default_body.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
foreach ($this->items as $i => $item) : ?>
    <tr>
        <td>
            <?php echo JHtml::_('grid.id', $i, $item->id); ?>
        </td>
        <td>
            <?php echo $item->greeting; ?>
        </td>
        <td>
            <?php echo $item->id; ?>
        </td>
    </tr>
<?php endforeach; ?>

В этом файле мы выводим непосредственно список записей. Напомним, что JHtml::_ - это хелпер функция, которая позволяет отобразить различные HTML элементы. В нашем случае она отображает чекбокс для записей.

Создаем файл admin/views/helloworlds/tmpl/default_foot.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
?>
<tr>
    <td colspan="3"><?php echo $this->pagination->getListFooter(); ?></td>
</tr>

Здесь мы выводим постраничную навигацию.

Создаем модель

Представление HelloWorlds запрашивает данные у модели. В Joomla есть специальный класс, который управляет списком данных - JModelList. Наследуемые от JModelList классы по сути могут включать только:

  • метод getListQuery - конструирует SQL запрос
  • list.start - состояние модели для определения смещения списка
  • list.limit - состояние модели для определения длины списка

Методы getItems (для получения списка записей) и getPagination (для получения постраничной навигации) определены в классе JModelList, поэтому их необязательно определять в классе HelloWorldModelHelloWorlds. Создаем файл admin/models/helloworlds.php:

<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
 
// Подключаем библиотеку modellist Joomla.
jimport('joomla.application.component.modellist');
 
/**
 * Модель списка сообщений компонента HelloWorld.
 */
class HelloWorldModelHelloWorlds extends JModelList
{
    /**
     * Метод для построения SQL запроса для загрузки списка данных.
     *
     * @return  string  SQL запрос.
     */
    protected function getListQuery()
    {
        // Создаем новый query объект.
        $db = JFactory::getDbo();
        $query = $db->getQuery(true);
 
        // Выбераем поля.
        $query->select('id, greeting');
 
        // Из таблицы helloworld.
        $query->from('#__helloworld');
 
        return $query;
    }
}

Собираем пакет установки компонента

Не забудьте поменять номер версии в файле helloworld.xml:

<version>0.0.5</version>

И добавить поддержку контроллера и представления в разделе основных файлов администрирования:

<filename>controller.php</filename>
<folder>views</folder>

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="2.5.0" method="upgrade">
 
    <name>Hello World!</name>
    <!-- Следующие элементы необязательны -->
    <creationDate>Июль 2012</creationDate>
    <author>Вася Пупкин</author>
    <authorEmail>Ваш e-mail</authorEmail>
    <authorUrl>Ваш сайт</authorUrl>
    <copyright>Информация о копирайте</copyright>
    <license>Информация о лицензии</license>
    <!--  Версия записывается в таблицу компонентов -->
    <version>0.0.5</version>
    <!-- Описание необязательно -->
    <description>Описание компонента Hello World! ...</description>
 
    <!-- Запускается при установке -->
    <install>
        <sql>
            <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
        </sql>
    </install>
    <!-- Запускается при удалении -->
    <uninstall>
        <sql>
            <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
        </sql>
    </uninstall>
    <!-- Запускается при обновлении -->
    <update>
        <schemas>
            <schemapath type="mysql">sql/updates/mysql</schemapath>
        </schemas>
    </update>
 
    <!-- Раздел основных файлов сайта -->
    <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. 
    Поэтому указанные в этом разделе файлы будут скопированы из папки /site/ нашего пакета-установщика в соответствующую папку установки. -->
    <files folder="site">
        <filename>index.html</filename>
        <filename>controller.php</filename>
        <filename>helloworld.php</filename>
        <folder>models</folder>
        <folder>views</folder>
    </files>
 
    <!-- Администрирование -->
    <administration>
        <!-- Раздел Меню -->
        <menu>Hello World!</menu>
        <!-- Раздел основных файлов администрирования  -->
        <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. 
        Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. -->
        <files folder="admin">
            <filename>index.html</filename>
            <filename>controller.php</filename>
            <filename>helloworld.php</filename>
            <folder>models</folder>
            <folder>sql</folder>
            <folder>tables</folder>
            <folder>views</folder>
        </files>
    </administration>
 
</extension>

Содержимое директории с кодом:

helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/models/index.html
site/models/helloworld.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
admin/index.html
admin/controller.php
admin/helloworld.php
admin/models/index.html
admin/models/helloworlds.php
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.4.sql
admin/tables/index.html
admin/tables/helloworld.php
admin/views/index.html
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworlds/tmpl/default_head.php

Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую c GitHub. Далее установите его, используя менеджер расширений Joomla. Теперь зайдите в компонент "hello-world" через меню "Компоненты" - вы увидите список записей, который сосоит из двух колонок, двух рядов и чекбоксов.

Интерфейс администратора - список записей

В следущей части мы разберем добавление языковой поддержки.

Код для этой части

Скачать com_helloworld часть 5

Актуальный код части 5 на GitHub

Dmitry Rekun
Работаю в банковской сфере, а с веб-разработкой (непосредственно с Joomla) столкнулся в 2007 году. Теперь это моё хобби и время от времени вторая работа. Какое-то время вёл свой блог, но решил попробовать работать в команде. И вот c 2012 года я здесь :)