Расширения, которые мы выбираем: плагин Pagelist
- 920 просмотров
- 1 октября, 2023
- Обновлено: 17 октября, 2023
- admin
- Время чтения: 5 минут
- 1 (Подробно)
![История создания плагина Pagelist](pics/thumbs/23/img-23-966x644-crop.jpg)
Когда-то очень давно я общался с главным создателем и идейным вдохновителем проекта Cotonti Владимиром Сибировым aka Trustmaster по поводу идеи универсального плагина, способного, как минимум, заменить:
- плагин News
- плагин Recent Items
И вообще, хотелось формировать виджеты в виде списков страниц модуля Page в любом виде. Казалось бы противоречивый вопрос оказался совершенно простым в реализации. По крайней мере, в экосистеме Cotonti. Именно так Trustmaster и написал плагин Pagelist.
Принцип работы плагина Pagelist
Плагин действительно оказался несложным. Формально, это просто функция, выполняющая следующие действия:
- Подключение шаблона
- Обработка аргументов с условиями и формирование MySQL-запроса
- Разбор полученного массива данных на теги в регулярном блоке
- Формирование разбивки на страницы или паджинации (при необходимости)
Другими словами, можно сформировать и оформить вывод страниц в любом количестве, последовательности и с любыми условиями. Это могут быть:
- Новости (ХХ записей конкретного раздела с выводом по убыванию даты)
- Recent Pages (ХХ записей любых или выбранных разделов по убыванию даты)
- Статистика посещения страниц сайта в “админке” (новые страницы, лучшие страницы, лучшие / новые за ХХ дней и т. д.)
- Любые другие выборки
Пункт 4 требует пояснения. Pagelist сформирует любой набор записей, даже с условиями, которые изначально неизвестны разработчику плагина. Например, на вашем сайте размещен каталог смартфонов (раздел с кодом smartphones). Для каждой товарной позиции в созданном экстраполе page_shop_weight указан вес изделия. В таком случае вывод списка пяти телефонов с весом менее 180 грамм будет таким:
{PHP|sedby_pagelist('pagelist', 0, '', 'page_shop_weight < 180', 'single', 'smartphones', 1)}
Можно добавить и сортировку по весу:
{PHP|sedby_pagelist('pagelist', 0, 'page_shop_weight ASC', 'page_shop_weight < 180', 'single', 'smartphones', 1)}
Поскольку MySQL позволяет сортировать по любому количеству полей, к сортировке по весу можно добавить и сортировку по цене. В таком случае получим виджет “5 самых дешевых смартфонов весом менее 180 грамм”:
{PHP|sedby_pagelist('pagelist', 5, 'page_shop_weight ASC, page_shop_price ASC', 'page_shop_weight < 180', 'single', 'smartphones', 1)}
Конечно, использование функции в шаблоне сложнее вставки TPL-тега или переменной. И более трудоемко, чем использование настроек мышью в админке. Однако сложность не настолько значительная, а функциональность и гибкость такого подхода легко перевешивают действительно небольшое время, необходимое для того, чтобы понять принцип действия плагина Pagelist и научиться формировать свои запросы.
Структура шаблона Pagelist
Напомним, что шаблоны для вызовов функции могут быть любые и разные. По умолчанию tpl-файл имеет примерно следующий вид:
<!-- BEGIN: MAIN --> <ul> <!-- BEGIN: PAGE_ROW --> <li class="{PAGE_ROW_ODDEVEN}"> <a href={PAGE_ROW_URL}>{PAGE_ROW_NUM}. {PAGE_ROW_SHORTTITLE}</a> </li> <!-- END: PAGE_ROW --> <!-- BEGIN: NONE --> <li> {PHP.L.Empty} </li> <!-- END: NONE --> </ul> <!-- IF {PAGE_TOP_PAGINATION} --> <p> {PAGE_TOP_PAGEPREV}{PAGE_TOP_PAGINATION}{PAGE_TOP_PAGENEXT} </p> <!-- ENDIF --> <!-- END: MAIN -->
Перечислять все TPL-теги нет смысла: это все pagetags и (при включении соответствующей настройки) все usertags. Опциональные штатные теги указаны на странице плагина. Использование HTML-элементов ul и p исключительно для иллюстративности.
Хуки в Pagelist
Функция имеет четыре хука:
- pagelist.first
- pagelist.query
- pagelist.loop
- pagelist.tags
Их достаточно для того, чтобы обеспечить все необходимые точки входа для добавления дополнительного пользовательского кода.
Например, вы хотите каждую страницу в виджете сопровождать иконкой, обозначающей ее тип. По умолчанию это тип doc, но хочется добавить еще image, video и presentation. Естественно, соответствующего TPL-тега в плагине нет и никогда не будет, а использование логики шаблонизатора потребует сложных конструкций. Но можно все сделать при помощи хука:
- Создаем экстраполе page_pagetype
- Формируем ресурсы для представления соответствующих иконок в формате:
$R['pagetype_doc'] = '<img src="..." alt="..." class='...' />'; $R['pagetype_image'] = '<img src="..." alt="..." class='...' />'; $R['pagetype_video'] = '<img src="..." alt="..." class='...' />'; $R['pagetype_presentation'] = '<img src="..." alt="..." class='...' />';
Теперь в плагин проекта добавим часть с хуком pagelist.loop следующего содержания:
<?php /* ==================== [BEGIN_COT_EXT] Hooks=pagelist.loop [END_COT_EXT] ==================== */ defined('COT_CODE') or die('Wrong URL'); if ($row['page_pagetype']) { $pageType = Cot::$R['pagetype_' . $row['page_pagetype']]; } else { $pageType = Cot::$R['pagetype_doc']; } $t->assign('PAGE_ROW_PAGETYPE', $pageType);
В итоге получим TPL-тег PAGE_ROW_PAGETYPE, который можно использовать в регулярном блоке PAGE_ROW шаблона плагина Pagelist. В шаблон page.edit.tpl добавим теги для изменения содержимого экстраполя page_pagetype:
<tr> <td>{PAGEEDIT_FORM_PAGETYPE_TITLE}:</td> <td>{PAGEEDIT_FORM_PAGETYPE}</td> </tr>
Теперь если оставить его пустым, получим иконку ресурса doc. Для альтернативных вариантов можно использовать значения image, video или presentation.
Развитие плагина Pagelist
Долгое время плагин использовался “как есть”. Единственное изменение касалось переноса функции в отдельный файл pagelist.functions.php для того, чтобы иметь возможность подключать ее только там, где это необходимо. Дальнейшие изменения также стали не сильно принципиальными:
- Совместимость с плагином интернационализации контента i18n
- Отключаемое создание usertags (модуль Users)
- Отключаемый вывод количества комментариев для страницы (плагин Comments)
- Отключаемый вывод количества рейтингов, среднего значения и графического представления (плагин Star Ratings)
- Добавление кэширования (только при выводе для незарегистрированных пользователей)
- Очистка кэша при добавлении, изменении и удалении страницы
- Добавление AJAX-паджинации
- Учет доступа к разделам выводимых страниц (только при выводе для незарегистрированных пользователей
- Опциональный режим вывода только опубликованных страниц
Где-то на полпути в дистрибутиве Cotonti появился клон Pagelist – функция cot_page_enum(). В виде чистой функции она оказалась лишена некоторых плюсов полноценного плагина, за исключением возможности кэширования вывода. Странно, но даже в таком виде она почему-то не получила распространения у владельцев ресурсов на базе Cotonti.
Идея, заложенная в Pagelist, использовалась и при создании других аналогичных плагинов, предназначенных для создания виджетов комментариев, форумных тем и постов, элементов структуры сайта.
Что еще может Pagelist?
Все, что касается работы со страницами. С помощью этого плагина можно создать виртуальный раздел в любой локации сайта, даже там, где это технически не предусмотрено.
Самый простой пример: у вас есть пустой родительский раздел documentation, в котором есть три подраздела со страницами:
- documentation
- basics
- advanced use
- undocumented features
В таких случаях возникает вопрос: чем наполнять “родителя” documentation? Самый простой ответ – использовать Pagelist для вывода в нем всех страниц из “потомков”:
{PHP.c|sedby_pagelist('pagelist', 10, 'page_date DESC', '', 'single', '$this', 1, 0, 0, 'page')}
Или, к примеру, вам необходимо создать страницу товаров со скидками и вывести на ней все товары с непустым экстраполем page_shop_has_discount. Можно и это:
{PHP|sedby_pagelist('pagelist.discounts', 10, '', 'page_shop_has_discount != ""', '', '', 0, 0, 0, 'page')}
И вы получите полноценный виртуальный раздел с паджинацией по 10 позиций на страницу, который можно разместить буквально где угодно, даже на главной странице сайта.
Что дальше?
Да, собственно, ничего. Плагин Pagelist для меня остается обязательным расширением для любого проекта. Расширением, которое устанавливается в самую первую очередь и которое решает 99% всех задач, связанных с выводом списков страниц.
Все примеры относятся к теме интернет-магазина исключительно ради иллюстративности. Аналогичные приемы могут (и должны) использоваться для сайтов любой тематики: корпоративных, блогов, порталов, одностраничников (landing page), хобби-сайтов и любых других.
Плагин был, остается и всегда будет бесплатным. Любые вопросы, связанные с его использованием, вы можете задавать в блоге или на странице плагина.
С благодарностью к Trustmaster...
Новый комментарий