Joomla 1.5: Создание плагинов группы Content
Индекс материала |
---|
Joomla 1.5: Создание плагинов группы Content |
PHP - файл плагина |
INI - файл плагина |
Все страницы |
У плагинов группы Content Plugin очень много вариантов применения. Группа Content Plugin имеет прямое отношение к отображению вашего содержимого. Для создания самого плагина нужно как минимум два файла: XML файл манифеста и собственно файл PHP.
Поскольку каждый плагин в Joomla реагирует на какое – то своё событие, то очевидна кое - какая разница в их реализации. В данной заметке я приведу пример реализации плагинов группы content. Плагин для одного из событий разберём более подробно - это реально существующий плагин loadmodule. Так же в конце я расскажу, как добавить мульти язычность вашим плагинам.
XML - файл манифест плагина
XML файл - манифест называют так же, как и файл PHP и собственно так же, как и называется ваш плагин. Файл - манифест так же является одним из необходимых файлов, он всегда начинается с XML-тэга определения, и использует кодировку UTF-8.
<?xml version="1.0" encoding="utf-8"?> <!-- Для определения группы плагина добавьте следующее: --> <install version="1.5" type="plugin" group="content">
- version - определяет, что расширение для версии 1.5
- type - определяет, что тип расширения - плагин
- group - определяет, что плагин относится к группе content
Как и требуют правила XML - элемент install является корневым, единственным, а так же в нём присутствуют атрибуты:
Далее можно добавить информацию о себе и непосредственно о плагине:
<name>Имя вашего плагина</name> <creationDate>Дата создания</creationDate> <author>Ваше имя</author> <authorEmail>Ваш e-mail адрес</authorEmail> <authorUrl>Ваш вэб сайт</authorUrl> <copyright>Авторские права</copyright> <license>Тип лицензии, например GNU/GPL</license> <version>Версия плагина</version> <description>Описание плагина; показывается при установке в настройках плагина в менеджере плагинов</description>
Далее поместите название своего PHP - файла, который будет содержать код плагина, в xml-элемент <filename>, который в свою очередь должн быть вложен внутрь xml-элемента <files>. Имя PHP - файла должно быть таким же, как имя XML - файла - манифеста. Так же поместите это имя в атрибут plugin = " " xml-элемента <filename>, как показано ниже:
<files> <filename plugin="nameofplugin">nameofplugin.php</filename> </files>
Можно добавлять сколь угодно файлов для своего плагина. Нужно лишь добавить новый xml-элемент <filename> содержащий имя файла, и поместить его внутрь xml-элемента <files> пример ниже:
<files> <filename plugin="nameofplugin">nameofplugin.php</filename> <filename>somefile1.php</filename> <filename>somefile2.php</filename> </files>
Если вы любите порядок и у вас плагин имеет целую кучу файлов, то вы конечно захотите сгруппировать свои многочисленные файлы по каталогам. В таком случае можно поступить следующим образом: вместо имени файла в xml-элементе <filename> указывайте путь от директории плагина к файлу ( включая имя файла естественно):
<files> <filename plugin="nameofplugin">nameofplugin.php</filename> <filename>scripts/somescript.js</filename> <filename>css/somecss.css</filename> <filename>somefile1.php</filename> <filename>somefile2.php</filename> </files>
А можно просто перечислить директории, которые у вас имеются в директории плагина следующим образом:
<files> <filename plugin="nameofplugin">nameofplugin.php</filename> <filename>somefile1.php</filename> <filename>somefile2.php</filename> <folder>scripts</folder> <folder>css</folder> </files>
В этом случае вам даже не придётся перечислять файлы которые они содержат.
Что касается мульти язычности, то для её обеспечения в Joomla используются INI - файлы. Это конечно не обязательно, но если вы делаете плагин с учётом мульти язычности, то люди из других стран смогут легко перевести Ваш плагин на свой собственный язык.
Дополнительные языковые файлы всегда устанавливаются в:
administrator/languages/xx-XX/
Где xx-XX – код языка, уже установленного в Joomla. Языковые коды можно найти (используется ISO 639-1), и
Например так добавляется поддержка английского языка для плагина: nameofplugin группы content:
<languages> <language tag="en-GB">en-GB.plg_content_nameofplugin.ini</language> </languages>
Ещё, конечно не обязательно, но вы можете добавить какие то параметры для настройки плагина:
<params> <param name="paramname" type="typeofparameter" default="defaultsetting" label="title" description="description"/> </params>
- name: имя параметра. Это вы будете отлавливать далее в PHP коде.
- type: это можно выбрать между несколькими типами параметров. Существующие типы параметров можно посмотреть но при желании можно создать и свои.
- default: установка значения по умолчанию для этого параметра.
- label: html – лейбл параметра, который отображается в настройках плагина.
- description: текст, который появляется как всплывающая подсказка для этого параметра.
Атрибуты xml-элемента <param/>
Если у вашего плагина нет параметров, то добавьте просто пустой xml-элемент:
<params />
И не забывайте заканчивать свой XML файл следующим xml-элементом:
</install>
PHP - файл плагина
Теперь создайте php - файл, и поместите следующий код в самом его начале:
// запрет прямого доступа defined( '_JEXEC' ) or die( 'Restricted access' );
Это предотвращает прямое обращение к этому файлу. Всегда начинайте свой php – код для Joomla 1.5 с этих строк. После этого нужно импортировать файл, содержащий описание класса JPlugin из библиотеки Joomla 1.5
jimport( 'joomla.plugin.plugin' );
Фактически параметр функции jimport – это путь к файлу требуемого класса, от директории libraries/, но вместо разделителя директорий – слеша «/» используется точка ( Так наверно красивее, и круче, и конечно медленнее ).
Далее объявляем класс с именем plg|Группа|Имяплагина - он обязательно должен расширять класс JPlugin.
Здесь, символами «|» я разделил имя класса на составные синтаксические элементы: обязательная приставка plg, далее с большой буквы имя группы плагина, в нашем случае Content, и после уже название плагина. Именно в таком виде синтаксический анализатор Joomla 1.5 ждёт от вас имена классов плагинов.Cимвол «|» - в реальном имени не нужен!
class plgContentNameofplugin extends JPlugin { ...
Обратите внимание на использование заглавных букв в стиле camelCase - это обязательно!
Строим наш плагин дальше…
Ниже заморочка с конструктором - всего лишь попытка сохранить обратную совместимость с PHP 4 - версии, в которой имя конструктора совпадало с названием класса.
function plgContentNameofplugin( &$subject, $params ) { parent::__construct( $subject, $params ); }
Для плагинов группы Content существует несколько событий, на которые они реагируют. Вы можете выбрать из следующего списка:
onBeforeContentSave: Это – событие происходит перед тем, как контент будет сохранен в базу данных.
onAfterContentSave: Это - событие, происходит после того, как контент сохранен в базу данных.
onPrepareContent: Это – начало подготовки контента для отображения. Больше всего подходит для обработки плагинами контента.
onAfterDisplayTitle: Плагины этого события могут разместить какую то информацию между заголовком и телом содержимого.
onBeforeDisplayContent: Плагины этого события могут разместить информацию, которая должна быть помещена непосредственно перед выводимым контентом.
onAfterDisplayContent: Плагины этого события могут разместить информацию, которая должна быть помещена непосредственно после выводимого контента
Более подробнее о событиях и типах плагинов, можно прочитать
Примеры заготовок кода плагинов группы content для разных событий:
onAfterContentSave
function onAfterContentSave( &$article, $isNew ) { global $mainframe; // код плагина здесь ... return true; }
Параметры :
- $article : ссылка на объект JTableContent, который хранит данные статьи и которому предстоит сохраниться в БД.
- $isNew : bool - true, если контент новый.
onAfterContentSave
function onAfterContentSave( &$article, $isNew ) { global $mainframe; // код плагина здесь ... return true; }
Параметры :
- $article : ссылка на объект JTableContent, который был сохранен в БД, который хранит данные статьи.
- $isNew : bool - true, если контент новый.
onPrepareContent
function onPrepareContent( &$article, &$params, $limitstart ) { global $mainframe; // код плагина здесь ... // не возвращает ничего. }
Параметры :
- $article: ссылка на статью, которая должна быть отображена.
- $params: ссылка на ассоциативный массив соответствующих параметров статьи *
- $limitstart: целое число – номер страницы в механизме pagination
Для следующих событий различным будет только имя метода, а внешние интерфейсы этих методов одинаковы, поэтому я сгруппирую их в одну запись:
onAfterDisplayTitle, onBeforeDisplayContent, onAfterDisplayContent
function onAfterDisplayTitle( &$article, &$params, $limitstart ) { global $mainframe; // Код плагина здесь ... // Возвращается строковое значение для этого события будет отображено в placeholder. // Как правило шаблоны отображают placeholder после разделителя статей. return ''; }
Параметры :
- $article: ссылка на статью, которая должна быть отображена.
- $params: ссылка на ассоциативный массив соответствующих параметров статьи *
- $limitstart: целое число – номер страницы в механизме pagination
* Массив параметров статьи это те параметры, которые мы задаём в настройках материала/статьи, например показывать ли дату создания, иконку печать и т.п. вот несколько переменных из той оперы:
show_title=1 link_titles=0 show_intro=1 show_section=1 link_section=0 show_category=0 link_category=0 show_author=0 show_create_date=0 ...
Ниже приведён пример кода для плагина loadmodule - группы Content. Он отображает модули в теле статьи, там где находит маркеры следующего вида: – соответственно плагин знает из какой позиции подгружать модули в то, или иное место.
Ещё раз повторю плагин loadmodule - реально существующий плагин, если вы соберётесь повторить этот пример проверьте, что плагин loadmodule - уже не установлен в вашей системе, иначе вы попросту не сможете его установить.
<?php // Запрет прямого доступа defined( '_JEXEC' ) or die( 'Restricted access' ); // Импортируем необходимый класс JPlugin jimport('joomla.plugin.plugin'); // Описываем класс, расширяющий JPlugin class plgContentLoadmodule extends JPlugin { /** * Плагин загружает модули позиций, указанных в контенте таким маркером: * */ public function onPrepareContent( &$row, &$params, $page=0 ) { // Получаем объект для работы с БД: $db = JFactory::getDBO(); // Простая и быстрая проверка, нужен ли вообще в данной статье наш плагин. // Если в статье вообще не присутствует слово 'loadposition' – вырубаем плагин if ( JString::strpos( $row->text, 'loadposition' ) === false ) { return true; } // Шаблон регулярки: $regex = '//i'; // Проверка, включён ли наш плагин: if ( !$this->params->get( 'enabled', 1 ) ) { $row->text = preg_replace( $regex, '', $row->text ); return true; } // Ищем все вхождения нашего шаблона, и помещаем его в массив $matches preg_match_all( $regex, $row->text, $matches ); // Кол-во вхождений $count = count( $matches[0] ); // Плагин сработает, только если есть совпадения с шаблоном регулярки: if ( $count ) { // Получаем параметры плагина $style = $this->params->def( 'style', -2 ); // Удаляем ненужные уже плейсхолдеры – описание функции см. ниже $this->_process( $row, $matches, $count, $regex, $style ); } // Не возвращаем никакого значения } // Служебная закрытая функция, которая удаляет плейсхолдеры { loadposition ... } protected function _process( &$row, &$matches, $count, $regex, $style ) { for ( $i=0; $i < $count; $i++ ) { $load = str_replace( 'loadposition', '', $matches[0][$i] ); $load = str_replace( '{', '', $load ); $load = str_replace( '}', '', $load ); $load = trim( $load ); // Подгружаем модули, указанной позиции и стиля см. описание ниже: $modules = $this->_load( $load, $style ); // Заменяем вхождение шаблона на вывод модуля: $row->text = preg_replace( '{'. $matches[0][$i] .'}', $modules, $row->text ); } // удаляет плейсхолдеры $row->text = preg_replace( $regex, '', $row->text ); } // Служебная закрытая функция – подгружает модули нужной позиции и стиля: protected function _load( $position, $style=-2 ) { // Получаем ссылку на объект документ: $document = &JFactory::getDocument(); // Получаем визуализатор модулей: $renderer = $document->loadRenderer('module'); // Устанавливаем значение параметров для модуля: $params = array('style'=>$style); $contents = ''; // Собираем вывод модулей в переменную, которую затем вернём foreach ( JModuleHelper::getModules($position) as $mod ) { $contents .= $renderer->render($mod, $params); } return $contents; } }
INI - файл (ы) плагина
Для мульти язычной поддержки принято использовать INI - файлы. Перевод будет работать в следующих местах:
- Тэги XML файла – манифеста, например: <description></description>
- XML атрибуты label и description из тегов <param /> файла – манифеста
- JText:: _ (здесь);
Языковых файла, если вы взялись за это конечно, возможно придётся создать два ( для одного языка ) : один для админки и один для сайта. Назвать их нужно соответственно пути расположения вашего плагина. Например, если бы мы создавали плагин контента, названный ' example', и он установлен в plugins/content/example, то тогда файлы нужно назвать так:
- en-US.plg_content_example.ini (Frontend)
- en-US.plg_content_example.sys.ini (Site)
Ниже пример процесса построения мульти язычной поддержки:
<param name="mode" type="list" default="1" label="PLG_CONTENT_EXAMPLE_MODE" description="PLG_CONTENT_EXAMPLE_EMAILS_DISPLAYED"> <option value="0">PLG_CONTENT_EXAMPLE_NONLINKABLE_TEXT</option> <option value="1">PLG_CONTENT_EXAMPLE_LINKABLE_TEXT</option> </param>
Локализованные строки переведены в ini файле:
PLG_CONTENT_EXAMPLE_MODE=Mode PLG_CONTENT_EXAMPLE_EMAILS_DISPLAYED=Select how the e-mails will be displayed PLG_CONTENT_EXAMPLE_NONLINKABLE_TEXT=Nonlinkable text PLG_CONTENT_EXAMPLE_LINKABLE_TEXT=As linkable mailto address
Как показывает опыт, что бы избежать проблем, для строк - перевода используйте верхний регистр, не используйте пробелы, и предваряйте их имена префиксами как имя расширения - чтобы избежать пресечения имён.
Итак, для мульти язычности, требуются, собственно сами файлы перевода. Далее их нужно прописать в xml – файле – манифесте. В INI - файле – переводе, то, что слева от знака = - это, что - то вроде констант, и они будут одинаковыми для всех файлов переводов, а меняться в зависимости от языка, будет то, что стоит справа. Например, голландская версия выглядела бы так:
PLG_CONTENT_EXAMPLE_MODE=Modus PLG_CONTENT_EXAMPLE_EMAILS_DISPLAYED=Selecteer hoe de e-mails worden weergegeven PLG_CONTENT_EXAMPLE_NONLINKABLE_TEXT=Niet-linkbare tekst PLG_CONTENT_EXAMPLE_LINKABLE_TEXT=Als een linkbaar mailto adres
Что бы перевод начал работать вы должны в php файле плагина загрузить языковой файл:
$lang = JFactory::getLanguage(); $lang->load('plg_content_simpleattachment', JPATH_ADMINISTRATOR); echo $JText::_('PLG_CONTENT_EXAMPLE_LINKNAME');
Ну вот, пока всё. Оригинал статьи