- PVSM.RU - https://www.pvsm.ru -
Доброго всем здравия!
Прошло практически ровно два года с момента моей первой публикации о парсере QuadBraces [1] — альтернативе MODX Evolution для простейших проектов, требующих шаблонизации. Это могут быть одностраничники с типовыми публикациями, портфолио, сайты-визитки, состоящие из почти статических страниц, и прочее подобное. С тех пор я обновлял свою разработку и незаметно для сообщества дополз до третьей версии. Нынешняя версия парсера QuadBraces содержит столько изменений, что я просто обязан опубликовать подробный туториал. Итак…
Начнём с обработчиков тегов. В QuadBraces 3 обработчики тегов вынесены в отдельные классы. Теперь разработчик волен определять свои типы тегов, не меняя код самого парсера. Для этого необходимо создать потомок класса QuadBracesTagPrototype, где нужно определить следующее:
На примере обработчика тегов константы:
class QuadBracesTagConstant extends QuadBracesTagPrototype {
protected $_name = 'constant';
protected $_start = '{*';
protected $_rstart = '/';
protected $_finish = '*}';
protected $_order = 5;
public function main(array $m,$key='') {
$v = '';
if (empty($key) || !defined($key)) {
$this->_error = 'not found';
} else { $v = constant($key); }
return $v;
}
}
Ага, точно — всё именно настолько просто. Хотя меня, как программиста старой закалки жутко бесит необходимость хранить файлы микроскопических размеров. Но это уже дело личное, как говорится.
Для тех, кто не читал предыдущую публикацию. Синтаксис тегов QuadBraces един для всех типов тегов:
В третьей версии парсера, как вы уже, наверное, поняли, есть режим синтаксиса MODX Revolution. В этом режиме теги начинаются с двух открывающих квадратных скобок, далее следует некий символ, который и определяет тип тега. А закрывается тег всегда двумя закрывающими квадратными скобками.
Пример тега некоего чанка:
{{news-item? &title=`Мухи съели мера города` &date=`15-09-17` &url=`/news/150917.html`}}
Если в чанке будет:
<article>
<h3>[+title+]</h3>
<span class="date">[+date+]</span>
<a href="[+url+]">Читать далее</a>
</article>
Тогда в итоге на месте чанка будет выведено:
<article>
<h3>Мухи съели мера города</h3>
<span class="date">15-09-17</span>
<a href="/news/150917.html">Читать далее</a>
</article>
Кстати, о мухах. Не они ли скушали пункт HTML из меню «исходный код» редактора на нашем Уютненьком?
Из коробки QuadBraces поддерживает следующие виды тегов (указаны начальная и конечная последовательности для двух режимов):
В нынешней версии парсера есть возможность впихнуть в объект парсера набор т.н. ресурсов. По сути это примерно то же самое, что и ресурсы в MODX. Грубо говоря в базе данных конечного проекта хранится таблица, в которой хранятся записи с постами для блога. Главное — помнить, что каждая запись должна содержать численный ID, ID родителя или NULL и псевдоним для создания URL'а. При установке свойства resources объекта парсера устанавливается свойство idx объекта парсера. Оно представляет собой индекс ветвей дерева ресурсов. Это позволяет работать со структурой конечного набора ресурсов. Собственно, со всей этой фигнёй функциональностью и работает тег ссылок.
Кастомные обработчики переменных — это эдакие микропарсеры, произвольно обрабатывающие переменные парсера. Например, если в некоей переменной парсера (назовём её, скажем, top-menu) содержится массив с URL'ами вида:
array(
array('url' => '/','title' => 'Глагне'),
array('url' => '/about.html','title' => 'О сайте'),
array(
'url' => '/news/','title' => 'Новости','children' => array(
array('url' => '/news/10-09-17.html','title' => 'Мухи прилетели в город'),
array('url' => '/news/15-09-17.html','title' => 'Мухи съели мера города')
)
),
array('url' => '/contacts.html','title' => 'Контакты'),
);
Из него можно сделать меню. Для этого достаточно поместить в нужном месте конструкцию:
[:menu@top-menu:]
На её месте будет выведено меню при помощи маркированных списков. В лучших традициях Wayfinder'а, так сказать.
Вообще по кастомным обработчикам, думаю, нужно будет написать отдельную статью.
Отдельно про одну важную фишку шаблонов, а именно про метаполя. Едва ли не с первой версии существует возможность в коде шаблонов устанавливать метаполя. Оные по сути представляют собой переменные, определяемые в самом шаблоне вот такой конструкцией:
<!-- FIELD:название_поля? [аргументы] -->
Аргументы — примерно то же самое, что и в тегах парсера. Вне зависимости от того, какие аргументы будут указаны в поле, конечное поле будет содержать три атрибута:
Все метаполя будут доступны через свойство fields парсера.
Не менее важной фишкой являются метазначения. Представим себе, что у нас в парсере определена переменная somevar. Метазначение в установленном шаблоне может переопределить текущее значение переменной. Метазначения определяются конструкцией:
<!-- DATA:название_переменной `значение переменной` -->
При установке шаблона и то, и другое удаляется из конечного кода шаблона.
:
:
Одно из важнейших свойств парсера QuadBraces является свойство paths. Оно определяет, где парсер будет искать чанки, сниппеты, расширения, шаблоны. Языковая система работает немного обособлено. В процессе поиска элемента парсер по очереди перебирает все зарегистрированные пути. Каждый раз поисковая функция добавляет к выбранному пути папку в зависимости от вида элемента. Чанки — chunks, шаблоны — templates, сниппеты — snippets. И уже там ищется искомый элемент. Напомню, что точка в ключах чанков, сниппетов и шаблонов по факту заменяет разделитель директорий.
Пример:
$parser->paths = 'D:/projects/mysite/content,D:/repo/templates/default';
$fn = $parser->search('snippet','basis.snipcon');
По факту парсер в данном случае будет проверять существование следующих файлов:
D:/projects/mysite/content/snippets/basis/snipcon.php
D:/repo/templates/default/snippets/basis/snipcon.php
Будет возвращён последний найденный файл. При включённой языковой системе фактически в поиск добавляются пути с языковыми сигнатурами. Допустим, установленный язык — Русский, то есть сигнатура — «ru». Таким образом список файлов следующий:
D:/projects/mysite/content/snippets/basis/snipcon.php
D:/projects/mysite/content/snippets/basis/ru/snipcon.php
D:/repo/templates/default/snippets/basis/snipcon.php
D:/repo/templates/default/snippets/basis/ru/snipcon.php
Всё прочее получается через свойства и методы.
Во-первых, сразу оговорюсь, что языковую систему нужно включать явно. Это делается подключением класса QuadBracesLang. Делается это простейшим кодом до инклуда основного класса:
define("QUADBRACES_LOCALIZED",true);
Лучше всего включить флаг loadLanguage. Тогда словари будут подгружаться автоматически. В принципе по умолчанию при установке путей парсера устанавливаются пути языковой системы. По сути языковая система ищет по тому же принципу свои файлы, что и поисковая система элементов. Только папка языковой системы — lang.
Пример:
$parser->paths = 'D:/projects/mysite/content,D:/repo/templates/default';
$parser->language = 'ru';
Будут сканироваться папки:
D:/projects/mysite/content/lang/ru/
D:/repo/templates/default/lang/ru/
В оных будут искаться все файлы с расширением «lng». Каждый файл считывается построчно. На каждой строке располагаются четыре элемента — языковой ключ, заголовок, описание, плейсхолдер. Языковой ключ — то, что потом используется в языковом теге. Заголовок (caption) — замена языкового тега по умолчанию. Описание (description) — обычно используется для подсказок или описаний полей. Плейсхолдер (placeholder) — чаще всего используется для соответствующего атрибута элементов ввода.
Объект парсера поддерживает события. Обработчики, как я писал выше, устанавливаются методом registerEvent.
Каюсь, по незнанию напоролся на одну особенность PHP. Если, допустим, назначить функцию на обработчик события templateNotFound, а в ней попытаться установить свойство template, ничего не произойдёт. Это обусловлено ограничениями рекурсии при вызове аксессоров для свойств объекта PHP. Если кратко, то нельзя устанавливать свойство через аксессор и аксессора этого же свойства. Никак. От слова «совсем». Так что если захотите сделать 404-ю через обработчик события templateNotFound, вызывайте внутре него неонку метод setTemplate.
Все теги поддерживают обработчики конечного значения. Например, получили мы переменную, а она пустая. Обработчик notempty позволяет задать выводимый текст на этот случай. У некоторых расширений есть дополнительные «расширения». Например, у базовой логики есть расширения «then» и «else».
Расширение ul/ol имеет два внутренних плейсхолдера: [+classes+] — классы элемента (first, last), [+item+] — собственно строка. Для расширения for доступен внутренний плейсхолдер [+iterator+], содержащий номер текущей итерации. Для расширения foreach доступны внутренние плейсхолдеры: [+iterator.index+] — номер позиции текущей итерации, [+iterator+] — текущий индекс.
Собственно, работать с классом парсера очень легко. Базовый пример:
<?php
require 'quadbraces/parser.php';
$parser = new QuadBracesParser('некий/путь/к_шаблонным_данным');
$parser->template = 'my-template';
echo $parser->parse();
?>
В нём мы подключаем класс парсера, инициализируем объект с передачей пути к шаблонным данным, устанавливаем шаблон и парсим. Само собой до обработки можно передать в парсер «настройки», переменные. А до включения класса парсера включить языковую систему, как было написано выше. Более практический пример:
<?php
define("QUADBRACES_LOCALIZED",true);
require 'quadbraces/parser.php';
$parser = new QuadBracesParser('D:/projects/foo/content/template');
$parser->language = 'ru';
$parser->data = array(
'pagetitle' => 'Мухи съели всё',
'date' => '20-09-17',
'image' => 'content/images/flies.jpg'
);
$parser->template = 'news.single';
echo $parser->parse();
?>
Шаблон будет искаться в следующих файлах:
D:/projects/foo/content/template/templates/news/single.html
D:/projects/foo/content/template/templates/news/ru/single.html
Сразу прошу прощения за своё неумение писать туториалы и документацию! Если сообществу будет по-настоящему интересно, наиболее интересные моменты будут раскрываться в последующих публикациях. Задавайте вопросы — с радостью отвечу. Если заметите ошибку — пишите issues на гитхабе сюда [2].
Автор: XanderBass
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/264022
Ссылки в тексте:
[1] первой публикации о парсере QuadBraces: https://habrahabr.ru/post/266865/
[2] гитхабе сюда: https://github.com/XanderBass/quadbraces
[3] Источник: https://habrahabr.ru/post/338018/
Нажмите здесь для печати.