-
Notifications
You must be signed in to change notification settings - Fork 1
ru custom tags
Чтобы добавить тег [MyTag]
нужно создать класс для него (например, my\ns\Tag
) и добавить его в список:
$parser = new Parser(null, [
'mytag' => '\my\ns\Tag',
]);
Класс должен расширять базовый axy\ml\tags\Base
.
Единственный метод, который следует обязательно определить - getHtml(void):string
.
Пример:
namespace my\ns;
class MyTag exnteds \axy\ml\tags\Base
{
public function getHTML()
{
return 'Oh, shit, this is my tag!!';
}
}
Пример, тег: [MyTag:arg1:arg2 this is value].
Вначале устанавливаются следующие protected-переменные:
-
$name
: имя тега в нижнем регистре (mytag
). -
$args
: массив аргументов (["arg1", "arg2"]
). -
$value
: значение тега (this is value
, крайние пробелы обрезаются).
После чего вызывается protected-метод parse()
, который можно переопределить.
Затем при отрисовке всего документа вызывается метод getHTML()
, либо getPlain()
, если запрашивается простой текст (см. Result).
Подразумевается, что parse()
может быть вызван только единожды, а getHTML()
и getPlain()
могут вызываться неоднократно, в том числе ни разу.
Поэтому основной разбор следует сделать в parse()
, а в getHTML()
уже просто компоновать вывод.
Сюда попадают аргументы тега.
Разбор аргументов можно отключить:
class MyTag exnteds \axy\ml\tags\Base
{
protected $args = false;
}
В этом случае в $value
останется всё исходное содержимое тега после имени.
В примере - :arg1:arg2 this is value
.
Возвращает аргумент с порядковым номером $num
(начиная от нуля).
Если такого нет, возвращает $default
.
По сравнению с прямым доступом к $this->args
- не нужно проверять наличие аргумента.
В этом массиве указываются возможные опции и их значения по умолчанию. Если в настройках парсера указываются другие опции для тега, они накладываются поверх этих.
class MyTag exnteds \axy\ml\tags\Base
{
protected $options = [
'one' => 1,
'two' => 2,
];
}
$parser = new Parser(null, [
'mytag' => [
'classname' => '\my\ns\MyTag',
'options' => [
'two' => 22,
'three' => 3,
],
],
]);
Итоговые опции:
[
'one' => 1,
'two' => 22,
'three' => 3,
]
Объект, содержащий следующие поля:
-
result
- текущий объект результата. Уже содержит в себе мета-данные, заголовки и токены. Не рекомендуется трогать в нём свойстваhtml
иplain
. -
options
- глобальные настройки используемые разборщиком. Объект, где настройки доступны, как read-only свойства. -
tags
- список доступных тегов (см. ниже). -
custom
- пользовательский контекст (см. ниже).
Объект, из полезных методов - create($name, $content, $context)
.
Внутри своего тега можно создать экземпляр другого и использовать его вывод.
-
$name
- имя тега. -
$content
- содержимое тега (для тега[name:arg value]
это будет:arg value
). -
$context
- следует не забыть передать$this->context
.
$img = $this->context->tags->create('img', ' /i/a.png', $this->context);
return $img->getHTML();
Пользовательский контекст можно использовать для передачи каких-то элементов системы. Например, наш тег выводит что-то из БД, подключение к ней можно передать через эти настройки.
$customContext = [
'db' => $db,
];
$parser = new Parser(null, null, $customContext);
class MyTag exnteds \axy\ml\tags\Base
{
public function getHTML()
{
return $this->context->custom['db']->query('SELECT ...');
}
}
Может быть полезно, если один класс обслуживает несколько тегов.
Текст из содержимого тега, кроме аргументов (если они используются).
Если содержимое тега имеет неверный формат, ошибки можно складывать сюда. Просто порядковый массив сообщений.
protected function parse()
{
if (!isset($this->args[0])) {
$this->errors[] = 'Arguments is empty';
}
}
Метод, экранирующий текст в соответствии с глобальной опцией escape
.
Следует не забывать экранировать HTML.
return '<a href="'.$this->escape($this->url).'">'.$this->escape($caption).'</a>';
Считывают очередной и, соответственно, последний компоненты значения.
Например, тег: [MyTag:arg one "two three" four five]
.
$this->getNextComponent(); // one
$this->getNextComponent(); // two three
$this->getLastComponent(); // four five
Если компонентов не осталось, возвращают пустую строку.
Вырезают компоненты из $value
, так что считать таким образом структуру тега можно только один раз.
Метод shouldSplitBlock()
возвращает указание на то, следует ли разбивать блок по этому тегу.
Например: This is code: [code 2 + 2].
Это строчный тег (<code>
), блок не разбивается и выводится один абзац.
Или:
This is code:
[[[code
$x = 1;
$y = $x + 2;
]]].
Здесь уже блочный код (<pre>
, он разорвёт текущий блок):
<p>This is code:</p>
<pre>
[[[code
$x = 1;
$y = $x + 2;
]]]
</pre>
<p>.</p>
По умолчанию $splitBlock=FALSE
(блок не разрывается).
shouldSplitBlock()
возвращает $this->splitBlock
.
Если блок следует разорвать, переопределяется либо метод, либо значение свойства.
Вызывается для тега, если он оказывается единственным в блоке. По умолчанию для такого тега создаётся абзац.
[url http://example.loc/ Link]
[code 2 + 2]
[code
x = 1;
y = x + 2;
]
[<div>
Text
</div>]
Результат:
<p>[url http://example.loc/ Link]</p>
<p>[code 2 + 2]</p>
<pre>
x = 1;
y = x + 2;
</pre>
<div>
Text
</div>
Для ссылки создался абзац, для строчного кода тоже, для блокового кода нет. Для html абзац никогда не создаётся.
Вызывается из конструктора. Здесь следует определить основные действия по разбору тега.
Вызывается при отрисовке документа. Здесь следует скомпоновать вёрстку из уже разобранных данных.
Возвращает plain-текст, обычно используемый для поисковых движков.
По умолчанию переадресовывает на getHTML()
, но можно определить что-нибудь более подходящее.
Обычно, не нужно выводить никакие HTML-теги и другие оформительские штучки, просто голый текст.