Класс Tags

Класс для работы с шаблонами.

Мне нравится HTML поэтому сделал шаблонизатор, шаблоны которого выглядят как обычный HTML, так же парсятся и так же работают. Жертва скорости в пользу собственной удобности. Принцип шаблонизатора очень прост: он обходит все теги (стандартные и пользовательские), затем их обрабатывает исходя из правила "глубже - первее". Таким образом один тег вложенный в другой обработается первее.

Местами шаблонизатор всё же выходит за пределы HTML. В нём, например, есть переменные обычные доступные во всё шаблоне и локальные - доступные в пределах тега. Так же есть деление на супер-дупер теги, контейнеры и обычные.

Супер-дупер теги вырезаются сразу после парсинга обычных переменных и возвращаются после обработки всего шаблона. Благодаря чему можно сделать кэширование блоков (тег <cache />), пропуск сложных или "not well formed" (шаблонизатор от этого дохнет) кусков кода (тег <skip />).

Контейнеры парсятся так же, как и обычные за исключением того, что обработка текста внутри тега отдана ему самому. В них можно обрабатывать локальные переменные, переменные видимые только этому тегу.

Методы

tags::parse()

Парсит шаблон.

Пример

function tag_my_first_tag($attr){
    return '[tag_my_first_tag] '.$attr['#text'];
}

function tag_my_second_tag($attr){
    return str_replace('[tag_my_first_tag]', '[replaced]', $attr['#text']);
}

$text = 'Some text <my_second_tag>
    and text here
    <my_first_tag>and here some text</my_first_tag>
</my_second_tag>.';

// Some text and text here [replaced] and here some text.
print_r(tags::parse($text));

Вторым параметром можно передать true сообщив тем самым шаблонизатору о том, что это его последний вызов (точнее, что это его главный вызов, а все остальные - дочерние). Тогда Tags сможет обработать некоторые теги, которые должны быть отображены лишь в последнем вызове. Например, тег <cdata /> нельзя обрабатывать до последнего вызова, так как он может нарушить структуру HTML-кода и шаблонизатор выкинет ошибку.

При ошибки Tags выбрасывает исключение.

try {
    tags::parse('
        <b>Test</b>

        <i>Wrong
    ');
} catch (Tags_Except $e){
    echo $e;
}

Выглядеть будет следующим образом.

Mismatched tag

Line: 4.

1
2
        <b>Test</b>
3
4
        <i>Wrong
5
    

tags::parse_else()

Функция парсит тег <else />.

Пример

function tag_ifelse($attr){
    return tags::parse_else(($attr['check'] > 1), $attr['#text']);
}

$text = '<ifelse check="2">
    Аттрибут check больше еденицы.
    <else />
    Аттрибут check меньше еденицы.
</ifelse>';

// Аттрибут check больше еденицы.
print_r(tags::parse($text));

tags::parse_vars()

Парсит локальные переменные вида %{some} и %var{some}.

Пример

function type_bold($var, $value){
    return '<b>'.$value.'</b>';
}

function container_local_vars($attr){
    $array = array(
        'key1' => 'Value #1',
        'key2' => 'Value #2',
        'key3' => 'Value #3'
    );

    return tags::parse_vars($attr, $array);
}

$text = 'Тут не работает: %{local_vars.key2}.
<local_vars>
    Локальная переменная: %{local_vars.key2} - %bold{local_vars.key2}.
</local_vars>';

// Тут не работает: %{local_vars.key2}.
// Локальная переменная: Value #2 - <b>Value #2</b>
print_r(tags::parse($text));

Метод tags::parse_vars() может принимать два, три или четыре параметра.

$data = array('key' => 'Test');
$data_multi = array(
    array('key' => 'Value #1'),
    array('key' => 'Value #2')
);

// массив

$params = array(
    '#tag' => 'vars',
    '#text' => 'Is a %{vars.key}'
);

// Is a Test
print_r(tags::parse_vars($params, $data));

// Is a Value #1Is a Value #2
print_r(tags::parse_vars($params, $data_multi, true));

// каждый параметр отдельно

// Is a Test
print_r(tags::parse_vars('Is a %{vars.key}', 'vars', $data));

// Is a Value #1Is a Value #2
print_r(tags::parse_vars('Is a %{vars.key}', 'vars', $data_multi, true));

tags::fill()

Заполняет тег данными из массива.

Пример

$array = array(
    'param1' => 'Value #1',
    'param2' => 'Value #2'
);

// <test_tag param1="Value #1" param2="Value #2" />
print_r(tags::fill('test_tag', $array));

// или

$array = array(
    '#tag' => 'test_tag',
    'param1' => 'Value #1',
    'param2' => 'Value #2'
);

// <test_tag param1="Value #1" param2="Value #2" />
print_r(tags::fill($array));

tags::unhtml()

Экранизирует все специальные символы в том числе "специальные" по мнению шаблонизатора.

Пример

$test = 'М<b>ног</b>о';

// М&lt;b&gt;ног&lt;/b&gt;о
print_r(tags::unhtml($test));

tags::html()

Обратное от метода tags::unhtml().

Пример

$test = 'М&lt;b&gt;ног&lt;/b&gt;о';

// М<b>ног</b>о
print_r(tags::html($test));

tags::char()

И ещё один экранизатор, но этот специально для символов.

tags::varname()

Строит переменную. Вторым параметром можно задать неймспейс, иначе будет использоваться неймспейс из настроек.

Пример

// $GLOBALS['key']['subkey']['sussubkey']
print_r(tags::varname('key.subkey.sussubkey'));

// $GLOBALS['_POST']['field'], это $_POST['field'], если кто не узнал
print_r(tags::varname('_post.field'));

// $this->vars['key']['subkey']['sussubkey']
print_r(tags::varname('key.subkey.sussubkey', '$this->vars'));

tags::variable()

Получает или ставит значение переменной.

Пример

$test = 'Test';

// Test
print_r(tags::variable('test'));

// при установки значения метод его же и возвращает
tags::variable('test', 'WTF?');

// WTF?
print_r($test);

tags::constant()

Синоним стандартной constant() только меняет все точки в названии константы на знак нижнего подчёркивания.

tags::elmname_parse()

Переводит названия полей в форме к виду переменных шаблонизатора.

Пример

// form.name.sub\.name
print_r(tags::elmname_parse('form[name][sub.name]'));

tags::elmname_unparse()

Обратное от метода tags::elmname_parse().

Пример

// form[name][sub.name]
print_r(tags::elmname_unparse('form.name.sub\.name'));

// form[name][sub.name]
print_r(tags::elmname_unparse('form[name][sub\.name]'));

tags::serialize()

Переводит массив в строку.

Пример

$array = array(1, 3, 5);

// YTozOntpOjA7aToxO2k6MTtpOjM7aToyO2k6NTt9
print_r(tags::serialize($array));

tags::unserialize()

Обратное от метода tags::serialize().

Пример

print_r(tags::unserialize('YTozOntpOjA7aToxO2k6MTtpOjM7aToyO2k6NTt9'));

/* Array
(
    [0] => 1
    [1] => 3
    [2] => 5
) *

tags::is_array()

Проверяет является ли строка массивом (ага).

Пример

// true
var_dump(tags::is_array('YTozOntpOjA7aToxO2k6MTtpOjM7aToyO2k6NTt9'));

tags::has_close_tag()

Проверяет нужен ли тегу из стандартного набора HTML закрывающий тег.