Описания конечно же не нашел. Изучил имеющиеся плагины. После двух дней мытарств удалось запустить плагин для Cookbook, который вывел в карте сайта все рецепты и продукты.
Думаю, что я не единственный, кто может задаться целью написать плагин для xmap. Как результат работы публикую текст условного плагина для условного компонента com_test. Этот тестовый компонент работает с деревом каталогов (catalogs), в каждом из которых может содержаться некоторые статьи (items). Естественно, результат необходимо оформить в надлежащем пакете для установке, но это уже просто. Изучайте утановленные плагины. Там как раз все ясно.
В меню ссылка на каталог выглядит следующим образом:
<site>/index.php?option=com_test&view=catalog&id=<номерочек каталога>
Ниже приведенный текст плагина разворачивает эту ссылку в дерево каталогов и их статей. Текст документирован достаточными для понимания коментариями. Все лишнее я убрал. Возможно, текст можно еще упростить, но не думаю, что принципиально. В каком-то смысле - это минимальный плагин. За остальным - вперед, изучайте плагины для com_k2 или com_content!
<?php/** * @license GNU General Public License version 2 or later; see LICENSE.txt * @author Alexander Bushmelev (Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.) */defined( '_JEXEC' ) or die( 'Restricted access' );/** * Обработка каталогов и элементов каталога * * Плагин для компонента XMap, который раскрывает каталог тестового компонента com_test из меню */class xmap_com_test { /** * Эта функция вызывается перед тем как будет обработан элемент меню и используется * для установки является ли данная ссылка контейнером или конечным элементом * Эта функция обязательно должна быть реализована * * @param object Обрабатываемый элемент меню * @param array массив параметров свойств элемента в карте * * @return void * @since 1.2 */ static function prepareMenuItem($node, &$params) { /* * Стандартные вызовы для получения информации о текущих параметрах элемента меню * следующие четыре строчки стандартны и служат для получения значений id и view */ $link_query = parse_url($node->link); parse_str(html_entity_decode($link_query['query']), $link_vars); $view = JArrayHelper::getValue($link_vars, 'view', ''); $id = intval(JArrayHelper::getValue($link_vars, 'id', 0)); if ($view == 'testitem') { if ($id) { $node->uid = 'com_testi' . $id; } else { $node->uid = 'com_testi' . $view; } /* * Устанавливаем, что этот элемент терминальный и не содержит в себе * других элементов которые нужно обрабатывать * Собственно, в этом весь смысл этой функции */ $node->expandible = false; } elseif ($view == 'catalog') { if ($id) { $node->uid = 'com_testc' . $id; } else { $node->uid = 'com_testc' . $view; } /* * Устанавливаем, что этот элемент является каталогом и должен * обрабатыватья рекурсивно * Собственно, в этом весь смысл этой функции */ $node->expandible = true; } } /** * Expands a com_test menu item. Эта функция вызывается для всех контейнеров * Обязательная для реализации функция * * @param object карта сайта * @param object Родительский элемент, к которому производится привязка * @param array массив параметров свойств элемента в карте * * @return void * @since 1.0 */ static function getTree($xmap, $parent, &$params) { // Добавляем описание используемых классов require_once JPATH_SITE.'/components/com_test/models/catalog.php'; require_once JPATH_SITE.'/components/com_test/helpers/route.php'; // Следующие строки более или менее стандартные и служат для получения // информации о view и id $link_query = parse_url($parent->link); if (!isset($link_query['query'])) { return; } parse_str(html_entity_decode($link_query['query']), $link_vars); $view = JArrayHelper::getValue($link_vars, 'view', 0); $catid = intval(JArrayHelper::getValue($link_vars, 'id', 0)); // Устанавливаем значения параметров элемента карты сайта // В данном случае тупо забиваем эти значения, но можно получить из описания $params['cat_priority'] = 0.5; $params['cat_changefreq'] = 'weekly'; $params['link_priority'] = 0.5; $params['link_changefreq'] = 'weekly'; if ($view == 'catalog') { // Обрабатываем только каталоги // Получаем объект каталог в зависимости от значения его идентификатора // Если идентификатор отсутствует, то это корневой каталог $catalog = ($catid? TestModelCatalog::loadCatalog($catid) : TestModelCatalog::getRoot()); // Вызываем внутреннюю рекурсивную функцию для обработки каталога self::getCatalogTree($xmap, $parent, $params, $catalog->id); } } /** * Функция внутренняя, название ее не принципиально. Параметры как удобно, так * и делаем. В данном случае это * * @param object карта сайта * @param object Родительский элемент, к которому производится привязка * @param array массив параметров свойств элемента в карте * @param int идентификатор каталога * * Последний параметр выбран так как было удобнее. Первые три можно считать необходимыми * Обращаем внимание, что параметр params передается по ссылке и может быть изменен * по ходу обработки. Нам менять его значение в данном примере не нужно. * * @return void */ static function getCatalogTree($xmap, $parent, &$params, $catid) { // Получаем все подкаталоги данного каталога $children = TestModelCatalog::getSubcatalogList($catid); // В данном примере каталоги не поддерживают информацию о времени их последнего // изменения, поэтому используем текущее время $modified = time(); $xmap->changeLevel(1); // Увеличивем уровень вложенности foreach ($children as $cat) { $node = new stdclass; $node->id = $parent->id; $node->uid = $parent->uid . 'c' . $cat->id; // В данном месте функция htmlspecialchars_decode() используется для того // чтобы на экран выводились читабельные символы. Этот вызов был необходим // так как название каталога содержит символы " $node->name = htmlspecialchars_decode($cat->name); // Для каждого элемента прописываем его url, в данном случае что-то типа: // 'index.php?option=com_test&view=catalog&id='.$catalogid // для этого используется встроенный роутер компонента $node->link = TestHelperRoute::getCatalogRoute($cat->id); $node->priority = $params['cat_priority']; $node->changefreq = $params['cat_changefreq']; $node->expandible = true; // это контейнер!!! $node->modified = $modified; // Вызов $xmap->printNode($node) и приводит к появлению строчки на экране if ($xmap->printNode($node) !== FALSE) { // Рекурсивно обрабатываем подкаталоги подкаталога self::getCatalogTree($xmap, $parent, $params, $cat->id); } } // После обработки подкаталогов обрабатываем все терминальные элементы // Все действия аналогичны обработке каталогов, кроме рекурсивной обработки $items = TestModelCatalog::getItemList($catid); foreach ($items as $item) { $node = new stdclass; $node->id = $parent->id; $node->uid = $parent->uid . 'i' . $item->id; $node->name = htmlspecialchars_decode($item->name); $node->link = TestHelperRoute::getItemRoute($item->id); $node->priority = $params['link_priority']; $node->changefreq = $params['link_changefreq']; $node->expandible = false; $node->modified = $modified; $xmap->printNode($node); } $xmap->changeLevel(-1); // Не забываем восстановить уровень вложенности! } }