В прошлых частях мы рассмотрели, как работают плагины в Joomla и какие типы плагинов используются, а также рассмотрели несколько примеров плагинов. Теперь настало время попрактиковаться и создать свой собственный плагин.
Мы напишем простенький плагин, который будет использовать событие "onBeforeCompileHead". Это событие типа "system", которое появилось в версии Joomla 1.6, и позволяет нам изменять HTML-элемент head
непосредственно перед его рендерингом. Таким образом, мы можем изменить любой HTML-элемент, который находится в head
: meta, link или script.
Что будет делать наш плагин?
Событие "onBeforeCompileHead" вызывается в методе fetchHead() класса JDocumentRendererHtml
. Этот метод читает информацию для HTML-элемента head
из объекта документа и выводит её в буфер в HTML формате. Следующий код вызывает это событие:
// Trigger the onBeforeCompileHead event
$app = JFactory::getApplication();
$app->triggerEvent('onBeforeCompileHead');
Если мы посмотрим в исходный код HTML-страницы, то увидим неколько элементов meta
внутри элемента head
:
<meta name="robots" content="index, follow" />
<meta name="keywords" content="My keywords." />
<meta name="rights" content="My rights." />
<meta name="language" content="en-GB" />
Наш плагин будет добавлять мета-тег "revised", основываясь на параметре, который пользователь введет для плагина. Например, вывод нашего плагина может выглядеть следующим образом:
<meta name="revised" content="Dmitry Rekun, 16 октября 2012" />
где атрибут "content" - это текст, который указан в параметре плагина.
Чтобы этого достичь, нам необходимо понять, каким образом объект JDocumentHTML
сохраняет данные для HTML-элемента head
. Давайте проведем небольшое расследование.
В методе fetchHead()
класса JDocumentRendererHead
(где вызывается событие "onBeforeCompileHead"), мы видим, что переменная $document
находится в сигнатуре метода. Это объект JDocumentHTML
, у которого есть метод getHeadData(), который возвращает head-данные для документа или страницы. Если мы добавим команду var_dump($document->getHeadData());
в метод fetchHead()
(например, непосредственно перед кодом, который вызывает событие), а потом посмотрим на страницу, то увидим длинный дамп вывода getHeadData()
. Частью этого дампа будет следующее:
array
'title' => string 'Home' (length=4)
'description' => string 'My description.' (length=15)
'link' => string '' (length=0)
'metaTags' =>
array
'http-equiv' =>
array
'content-type' => string 'text/html' (length=9)
'standard' =>
array
'robots' => string 'index, follow' (length=13)
'keywords' => string 'My keywords.' (length=12)
'rights' => string 'My rights.' (length=10)
'language' => string 'en-GB' (length=5)
Если мы сравним это с HTML кодом, который был показан ранее, мы увидим, что элементы meta
с атрибутами "name" хранятся в объекте в качестве ассоциативного массива внутри элемента "standard", который находится внутри элемента "metaTags". Значение атрибута "name" является ключом (например, "robots"), а значение атрибута "content" является значением (например, "index, follow").
Мы хотим, чтобы наш плагин добавлял новый мета-тег "revised" и его значением должен быть текст, который введет пользователь в форме "Менеджера плагинов". Мы хотим сохранить существующие мета-теги и добавить только новый.
Итак, алгоритм работы нашего плагина кода будет следующим:
- Прочитать существующие head-данные из документа. Это будет массив, который упоминался выше.
- Добавить элемент к ассоциативному массиву, который хранится в элементе "standard" внутри элемента "metaTags". Ключом для этого элемента будет "revised", а значением будут данные, которые пользователь ввел для параметра.
- Записать измененный массив в объект документа, используя метод setHeaderData() (по сути, он является зеркальным отражением метода
getHeaderData()
). - Мы хотим это сделать только тогда, когда есть какие-то данные в параметре плагина. Если данных нет, то ничего не делаем.
Создаем установочный файл (файл манифеста)
Давайте не будем усложнять и назовем наш плагин просто - My Meta.
Создайте для него новую папку (например mymeta), а внутри неё создайте пустой файл index.html и файл mymeta.xml со следующим содержимым:
<?xml version="1.0" encoding="utf-8"?>
<extension version="2.5" type="plugin" group="system" method="upgrade">
<name>PLG_SYSTEM_MYMETA</name>
<author>Ваше имя</author>
<creationDate>Дата создания</creationDate>
<copyright>Информация о копирайте</copyright>
<license>Информация о лицензии</license>
<authorEmail>Ваш адрес электронной почты</authorEmail>
<authorUrl>Ваш сайт</authorUrl>
<version>1.0.0</version>
<description>PLG_SYSTEM_MYMETA_XML_DESCRIPTION</description>
<files>
<filename plugin="mymeta">mymeta.php</filename>
<filename>index.html</filename>
<folder>language</folder>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field name="revised" type="text"
description="PLG_SYSTEM_MYMETA_FIELD_REVISED_DESC"
label="PLG_SYSTEM_MYMETA_FIELD_REVISED_LABEL"
filter="string"
default=""
size="50"
/>
</fieldset>
</fields>
</config>
</extension>
Обратите внимание на строку:
<extension version="2.5" type="plugin" group="system" method="upgrade">
Атрибут "group" указывает на тип нашего плагина. Это значит, что после установки он будет размещен в директории plugins/system.
Также мы создали элемент fields
с атрибутом "name", значение которого равно "params". Внутри мы расположили элемент fieldset
"basic", который содержит необходимое нам поле. Все это находится внутри элемента config
.
Если бы мы не создали элемент fields
с атрибутом "name", то не имели бы возможности редактировать параметры плагина. Все дело в том, что для формы редактирования плагина используется файл разметки (administrator/components/com_plugins/views/plugin/tmpl/edit_options.php), который ищет элемент fields
с именем "params" и включает содержащиеся в нем элементы fieldset
в качестве опций формы.
Внутри элемента fieldset
мы определили текстовое поле "revised". Таким образом, пользователь сможет указать свое значение для этого параметра. С помощью filter="string"
мы вводим ограничение на допустимые символы в тексте. Фильтрация производится с помощью метода clean() класса JFilterInput
.
Файл манифеста готов. Настало время написать непосредственно код плагина.
Создаем код плагина
Создайте в папке mymeta файл mymeta.php со следующим содержимым:
<?php
// Запрет прямого доступа.
defined('_JEXEC') or die;
/**
* Тестовый MyMeta плагин.
*/
class plgSystemMyMeta extends JPlugin
{
function onBeforeCompileHead()
{
if ($this->params->get('revised'))
{
$document = JFactory::getDocument();
$headData = $document->getHeadData();
$headData['metaTags']['standard']['revised'] = $this->params->get('revised');
$document->setHeadData($headData);
}
}
}
Мы назвали наш класс plgSystemMyMeta
согласно имеющемуся соглашению по именованию плагинов:
"plg" + <тип плагина> + <имя файла плагина>
В классе мы создали метод с названием onBeforeCompileHead()
и его название в точности совпадает с названием события, на которое мы ориентируемся. Код метода довольно прост для понимания, так как мы уже разобрались со структурой массива метода getHeadData()
:
- Сначала мы проверяем, есть ли что-то в параметре "revised" нашего плагина. Если нет, то пропускаем обработку. К параметрам плагина мы обращаемся через свойство $params. Это объект типа
JRegistry
, в котором хранятся параметры плагина. - Если что-то есть, то обрабатываем. Мы получаем объект документа и сохраняем результаты метода
getHeadData()
в переменной$headData
. - Мы создаем новый элемент ассоциативного массива под именем "revised" и устанавливаем его значение равным значению параметра плагина. Обратите внимание, наш элемент включен в массив, который в свою очередь включен в ещё один массив. Это мы видели в дампе вывода
getHeadData()
.
Добавляем языковые файлы
Последним шагом перед проверкой нашего плагина будет добавление языковых файлов. Вспомните наш файл манифеста:
<files>
<filename plugin="mymeta">mymeta.php</filename>
<filename>index.html</filename>
<folder>language</folder>
</files>
Элемент folder
указывает на то, что в папке нашего плагина дожна быть подпапка "language".
Когда мы создаем плагин, мы можем выбрать: расположить языковые файлы в папке плагина или в папке adminstrator/languages. Для расширений рекомендуется располагать все файлы расширения отдельно от базовых файлов Joomla, поэтому языковые файлы расширения также предпочтительно располагать в папке расширения. Будем придерживаться этой практики и создадим папку language внутри папки mymeta. Внутри папки language создадим ещё две подпапки для каждого из языков: en-GB и ru-RU. Не забудьте разместить в них пустой файл index.html.
В нашем примере у нас будет четыре языковых файла, по два для каждого из языков:
en-GB.plg_system_mymeta.ini
en-GB.plg_system_mymeta.sys.ini
Будут располагаться в mymeta/language/en-GB.
ru-RU.plg_system_mymeta.ini
ru-RU.plg_system_mymeta.sys.ini
Будут располагаться в mymeta/language/ru-RU.
После установки плагина они будут располагаться в plugins/system/mymeta/language/en-GB/ и plugins/system/mymeta/language/ru-RU/ соответственно.
Обратите внимание на то, что наименование языковых файлов тоже придерживается соглашения именования плагинов.
Файл plg_system_mymeta.ini является главным языковым файлом и содержит языковые строки, которые будут использоваться во время выполнения кода плагина, а также тогда, когда плагин будет открыт для изменения в Менеджере плагинов.
Содержимое файла en-GB.plg_system_mymeta.ini:
PLG_SYSTEM_MYMETA_FIELD_REVISED_LABEL="Revised сontent"
PLG_SYSTEM_MYMETA_FIELD_REVISED_DESC="Meta revised text for content attribute."
Содержимое файла ru-RU.plg_system_mymeta.ini:
PLG_SYSTEM_MYMETA_FIELD_REVISED_LABEL="Содержимое revised"
PLG_SYSTEM_MYMETA_FIELD_REVISED_DESC="Текст для атрибута content meta-элемента revised."
Файл с .sys в названии используется для перевода имени, когда его просматривают в списке Менеджера расширений или в списке Менеджера плагинов. Также мы размещаем описание нашего плагина в этом файле для того, чтобы перевести описание в сообщении, которое отображается при установке плагина.
Содержимое файла en-GB.plg_system_mymeta.sys.ini:
PLG_SYSTEM_MYMETA="System - My Meta"
PLG_SYSTEM_MYMETA_XML_DESCRIPTION="Adds meta element with the name revised."
Содержимое файла ru-RU.plg_system_mymeta.sys.ini:
PLG_SYSTEM_MYMETA="Система - My Meta"
PLG_SYSTEM_MYMETA_XML_DESCRIPTION="Добавляет meta-элемент c именем revised."
Подробнее об использовании языковых файлах в расширениях вы можете прочитать в статье "Создание компонента для Joomla 2.5 - языковые файлы".
Все - теперь наш плагин полностью готов. Давайте протестируем его работу.
Тестируем плагин
Запакуйте содержимое папки mymeta в архив (zip, tar, tar.gz, bz2) или скачайте его напрямую с нашего сайта и установите, используя Менеджер расширений.
Зайдите в "Расширения – Менеджер плагинов" и в фильтре "- выбор типа -" выберите "system". В списке вы должны увидеть наш плагин "Систем – My Meta". Кликните на него, и вы попадете в редактирование параметров плагина:
Измените состояние плагина на "Включено", введите текст для содержимого "revised" и сохраните. Теперь пройдите на главную страницу и просмотрите исходный код с помощью браузера. Вы увидите что-то похожее на это:
<meta name="robots" content="index, follow" />
<meta name="keywords" content="My keywords." />
<meta name="rights" content="My rights." />
<meta name="language" content="en-GB" />
<meta name="revised" content="Dmitry Rekun, 16 октября 2012 года" />
<meta name="description" content="My description." />
Мы видим, что мета-тег "revised" присутствует в списке мета-тегов. В качестве финального теста, вернитесь в "Менеджер плагинов" и сотрите содержимое параметра "revised". Теперь сделайте рефреш страницы и проверьте исходный код. Мета-тег с именем "revised" должен был пропасть, так как мы стерли его содержимое в параметрах плагина.
Поздравляю! Вы успешно справились с созданием собственного плагина для Joomla. В следующей части мы рассмотрим, каким образом можно переопределить базовые классы Joomla с помощью плагина.
{phocadownload view=file|id=151|target=s}