С проблемой создания расширений для Joomla 1.5 я столкнулся (и продолжаю сталкиваться) при переводе одного сайта с 1.0-версии на 1.5-ю и с удивлением обнаружил, что ветка 1.5 документирована из рук вон плохо. Более-менее нормально документирован сам API, который теперь называется Joomla Framework, но никаких вменяемых туториалов даже в официальном вики не наблюдается, поэтому мне пришлось использовать скудную информацию, почерпнутую из блогов в англоязычном Интернете, разбираться в коде Джумлы и в коде ее демо-примеров. Учитывая этот факт, а также факт практически полного отсутствия какой бы то ни было полезной информация по разработке на Джумле 1.5 в русскоязычном Интернете, я решился на эту скромную статью.

Здесь я опишу свой опыт создания простейшего плагина и доведения его до рабочего состояния, поэтому, если какие-то мои решения покажуться кому-то неправильными или неоптимальными, просьба дать знать, т.к. иначе добыть «правильную» информацию по этому вопросу исключительно трудно.



Постановка задачи



Требуется создать «родной» плагин, который позволял бы вставить в нужное месте статьи содержимое категории в виде списка ссылок на статьи этой категории. Очевидно, в терминологии Joomla — это контентный (content) плагин. Joomla 1.5 позволяет подключать расширения, написанные по-старому (как это принято в ветке 1.0) в режиме совместимости (legacy), для этого необходимо опубликовать системный плагин Legacy и включить Режим совместимости (Legacy Mode). Тем не менее было принято решение делать все «по-новому», т.е. в «родном» режиме. Плагин мы назовем ItemList. Для использования плагина необходимо в нужном месте содержимого статьи указать специальный тег в виде {itemlist: id_категории}.

Реализация



Для создания своего плагина необходимо создать класс, унаследованный от JPlugin и реализовать в нем требуемый функционал. Для успешного функционирования плагина в среде Joomla, в классе плагина должны быть реализованы некоторые методы с предопределенными именами – именно эти методы Joomla будет вызывать в процессе работы. Для контентных плагинов (согласно статье Andrew Eddie) таких методов предопределено 5 штук:
  • onPrepareContent
  • onAfterDisplayTitle
  • onBeforeDisplayContent
  • onBeforeContentSave
  • onAfterContentSave

Для создания нашего простейшего плагина нам понадобится только первый из методов, т.е. onPrepareContent, который имеет три параметра:
  • &$article – ссылка на объект статьи
  • &$params – ссылка на объект параметров статьи
  • $limitstart – номер страницы (я так понимаю, используется при «пагинации»)

В теле этого метода будет собственно реализован весь функционал нашего плагина, для чего необходимо:
  1. Найти в теле статьи тег, обозначающий плагин,
  2. Вычислить из н��го id категории, содержание которой необходимо вывести,
  3. Замена тега плагина на список ссылок на статьи категории.


Наш плагин состоит всего из двух файлов.

itemlist.php


<?php
    defined('_JEXEC') or die('Доступ запрещен.');
   
    jimport( 'joomla.plugin.plugin' );
   
    class plgContentItemList extends JPlugin {
      function plgContentItemList(&$subject, $params) {
        parent::__construct($subject, $params);
        $this->_plugin = JPluginHelper::getPlugin('content', 'itemlist');
      }
   
      function onPrepareContent(&$article, &$params, $limitstart) {
        $content = $article->text;
   
        if(preg_match_all("/{itemlist:.+?}/", $content, $matches, PREG_PATTERN_ORDER) > 0) {
          foreach ($matches as $match) {
            foreach ($match as $m) {
              $catid = intval(str_replace('}', '', str_replace('{itemlist:', '', $m)));
              $query = 'SELECT id, title FROM #__content WHERE catid = ' . $catid . ' AND state=1';
   
              $database = JFactory::getDBO();
              $database->setQuery($query);
              $items = $database->loadObjectList();
   
              $output = '<ul>';
              for($i = 0; $i < count($items); $i++) {
                $link = 'index.php?option=com_content&task=view&id='. $items[$i]->id;
                $output .= '<li><a href="'. $link . '">' . $items[$i]->title . '</a></li>';
              }
              $output .= '</ul>';
   
              $content = preg_replace('/{itemlist:.+?}/', $output, $content, 1);
            }
          }
        }
   
        $article->text = $content;
        return true;
      }
    }
    ?>



В этом файле реализован весь функционал нашего плагина. Класс plgContentItemList имеет конструктор, который, в целях совместимости с PHP4 реализован именно в старом стиле. Инициализация сводится лишь к тому, что необходимо загрузить информацию о плагине, что производится вызовом метода getPlugin класса JPluginHelper. В методе onPrepareContent с помощью регулярных выражений реализуются шаги, описанные выше.

Для установки плагина в Joomla, еще нам понадобится xml-файл с описанием плагина.

itemlist.xml


<?xml version="1.0" encoding="utf-8"?>
    <install version="1.5" type="plugin" group="content">
      <name>Content - ItemList</name>
      <author></author>
      <creationDate></creationDate>
      <copyright>Copyright (C) 2009. All rights reserved.</copyright>
      <license>www.gnu.org/licenses/gpl-2.0.html GNU/GPL</license>
      <authorEmail></authorEmail>
      <authorUrl></authorUrl>
      <version>1.0</version>
      <description>
        A category items list plugin. <br /><br />
        Usage: {itemlist:category_id}
      </description>
      <files>
        <filename plugin="itemlist">itemlist.php</filename>
      </files>
    </install>



Теперь архивируем zip-ом эти два файла в один архив, устанавливаем плагин через админпанель Joomla и не забываем его опубликовать. Для просмотра результатов его работы в теле статьи используем тег {itemlist: id_категории}.