Blitz: шаблонный подход к построению контента

blitz templates Blitz: шаблонный подход к построению контента Мне кажется, что пора уже рассматривать тему шаблонизаторов – специальных библиотек для построения шаблонов. Проблема любого крупного проекта, я думаю, – отделение дизайна от кода (т.е. html-страниц от php-кода). Зачем это делать? Ну на то конечно есть причины. Во-первых, разделенные дизайн и код легче поддерживать и изменять.

Во-вторых, если на сайте нужна смена скинов, без шаблонов не обойтись, потому что для каждого скина придется дублировать все php-файлы (код), а это не есть хорошо (потому что отнимает много времени) для постоянно изменяющегося кода в результате воздействия заказчика icon smile Blitz: шаблонный подход к построению контента

Так вот, существует множество шаблонизаторов, из которых я бы воспользовался одним из двух: Smarty и Blitz. О Smarty мы поговорим в других статьях, а в этой коснемся Blitz – шаблонизатора, о котором я совсем недавно узнал, в отличие от Smarty.

Blitz – шаблонизатор, написанный нашим соотечественником – Алексеем Рыбаком – на основе движка php_templates. Считается самым быстрым шаблонизатором на данный момент. Причина такого быстродействия – написан на языке Си (как модуль расширения PHP). Но у каждой вещи в этом мире есть свои достоинства и недостатки. Про главное достоинство Blitz я уже сказал, а главных недостатков я выделил у него три:

  1. На данный момент еще сыроват, т.к. не доделан даже до версии 1.0 (на момент написания этой статьи последняя версия была 0.6.1);
  2. Функционал не такой мощный, как в Smarty (этот недостаток можно едва компенсировать наличием механизма контекстов и итераций, которого нет у Smarty). Я бы сказал даже, Smarty гораздо мощнее;
  3. Библиотеку нужно устанавливать в качестве расширения PHP, что возможно не у всех хостинг-провайдеров.

Но, несмотря на эти недостатки, этот шаблонизатор стоит того, чтобы рассмотреть его возможности.

Установка Blitz

У меня, как Вы знаете (а может и не знаете), система Windows, поэтому я просто прикрутил модуль php_blitz.dll, ссылку на который можно найти здесь. В Linux как он устанавливается, я не знаю, но в официальной документации, которая состоит всего из одной странички, можно найти ссылку на исходники и готовые модули. Там же написано про то, как устанавливается этот Blitz.

Изучаем Blitz

Начнем с самого простого – выведем в окно браузера содержимое переменной:

example1.tpl

Содержимое переменной $a: {{$a}}<br />
Содержимое переменной $b: {{$b}}

example1.php

<?
    header('Content-Type: text/plain');

    $T = new Blitz('example1.tpl');
    $T->set(Array('b' => 'world'));
    echo $T->parse(Array('a' => 'Hello'));
?>

Вывод:

Содержимое переменной $a: Hello<br />
Содержимое переменной $b: world

В этом примере мы вывели содержимое двух переменных двумя способами. Функция set позволяет задать ассоциативный массив локальных переменных, а функция parse – возвращает результат выполнения шаблонизатора. Функция parse тоже может принимать массив переменных, но при этом они будут глобальными, т.е. видимыми не только в шаблонах как таковых, но и в контекстах (о контекстах я расскажу ниже).

Можно не передавать методу parse массив с глобальными переменными, а передать его отдельно методу setGlobal:

$T->setGlobal(Array(‘b’ => ‘world’));

Теперь покажу различие глобальных и локальных переменных в контекстах:

example2.tpl

Я {{$l}} переменная.<br />
Я {{$g}} переменная.<br />
{{BEGIN root}}<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я {{$l}} переменная.<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я {{$g}} переменная.<br />
{{END}}

example2.php

<?
    header('Content-Type: text/plain');

    $T = new Blitz('example2.tpl');
   
    $T->set(Array('l' => 'локальная в пределах шаблона'));
    $T->setGlobal(Array('g' => 'глобальная'));
    $T->block('/root', Array('l' => 'локальная в пределах контекста'));
   
    echo $T->parse();
?>

Вывод:

Я локальная в пределах шаблона переменная.<br />
Я глобальная переменная.<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я локальная в пределах контекста переменная.<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я глобальная переменная.

Здесь мы ввели понятие контекста – это блок информации в шаблоне, который должен быть выполнен, прежде чем его можно вывести. Выполнили мы его с помощью функции block, установив в ней локальные для данного контекста переменные. Если бы мы не установили локальные для root переменные, т.е. вызвали бы таким образом…

$T->block(‘/root’);

…, то вывод был бы таким:

Я локальная в пределах шаблона переменная.<br />
Я глобальная переменная.<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я  переменная.<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я глобальная переменная.

Т.е. локальная в пределах шаблона переменная не действует в зоне контекста, а глобальная переменная действует везде.

Если бы мы не вызвали block (не выполнили бы контекст), вывод был бы таким:

Я локальная в пределах шаблона переменная.<br />
Я глобальная переменная.

Вообще контексты в Blitz – очень мощная штука. С их помощью, по утверждению автора, можно формировать контент любой сложности. Еще бы! Ведь эти контексты могут быть вложенными:

example3.tpl

{{BEGIN root}}<br />
&nbsp;&nbsp;&nbsp;&nbsp;Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;{{BEGIN child}}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{BEGIN grandchild}}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #{{$i}} контекста root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{END}}<br />
&nbsp;&nbsp;&nbsp;&nbsp;{{END}}<br />
{{END}}

example3.php

<?
    header('Content-Type: text/plain');

    $T = new Blitz('example3.tpl');
   
    $T->block('/root');
    $T->block('/root/child');
    $T->block('/root/child/grandchild', Array('i' => 1));
   
    $T->context('/root/child/grandchild');
    $T->iterate();
    $T->set(Array('i' => 2));
   
    echo $T->parse();
?>

Вывод:

Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #1 контекста root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #2 контекста root.

Здесь мы два раза выполняем тело контекста grandchild с разными значениями переменной i. Причем делаем это двумя способами: уже знакомой нам функцией block и вызовами context-iterate-set. Вызов context() устанавливает текущий контекст, над которым будет потом выполнена итерация с помощью iterate() и которому будут присвоены локальные переменные с помощью set().

/root/child/grandchild – это, как Вы уже наверняка догадались, полный путь к контексту. Но можно задавать и относительные пути. Например:

$T->context(‘/root/child’);
$T->context(‘grandchild’);

Это эквивалентно

$T->context(‘/root/child/grandchild’);

Но я бы предпочел использовать более компактный вариант с block().

Для вызова определенного контекста без выполнения всего шаблона можно использовать fetch():

example4.php

<?
    header('Content-Type: text/plain');

    $T = new Blitz('example3.tpl');

    echo $T->fetch('/root/child/grandchild', Array('i' => 1));
?>

Этот пример выведет: Я – внук #1 контекста root.

А что делать, если нам нужно очистить текущий контекст от переменных и/или итераций? Для этого есть функция clean():

example5.php

<?
    header('Content-Type: text/plain');

    $T = new Blitz('example3.tpl');
   
    $T->block('/root/child/grandchild', Array('i' => 1));
   
    echo $T->parse();
   
    $T->clean('/root/child/grandchild');
   
    echo $T->parse();
?>

Этот пример выведет:

Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #1 контекста root.<br />
Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.

Но стоит нам убрать вызов clean(), как вывод станет таким:

Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #1 контекста root.<br />
Я - главный контекст root.<br />
&nbsp;&nbsp;&nbsp;&nbsp;А я - дочерний контекст child.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Я - внук #1 контекста root.

Иногда бывают случаи, когда тело шаблона хранится в переменной (например, если шаблоны хранятся не в текстовых файлах, а в базе данных). Для этого случая есть функция load():

example6.php

<?
header('Content-Type: text/plain');
   
$tpl = <<<TPL
hello, {{ \$world }}!
{{ bye('world') }}
TPL
;

class View extends Blitz {
    function bye($who) {
        return "Bye, $who!";
    }
}

$T = new View();
$T->load($tpl);
echo $T->parse(array('world' => 'world'));
?>

Здесь мы немного расширили класс Blitz и добавили в него свой метод, чтобы потом вызвать из шаблона. Метод, как видите, может принимать параметры прямо из шаблона.

Итоги

В общем, это все основные возможности шаблонизатора Blitz. Официальная документация у него небольшая (как я уже говорил – одна html-страница), ее можно найти здесь (на русском языке). Кстати, если Вы еще туда не заходили, по этой же ссылке приведены результаты тестов, по которым можно более-менее судить о быстродействии этого шаблонизатора. Еще замечание по поводу документации: ее английская версия гораздо актуальнее, поэтому я советовал бы всем обращаться именно к ней.

Теперь мы умеем отделять дизайн от кода, а это очень важно для больших проектов. Но это еще не все. Чтобы практически можно было осуществить это в реальности, я бы воспользовался более старым, медленным, но зато проверенным и мощным шаблонизатором Smarty, о котором расскажу в следущих статьях.

Скачать все примеры к этой статье.





Читайте также:



7 Ответов на “Blitz: шаблонный подход к построению контента”

  1. VolCh
    Август 4th, 2008

    Интересно было почитать, но чисто познавательно, то, что он работает как модуль начисто, имхо, отбивает все преимущества. Слишком узкая область применения, тем более при разработке для заказчика, а не для своего сервера с рутовым доступом. В общем при написании скриптов на заказ с нуля, имхо, два выбора оправданных шаблонизаторов: Smarty и XSLT, всё остальное от лукавого :)

  2. mif
    Август 9th, 2008

    Хах, наоборот это один из плюсов, а не минусов. Вы только почитайте, какие у него преимущества в скорости и удобстве использования. А то, что он подключается в качестве модулья, так это не проблема – напишите в тех.поддержку хостинга, и, если он у вас хороший (а для серьезных проектов, особенно для заказчика, по-другому быть не должно), вам его без проблем подключат.
    Не сочтите за рекламу, но, к примеру, на РБК-хостинге это сделали без проблем.

  3. novice
    Август 10th, 2008

    2 mif: С плохим хостингом это конечно недостаток, но с хорошим – стоит попробовать.

  4. рыбак алексей
    Август 12th, 2008

    привет, я – автор blitz
    случайно наткнулся на текст, хочу поправить чуть-чуть
    в example2.php нет бага – include “наследует” итерацию, это сделано как раз для больших любителей инклюдов, которым хочется поменьше делать телодвижений – один раз засетил и везде видно.

    касательно ссылок – полезнее давать ссылку на английскую доку, русская устарела, и там не описано очень много. правда, и английская тоже немного устарела ;)

    wbr,
    fisher

  5. novice
    Август 13th, 2008

    Привет, Алексей! :)
    Исправил статью. Спасибо за комментарий.

  6. ekim
    Декабрь 4th, 2008

    Мне не нравится Blitz, хотя работаю на нем уже пол года. Например,
    нельзя сделать так {{ if($a>0,’plus’,'minus’) }}
    нет конструкции {if elseif else}

    Smarty – это хоть не так быстро, но зато гибко и удобно. А скорость для шаблонизатора не самое главное.

  7. Константин
    Март 17th, 2009

    {{ if($a>0,’plus’,’minus’) }}

    так можно сделать – просто пишете функцию в классе, который расширяет Blitz типа

    function iftype($var_1, $type, $var_2, $comparison_ok=”, $otherwise=”, $eq=”) {
    if ($type==’<’) {
    if ($var_1 $var_2) return $otherwise; else return $eq;
    }
    elseif ($type==’>’) {
    if ($var_1 > $var_2) return $comparison_ok; else if ($var_1 < $var_2) return $otherwise; else return $eq;
    }
    elseif ($type==’==’) {
    if ($var_1 == $var_2) return $comparison_ok; else return $otherwise;
    }
    }

Оставить комментарий


© 2008 - 2012 i-novice.net | Все права защищены.