Часть 07 - панель управления
Создание панели инструментов
В Joomla администратор сайта обычно управляет компонентами с помощью панели инструментов и различных действий, которые связаны с этой панелью. Давайте создадим заголовок с иконкой и панель инструментов для нашего компонента. Для этого необходимо отредактировать файл 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'); // Устанавливаем панель инструментов. $this->addToolBar(); // Отображаем представление. parent::display($tpl); } catch (Exception $e) { throw new Exception($e->getMessage()); } } /** * Устанавливает панель инструментов. * * @return void */ protected function addToolBar() { JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS'), 'helloworld'); JToolBarHelper::addNew('helloworld.add'); JToolBarHelper::editList('helloworld.edit'); JToolBarHelper::divider(); JToolBarHelper::deleteList('', 'helloworlds.delete'); } }
В методе addToolBar()
мы используем класс JToolBarHelper
для добавления элементов в панель инструментов. Этот класс доступен из любой точки администраторской части, так как он подключается непосредственно в файле administrator/index.php:
require_once JPATH_BASE.'/includes/toolbar.php';
Функции JToolBarHelper::title
мы передаем второй параметр helloworld
. Это добавит к заголовку компонента css-класс helloworld
, что позволит нам далее настроить иконку заголовка. Также мы добавили кнопки добавления, редактирования записи и удаления списка записей. Вы можете найти другие классические функции по управлению в файле administrator/includes/toolbar.php.
JToolBarHelper::divider();
просто выводит символ разделителя и помогает визуально отделить различные группы кнопок.
Так как представление теперь может выполнять некоторые действия, мы должны добавить входные данные в файл 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> <thead><?php echo $this->loadTemplate('head');?></thead> <tbody><?php echo $this->loadTemplate('body');?></tbody> <tfoot><?php echo $this->loadTemplate('foot');?></tfoot> </table> <div> <input type="hidden" name="task" value="" /> <input type="hidden" name="boxchecked" value="0" /> <?php echo JHtml::_('form.token'); ?> </div> </form>
Теперь через скрытое поле task
мы передаем задачу, которая подставляется исходя из того, какую кнопку в панели инструментов мы нажали. Скрытое поле boxchecked
позволяет Joomla определить, выбрана ли хоть одна запись или нет.
Добавляем контроллеры
Для управления в панель инструментов было добавлено три кнопки, которые связаны с соответствующими действиями:
- helloworlds.delete
- helloworld.edit
- helloworld.add
Это так называемые составные задачи (controller.task). Поэтому необходимо добавить ещё два контроллера: HelloWorldControllerHelloWorlds
и HelloWorldControllerHelloWorld
. Подробнее о субконтроллерах можно почитать здесь:
http://docs.joomla.org/JController_and_its_subclass_usage_overview
Создайте файл admin/controllers/helloworlds.php со следующим кодом:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку controlleradmin Joomla. jimport('joomla.application.component.controlleradmin'); /** * HelloWorlds контроллер. */ class HelloWorldControllerHelloWorlds extends JControllerAdmin { /** * Прокси метод для getModel. * * @param string $name Имя класса модели. * @param string $prefix Префикс класса модели. * * @return object Объект модели. */ public function getModel($name = 'HelloWorld', $prefix = 'HelloWorldModel') { return parent::getModel($name, $prefix, array('ignore_request' => true)); } }
Мы переопределили метод getModel
для того, чтобы родительский класс JControllerAdmin мог получить доступ к классу нашей модели HelloWorldModelHelloWorld
и корректно выполнять удаление записей с помощью метода delete.
Создайте файл admin/controllers/helloworld.php со следующим кодом:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку controllerform Joomla. jimport('joomla.application.component.controllerform'); /** * HelloWorld контроллер. */ class HelloWorldControllerHelloWorld extends JControllerForm { }
Этот класс пустой, потому что необходимые нам методы add и edit расположены в родительском классе JControllerForm.
Добавляем представление для редактирования
Создайте файл admin/views/helloworld/view.html.php со следующим кодом:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку представления Joomla. jimport('joomla.application.component.view'); /** * HTML представление редактирования сообщения. */ class HelloWorldViewHelloWorld extends JViewLegacy { /** * Сообщение. * * @var object */ protected $item; /** * Объект формы. * * @var array */ protected $form; /** * Отображает представление. * * @param string $tpl Имя файла шаблона. * * @return void * * @throws Exception */ public function display($tpl = null) { try { // Получаем данные из модели. $this->form = $this->get('Form'); $this->item = $this->get('Item'); // Устанавливаем панель инструментов. $this->addToolBar(); // Отображаем представление. parent::display($tpl); } catch (Exception $e) { throw new Exception($e->getMessage()); } } /** * Устанавливает панель инструментов. * * @return void */ protected function addToolBar() { JFactory::getApplication()->input->set('hidemainmenu', true); $isNew = ($this->item->id == 0); JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW') : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld'); JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY'); JToolBarHelper::save('helloworld.save'); JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE'); } }
В режиме добавления/редактирования записи мы убираем возможность пользоваться основным администраторским меню с помощью hidemainmenu
. Также в зависимости от режима (добавление или редактирование) мы изменяем текст заголовка и текст под кнопками в панели.
Это представление будет отображать данные с помощью шаблона admin/views/helloworld/tmpl/edit.php:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Загружаем тултипы. JHtml::_('behavior.tooltip'); ?> <form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="helloworld-form"> <fieldset> <legend><?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_DETAILS'); ?></legend> <ul> <?php foreach ($this->form->getFieldset() as $field) : ?> <li><?php echo $field->label; echo $field->input; ?></li> <?php endforeach; ?> </ul> </fieldset> <div> <input type="hidden" name="task" value="" /> <?php echo JHtml::_('form.token'); ?> </div> </form>
В шаблоне мы используем метод getFieldset() для получения доступа к полям формы (в виде массива объектов класса JFormField), которую мы получаем с помощью модели.
Добавляем модель
Представление HelloWorldViewHelloWorld
запрашиавает форму и данные из модели. Эта модель должна содержать методы getTable()
, getForm()
и loadData()
. Создайте файл admin/models/helloworld.php со следующим кодом:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку modeladmin Joomla. jimport('joomla.application.component.modeladmin'); /** * Модель HelloWorld. */ class HelloWorldModelHelloWorld extends JModelAdmin { /** * Возвращает ссылку на объект таблицы, всегда его создавая. * * @param string $type Тип таблицы для подключения. * @param string $prefix Префикс класса таблицы. Необязателен. * @param array $config Конфигурационный массив. Необязателен. * * @return JTable Объект JTable. */ public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Метод для получения формы. * * @param array $data Данные для формы. * @param boolean $loadData True, если форма загружает свои данные (по умолчанию), false если нет. * * @return mixed Объект JForm в случае успеха, в противном случае false. */ public function getForm($data = array(), $loadData = true) { // Получаем форму. $form = $this->loadForm( $this->option . '.helloworld', 'helloworld', array('control' => 'jform', 'load_data' => $loadData) ); if (empty($form)) { return false; } return $form; } /** * Метод для получения данных, которые должны быть загружены в форму. * * @return mixed Данные для формы. */ protected function loadFormData() { // Проверка сессии на наличие ранее введеных в форму данных. $data = JFactory::getApplication()->getUserState($this->option . '.edit.helloworld.data', array()); if (empty($data)) { $data = $this->getItem(); } return $data; } }
Эта модель наследуется от класса JModelAdmin и использует метод loadForm() для получения формы. Обратите внимание, что мы используем свойство $this->option
, значение которого равно com_helloworld
. Оно определяется автоматически в конструкторе родительского класса JModel. Таким образом мы не привязываемся к названию нашего компонента, и если вдруг нам захочется его изменить, то мы сможем это сделать не меняя наш код.
Итак, метод loadForm() ищет формы в папке форм, которые по умолчанию находятся в models/forms. Создайте файл формы admin/models/forms/helloworld.xml:
<?xml version="1.0" encoding="utf-8"?> <form> <fieldset> <field name="id" type="hidden" /> <field name="greeting" type="text" label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL" description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC" size="40" class="inputbox" default="" /> </fieldset> </form>
Названия полей формы совпадают с названиями полей в таблице базы данных. Таким образом наш класс таблицы HelloWorldTableHelloWorld
сможет сохранить значения полей формы в соответствующих полях таблицы базы данных. Обратите внимание на скрытое поле id:
<field name="id" type="hidden" />
Для новой записи значение не указывается, а для существующей - это id
записи из базы. На основании этого класс таблицы оперделяет, добавлять или обновлять данные в базе.
Изменяем точку входа
Для использования иконки 48x48px в заголовке, внесем изменения в файл точки входа admin/helloworld.php - с помощью метода addStyleDeclaration класса JDocument добавим для неё css-стиль:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Устанавливаем обработку ошибок в режим использования Exception. JError::$legacy = false; // Устанавливаем некоторые глобальные свойства. $document = JFactory::getDocument(); $document->addStyleDeclaration('.icon-48-helloworld {background-image: url(../media/com_helloworld/images/hello-48x48.png);}'); // Подключаем библиотеку контроллера Joomla. jimport('joomla.application.component.controller'); // Получаем экземпляр контроллера с префиксом HelloWorld. $controller = JControllerLegacy::getInstance('HelloWorld'); // Исполняем задачу task из Запроса. $input = JFactory::getApplication()->input; $controller->execute($input->getCmd('task', 'display')); // Перенаправляем, если перенаправление установлено в контроллере. $controller->redirect();
В итоге получится вот такой симпатичный заголовок:
Добавляем языковые константы
Откройте файл admin/language/en-GB/en-GB.com_helloworld.ini и замените код на следующий:
COM_HELLOWORLD_ADMINISTRATION="HelloWorld - Administration"
COM_HELLOWORLD_HELLOWORLD_CREATING="HelloWorld - Creating"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Details"
COM_HELLOWORLD_HELLOWORLD_EDITING="HelloWorld - Editing"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="This message will be displayed"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Message"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Greeting"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="ID"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="HelloWorld manager: Edit Message"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="HelloWorld manager: New Message"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="HelloWorld manager"
COM_HELLOWORLD_N_ITEMS_DELETED_1="One message deleted"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d messages deleted"
Откройте файл admin/language/ru-RU/ru-RU.com_helloworld.ini и замените код на следующий:
COM_HELLOWORLD_ADMINISTRATION="Hello World! - Администрирование"
COM_HELLOWORLD_HELLOWORLD_CREATING="Hello World! - Создание"
COM_HELLOWORLD_HELLOWORLD_DETAILS="Детали"
COM_HELLOWORLD_HELLOWORLD_EDITING="Hello World! - Редактирование"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC="Сообщение для отображения"
COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL="Сообщение"
COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING="Приветствие"
COM_HELLOWORLD_HELLOWORLD_HEADING_ID="ID"
COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT="Hello World!: Изменить сообщение"
COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW="Hello World!: Добавить сообщение"
COM_HELLOWORLD_MANAGER_HELLOWORLDS="Управление Hello World!"
COM_HELLOWORLD_N_ITEMS_DELETED_1="Одно сообщение удалено"
COM_HELLOWORLD_N_ITEMS_DELETED_2="%d сообщения удалено"
COM_HELLOWORLD_N_ITEMS_DELETED_MORE="%d сообщений удалено"
Собираем пакет установки компонента
Создайте две png-иконки для нашего компонента размером 16х16px и 48х48px пикселей, назовите их hello-16x16.png и hello-48x48.png и сохраните в папке media/images/.
Не забудьте поменять номер версии в файле helloworld.xml:
<version>0.0.7</version>
Добавляем поддержку контроллеров:
<folder>controllers</folder>
Добавляем поддержку медиа:
<media destination="com_helloworld" folder="media"> <filename>index.html</filename> <folder>images</folder> </media>
Добавляем поддержку икноки в пункте меню:
<menu img="../media/com_helloworld/images/hello-16x16.png">COM_HELLOWORLD_MENU</menu>
helloworld.xml
<?xml version="1.0" encoding="utf-8"?> <extension type="component" version="2.5.0" method="upgrade"> <name>COM_HELLOWORLD</name> <!-- Следующие элементы необязательны --> <creationDate>Июль 2012</creationDate> <author>Вася Пупкин</author> <authorEmail>Ваш e-mail</authorEmail> <authorUrl>Ваш сайт</authorUrl> <copyright>Информация о копирайте</copyright> <license>Информация о лицензии</license> <!-- Версия записывается в таблицу компонентов --> <version>0.0.7</version> <!-- Описание необязательно --> <description>COM_HELLOWORLD_DESCRIPTION</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>language</folder> <folder>models</folder> <folder>views</folder> </files> <media destination="com_helloworld" folder="media"> <filename>index.html</filename> <folder>images</folder> </media> <!-- Администрирование --> <administration> <!-- Раздел Меню --> <menu img="../media/com_helloworld/images/hello-16x16.png">COM_HELLOWORLD_MENU</menu> <!-- Раздел основных файлов администрирования --> <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. --> <files folder="admin"> <filename>index.html</filename> <filename>controller.php</filename> <filename>helloworld.php</filename> <folder>controllers</folder> <folder>models</folder> <folder>sql</folder> <folder>tables</folder> <folder>views</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.sys.ini</language> </languages> </administration> </extension>
Содержимое директории с кодом:
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
site/language/ru-RU/index.html
site/language/ru-RU/ru-RU.com_helloworld.ini
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/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
admin/language/index.html
admin/language/en-GB/index.html
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/language/ru-RU/index.html
admin/language/ru-RU/ru-RU.com_helloworld.ini
admin/language/ru-RU/ru-RU.com_helloworld.sys.ini
admin/models/index.html
admin/models/helloworld.php
admin/models/helloworlds.php
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.xml
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/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
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
language/index.html
language/en-GB/index.html
language/en-GB/en-GB.com_helloworld.sys.ini
language/ru-RU/index.html
language/ru-RU/ru-RU.com_helloworld.sys.ini
media/index.html
media/images/index.html
media/images/hello-16x16.png
media/images/hello-48x48.png
Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую c GitHub. Далее установите его, используя менеджер расширений Joomla. Теперь вы можете добавлять, удалять и редактировать сообщения.
В следующей части мы добавим валидацию формы.
Код для этой части
Скачать com_helloworld часть 7
Актуальный код части 7 на GitHub