На прошлой работе в качестве шаблонизатора использовали Blitz — так исторически сложилось. Единственным его плюсом по сравнению со Smarty является только скорость работы. Хотя на больших проектах шаблонизатор не является узким горлышком. В качестве примера можно привести Flickr, который использует Smarty. Из более приземленных проектов могу привести один из своих проектов на Smarty. Выбирать шаблонизатор из-за скорости — это большая ошибка. Шаблонизатор должен быть удобным, гибким и иметь большое сообщество. Теперь про минусы Blitz.
1) Далеко не каждому проекту требуется выделенный сервер — новичкам вполне хватает шаред-хостинга. А это означает, что нужно будет уговаривать хостера поставить новое расширение (Blitz — это модуль на Си). Smarty же представляет собой php-класс, для которого вообще не требуется каких-либо сторонних dll.
2) В Blitz нельзя писать даже самых простых выражений в if
Например, такая конструкция работать не будет {{ if $vote < 0}}
В Blitz есть только (if else). Лично мне не хватает (if elseif else)
Например, вывожу оценку за сообщение +/-.
если кол-во голосов < 0, то цифра красная
если кол-во голосов = 0, то цифра черная
если кол-во голосов > 0, то цифра зеленая
в Смарти это было бы так
{if $vote < 0}красный{elseif $vote == 0}черный{else}зеленый{/if}
3) В Blitz передать можно только переменные по отдельности.
Например требуется мне вывести профиль компании (название, адрес, телефон). Эти данные хранятся в базе, я их оттуда беру одним селектом и в итоге получаю ассоциативный массив.
// В Smarty я передаю только массив $smarty->assign('company',array('title'=>'Рога и копыта', mobile=>'53-25-34', 'www'=>'ekimoff.ru')); // а в шаблоне я пишу компания {$company.title} телефон {$company.mobile} сайт {$company.www}
По-моему довольно красиво. Можно и объекты целиком передавать (но это уже слишком сложно для верстальщика)
4) В Blitz сложно выводить вложенные массивы с условиями.
Например, вывести список из 10 чекбоксов, 5 из них должны быть чекнуты. В Smarty это делается так
$smarty->assign('categories', $category_array); // массив всех чекбоксов $smarty->assign('category', $Company->getCategories()); // массив чекбоксов, котрые нужно отметить // в шаблоне конструкция из одной строчки {html_checkboxes name="category" options=$categories selected=$category separator=""}
На самом деле в Смарти полно всяких универсальных конструкций, но на практике используется функционал из 10 страниц документации.
5) Маленькое коммьюнити Blitz. Спрашиваешь на форуме когда будет это реализовано? Тебе отвечают возможно это будет реализовано, но когда — неизвестно. Вообще, Blitz делал один русский программист в стиле just for fun — так он пишет на официальной странице. У Смарти огромное сообщество в России и в мире. Если писать запрос на английском в Гугле, то всегда найдете ответ.
Соответственно, когда вы будете искать работу, то шанс найти вакансию со Smarty довольно велик (почти столько же вакансий по XSLT+PHP).
А мне XSLT нравится как шаблонизатор. Преимуществ масса, работает шустренько, можно расширять php-шными функциями если очень надо... Но главное что такие чудеса им можно творить, ухх...
XSLT мне показался слишком сложным. Порог входа довольно высок для верстальщиков.
Смарти штука сносная, но есть несколько вещей которые меня заставляют негодовать:
* проблемы с инлайновыми JS и CSS т.к. в них используются фигурные скобки - нужно оборачивать в {literal}
* встроенное кеширование отрендеренных страничек (точнее то, что многие им активно и бездумно пользуются и получается полное г-но)
* если не ошибаюсь, там по умолчанию отключен эскейпинг переменных, т.е. если я передам в шаблон переменную с текстом '<script>alert("0wned");</script>' и в шаблоне напечатаю ее, то получится бяка...
PS: а можешь сделать чтобы мне на почту сообщения приходили, если в посте где я комментировал появился новый комментарий?
1) ну не вижу особых проблем с инлайнами. К тому же по-хорошему инлайны нужно выносить в отдельные файлы.
2) там есть 2 кэширования. Компиляция шаблонов - перевод шаблона в php-mess. Тут не вижу проблем. Данная опция ускоряет код за счет того, что шаблоны по сути не используются (т.е. при каждом обращении не прогоняются через регулярные выражения). Кэширование страниц - кэшируютя итоговые страницы с текстом. Если страниц не много и мы не перегружаем файловую систему, то это замечательно.
3) а в чем тут проблема? Ты когда пишешь в PHP < ?=$text?> у тебя автоматически экранируются теги? magic_htmlspecialchars))
Тут ты должен сам понимать, когда нужно экранировать, а когда нет. В случае экранирования, ты можешь выбрать 2 подхода:
экранировать в php
$smarty->assign('text', htmlspecialchars($text));
экранировать в smarty
{$text|escape:'html'}
PS: да, надо сделать. Посмотрю плагин какой-нибудь.
1) Насчет выноса в отдельные файлы согласен, но допустим всякие счетчики/баннеры их нередко используют. В обработчиках событий тоже нередко встречается типа onclick="handle({a:a, b:b})". Я это не просто так говорю - мне сейчас достался по наследству проект где этими literal весь шаблон утыкан. Так зачем создавать проблему на пустом месте?
2) Первое кеширование (в PHP скрипт) там называют скорее даже компиляцией и его наличие я только приветствую. А вот с кешированием отрендеренных страниц не согласен, т.к. его слишком часто применяют не к месту и других кешей не предусматривают. Зачем нам еще какой-то кеш, если есть уже в Smarty?
3) Дело в том, что вывод неэкранированных данных необходим гораздо реже и он опасен, требует осознания ответственности, предварительной фильтрации данных (чтобы теги <a> пропускало а <script> нет, чтобы в ссылках "http://" пускало а "javascript:" нет. На примере твоего блога - не нужно эскейпить:
* текст поста (но нужно тщательно фильтровать)
* комментарии (то же)
нужно эскейпить (т.к. здесь HTML не нужен как таковой):
* имена авторов
* заголовки постов
* теги
* то, что ввели в поисковую форму
* meta keywords и description
наверняка еще куча атрибутов разных тегов и того, что я не вспомнил.
Т.е. идея в том, что если ты что-то лишнее проэкранируешь - ничего страшгого не случится, ну увидит юзер где-то эскейп-последовательности вместо тегов. Как правило это легко заметить и поправить. А если ты забыл проэкранировать, то это дыра в безопасности, уведенные аккакнты пользователей, ифреймы-вирусы, украденные кредитки, статьи по всему интернету "Ааа на сайте блабла обнаружили уязвимость, тысячи юзеров лишились аккаунтов" и т.п., да и заметить это на ранних стадиях сложнее.
В XSLT экранирование заложено в идею языка, чтобы вывести что-то неэкранированное нужно довольно сильно постараться. В шаблонизаторе Django тоже экранирование включено по-умолчанию, для вывода неэкранированного текста нужно указать что содержимое переменной безопасно {{variable|safe}} - т.е. как в смарти, но наоборот. Как в других - не знаю, не сталкивался...
1) а как это решается в других шаблонизаторах? эта проблема из-за самого подхода в подобных шаблонизаторах: замена таких тегов производится через регулярные выражения, так что по-другому никак. В нескольких моих проектах literal стоит только в футере для экранирования счетчиков посещаемости и кнопок типа "Добавить в Фэйсбук".
2) начнем с того, что кэширование отрендеренных страниц по умолчанию выключено. Включать его нужно для небольших проектов на шаред-хостинге. Далеко не все начинают с хайлоада. В 2007 году делал сайт компании на Вордпрессе. Хостинг за 150 руб. Несколько сотен страниц. Как только посещаемость выросла до 100 человек + если приходили поисковики, то хостер автоматически вырубал сайт. Так вот, полное кэширование страниц спасло бы ситуацию. Но я тогда переехал на выделенный сервак. Кстати, для Вордпресса есть подобные плагины, которые целиком кладут страницы в кэш.
3) я все-таки не согласен с концепцией magic_htmlspecialchars. В качестве аргумента приведу пример с magic_quotes, которые DEPRECATED, начиная с PHP 5.3.0. У кого руки из жопы растут, того magic_ фичи не спасут.
1) В Django в качестве служебных символов используются двойные кавычки {{ и }} для печати переменных и {% %} для тегов типа for, if и т.п. Думаю никто не будет спорить что конструкции {{ в JS/CSS исчезающе редко можно встретить. Два раза на клавишу нажать вместо одного рука не отвалится думаю.
В XSLT служебные конструкции - это тот-же XML, но в отдельном пространстве имен. С другими шаблонизаторами не работал практически, но из этих 3-х со смарти были самые большие проблемы и дискомфорт от работы.
2) Пожалуй спорить не буду, тут у меня самые маленькие претензии и самые слабые аргументы (ближе к IMHO) по сравнению с двумя другими. Возможно даже соглашусь.
3) Даже не знаю с какой стороны подойти, чтобы показать, что сравнение с magic_quotes неверное... Сейчас большинство проектов используют для запросов либо плейсхолдеры наподобие тех, что в PDO - типа
$stmt = $dbh->prepare('Select * FROM table WHERE id=?, a=?');
$stmt->execute(array(150, 'red'));
либо используют ORM - тут уже движок ORM обо всем позаботится. Т.е. фактически тут программисту тоже не нужно указывать вручную каждый раз, когда (если) он вспомнит о безопасности, mysql_real_escape_string(). Все делается В НУЖНЫХ МЕСТАХ автоматически БЕЗ ЕГО УЧАСТИЯ. И magic_quotes в этой ситуации только мешает, поэтому он и deprecated.
Т.е. если проецировать способ эскейпинга SQL запросов на magick методы, то уместно такое сравнение:
"Ручной эскейпинг вывода в смарти" == "делать каждый раз вручную mysql_real_escape_string()"
"Автоматический эскейпинг вывода в Django" == "Автоматический эскейпинг параметров запроса с плейсхолдерами в PDO"
а magic_quotes тогда эквивалентен поведению как если бы оператор echo по умолчанию делал бы для всего что он печатает htmlspecialchars() xD Правда бредово звучит? Потому и Deprecated
Так в том то и дело, что запросы в базу нужно всегда экранировать, а эксейпинг при выводе в браузер нужно делать не всегда. Вот например пост http://ekimoff.ru/225/ - там прямо в базе хранится html формы. Зачем мне эскейпить его на автомате при выводе? Вообще есть много CMS, в которых тексты хранятся в базе в перемешку с html.
а ты пишешь
// что если ты что-то лишнее проэкранируешь - ничего страшгого не случится
т.е. ты сам по сути предлагаешь
// echo по умолчанию делал бы для всего что он печатает htmlspecialchars()
Ты почему то расcматриваешь только сайты с user-generated-content, на которых нужно экранировать всё подряд. А я говорю, что эскпейпить нужно не всегда, а когда это действительно нужно. Разница в подходах. У меня есть пара сайтов, на которых вобще нет экранирования, потому что тексты только "свои".
Короче, обсуждение шаблонов всегда выливается в холивар.
Мне приходилось писать с нуля (без фреймворков и т.п.) сайты с админками (управлением структурой сайта, темами дизайна, контентом, импорт данных и т.д.), так вот я так и не смог найти агрументов для применения smarty и прочих специальных шаблонизаторов.
При этом код на чистом ПХП без всяких пришлепок и все замечательно работает и читается.
Есть легенда, что с помощью шаблонизатора можно отделить дизайн от логики, или функционала, или кто как это называет. Но во-первых я не пойму зачем надо это отделять, потому как для отображения динамических страниц как не крути будет смесь минимум HTML+PHP кода, и это нормально. А во-вторых, совершенно понятно что никак это разделить нельзя, без грандиозного усложнения кода и прикручивания лишних звеньев.
Я к тому, что зачем усложнять себе и другим (кто возможно в будущем будет править ваш код) жизнь, разве что для понтов =)
Сравниваете куй с пальцем или мопед с спортбайком.
Блитц для высоконагруженных проектов, а смарти по сравнений с ним поделка на коленке.
Если вы в хайлоаде работаете то за упоминание про смарти вас просто уволят нафиг.
Там много чего нельзя писать, так это шаблонизатор, а не фреймворк.
Автор явно зеленоватый, удачи в рядах смарти :). Я это унылое говно даже близко не подпущу.
Blitz такое унылое говно по сравнению с ClearSilver...