Создание панели инструментов
В 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. Теперь вы можете добавлять, удалять и редактировать сообщения.
В следующей части мы добавим валидацию формы.