PHP, шаблоны и короткий синтаксис
11 августа 2010
Одним из самых частых аргументов, приводимых в пользу шаблонизаторов по сравнению с голым PHP, является более красивый синтаксис:
{$code}
вместо
echo $code
На самом деле этот аргумент, хотя и самый часто используемый, является полностью необоснованным.
Если включить в php.ini short_open_tag, можно вместо действительно громоздкого кода, приведённого выше, писать:
$code
При использовании альтернативного синтаксиса управляющих конструкций, код будет гораздо понятней, чем шаблон того же Smarty:
<ol> <?foreach($users as $user): <li> <h2><?=$user->username</h2> <p><?=$user->notes</p> </li> <?endforeach </ol>
Комментарии RSS по email OK
Неужели так много стоит усилий написать <?php echo $code; ?> вместо <?=$code; ?> ? Или if ($foo === true) вместо if ($foo == true) ? Ведь потом настолько легче.
Александр, а, например, про такое
что скажешь?
Чем проще, чем в Smarty 3
{$user.username}
{$user.notes}
Сам тоже был сторонником шаблонов на PHP, пока не появился Smarty 3.
И такой вариант и Smarty тоже - полный отстой.
а меня еще прикалывают ебанаты, которые в своем проекте на своем сервере отключают short_open_tags и только поэтому используют смарти. а еще они говорят, что шаблон-то все равно компилируется, поэтому нет потери производительности. по факту потеря уже идет на этапе компиляции, пусть она и происходит 1 раз. то что этим можно пренебречь - это уже другой вопрос.
Насколько мне известно, нынче писать полные пхп тэги, как минимум, правило хорошего тона. О переносимости я вообще молчу...
я со смарти так и не подружился, и слава богу)))
А я уже к полным тегам привык, пишется уже автоматом и просто не замечаешь что пишешь <?php echo $something?>. Ну а любая хорошая IDE позволяет добавить своё сочетания для авто дополнения, пишете что-то вроде <?php echo ?> и вообще забываете о проблеме :)
Я вообще не люблю подобные смешивания двух синтаксисиов, будь то PHP+HTML или Smarty+HTML - читать потом неудобно. С другой стороны, однозначным решением проблемы я тоже не располагаю.
В плане переносимости считаю правильным всегда использовать полные теги и поддерживаю идею о текстовых макросах в IDE.
А вообще можно пользоваться вариантами типа printf() и смешивать синтаксисы только тогда, когда это действительно необходимо. Хотя Smarty неплохо выглядит с т.з. читаемости.
Сколько раз не пытался использовать short_open_tag, столько раз и жалел об этом. Так как обычно все равно потом проект попадает на сервер где забыли их включить, и наружу вылазит весь пхп код тогда. Или администратор может обновить что-то на сервере и забыть включить short_open_tag (т.е. не обязательно, что бока будут при переезде только). В общем стремная и по большому счету не такая уж и нужная штука.
Между {$code} и <?=$code?> разница действительно невелика. Но возможности шаблонизаторов обычным выводом не ограничиваются.
Между {$code|escape} и <?=htmlspecialchars($code)?> разница уже чувствуется, а это только вершина айсберга :)
idle
XML-шаблоны не так часто приходится писать. Да и проблема там будет только в одной строчке-заголовке, но не в теле. Решить можно, например, через echo.
alkaruno
Ничем. В том то и дело, что одинаково.
Тормоз
Есть решение лучше?
Ярик
«Правило хорошего тона» — плохой аргумент. Правила неспроста придуманы, за ними стоят решение каких-то проблем ;)
Bobby
Вот это уже пошло нормальное сравнение, а не просто «синтаксис вот в этом примере круче». Так и надо.
Основная проблема php-кода в шаблонах состоит в том, что такой шаблон может легко сломать весь сайт, если где-то что-то не будет закрыто.
Плюс нет возможности реализовать режим "песочницы", т.е. разрешить использовать в шаблоне ограниченное количество тэгов.
Так же у вас приведены совсем простые примеры, попробуйте ваш код с разнообразными преобразованиями (escape/iconv) и вы увидите насколько он будет "массивнее" кода на псевдо языке.
Вот, по моему мнению, отличный шаблонизатор.
http://www.twig-project.org/
надеюсь код нормально вставиться, как такое написать на нативном php чтобы было понятно и красиво (twig):
White Shadow
Скрипты и стили не так просто будет, потому что они должны быть тегами, а не тестом, то есть как минимум обернуть в вызов функции надо $this->javascript('jquery'); и $this->javascripts() ?
С блоками надо было сразу посложнее делать:
layout.twig
{% block content %}123{% endblock %},
index.twig
{% block content %}{% parent %}456{% endblock %},
или так:
layout.twig
{%block head %}
{%block title %}123{% endblock %}
{%block meta %}456{% endblock %}
{% endblock %}
1.twig
{% extends "layout.twig" %}
{%block title %}321{% endblock %}
Результат
321456
2.twig
{% extends "1.twig" %}
{%block meta %}654{% endblock %}
Результат
321654
3.twig:
{% extends "1.twig" %}
{%block head %}789{% endblock %}
Результат:
789
Sergunik
Зря, smarty - отличный и очень удобный шаблонизатор.
White Shadow
Ну, с наследованием уже не так просто — придётся дописать этот функционал. Но синтаксис PHP, причём в довольно нестрашном виде, при этом сохранить возможно. т.е. фактически тут выходит тоже, что и в twig, только без слоя, заменяющего синтаксис (ну и конечно без многого другого). Если нужен тот же sandbox, тут уже обойтись без предобработки или компиляции шаблона никак не удастся.
глупое оправдание с xml легко обходится, у меня на проекте такое было единожды.
не хочется проверять, но кажется, короткий <?= работает и при отключенных коротких тегах. пользуюсь php шаблонами, но альтернативный синтаксис - зло, скажите какая IDE-шка подсветит мне начало и конец блока, как при ~~~ [php] <? foreach(....) { ?>; .... очень много кода .... <? } ?>; ~~~
Прежде чем называть Smarty тормознутым, посмотрите настройки, небось на продакшине не отключаете проверку шаблонов, а возможно даже принудительная перекомпиляция врублена. А уж кеширование с nocache в php шаблонах никто не использует.
Есть решение лучше?
Я просто переменные пишу сейчас в шаблоне :)
И шаблон - вообще обычный HTML-файл.
Посмотри "Йерку".
AmdY
Короткое echo при отключенных коротких тегах не работает.
Блоки с альтернативным синтаксисом подсвечивает, например, PhpStorm.
Use XSLT, Luke! )))
Полные теги считаю признаком хорошего тона.
Почти все популярные стандарты кодирования содержат это правило (Zend, PEAR, Cake и т.п.)
Главное преимущество это переносимость (будет работать на любых системах и в любой конфигурации)
И запись имхо должна быть полной т.е. с ; в конце
Вообще пусть пользуется кто чем хочет, главное чтобы придерживались стандартов, а то бывает открываешь файл, а там тебе и краткие и полные теги и еще куча всего "радующего" глаз :)
Проблема в том что short tag становяться deprecated в PHP 6, разве нет?
Сам я люблю эту форму записи, но меня заставляют от нее отказываться :)
На мой взгляд это чертовски логично - использовать их только в шаблонах (как я и делал), но видимо дальше это делать не судьба, если хочешь оставаться хорошим php парнем.
Кратко:
Short tags - зло.
PHP/HTML mess - зло, за некоторым исключением.
Идея MVC - крута.
Smarty, Twig, etc - хорошо, за некоторым исключением.
kaiser Zaido
Нет.
mktums
Как-то это совсем без аргументов ;)
@White Shadow
Солидарен с тобой. Twig - отменный шаблонизатор! Использую его с 0.9.5 версии.
Сейчас приходится работать над проектом ан Smarty .. конструкции приведенного вида просто рвут мозг на запчасти. Врагу не пожелаешь этом говнокоде ковыряться. :(
{if $show_survey_results eq 1}
{assign var="preheader" value="<a href='/
$smarty.const.ADMIN_FILE
?dpt=modules&sub=survey&edit_poll=$survey_id
' title='$smarty.const.EDIT_BUTTON
' style='float: right;'>+</a>"}{if $isadmin eq "yes"}{assign var="postheader" value=
$preheader``$smarty.const.STRING_SURV_INDEX
}{else}{assign var="postheader" value=$smarty.const.STRING_SURV_INDEX}{/if}{include file="header.tpl.html" header=$postheader}
Плохо только одно - отсутствие поддержки Twig со стороны Zend Studio и NetBeans. Может со временем прикрутят ..
Чуть не забыл -- по тестам Twig еще и гораздо быстрее Smarty и т.п. шаблонизаторов!
Шаблонизаторы хороши коротким специализированым синтаксисом (что в лоне концепции DSL). Я долго предпочитал <?=$var?>, но при разработке одной архитектуры мне потребовалось свернуть такую конструкцию:
<? function opt_module_name_template_name($_ = false) { if ($) extract($); ?>
<? } ?>
Сделал так:
{template_name:
:}
После этого, так как шаблонизатор всё равно уже есть, добавил {var} вместо <?=$var?>, {*func} вместо <?=op_module_name_func()?>, {=template} вместо <? opt_module_name_template($_) ?> и т.д.
Стало сильно лучше.
Но PHP код из шаблонизатора не изгонял. Недавно описал, почему:
http://pavel-koryagin.livejournal.com/8002.html
И особый синтаксис для if/for/foreach в шаблонизаторах по-прежнему считаю излишеством по принципу: нужна логика - ставим PHP-тег, нужен типовой маркер - он поддерживается шаблонизатором.
2stalker
Ваш пример не пример. Наличие говнокода зависит только от разработчика. Поверте в Twig можно тоже такого наворотить если захотеть или просто из за незнания. Преимущество Smarty в том что когда я делаю сайт я могу с чистой совестью сказать верстальщику "в этом проекте я использовал Smarty, так что ты сам можешь подправить таблицу в шаблоне". Без использования шаблонизатора очень часто верстальщик говорит "у тебя там так много PHP, я его не знаю так что правь все сам, я боюсь поломать там все". Вывод для больших проектов удобнее использовать шаблонизатор, притом важно что бы он был популярный поскольку так больше шанс что кроме тебя его знают и другие. А когда пишешь небольшой проект то проще все на php делать. На счет быстродействия... Вы гоните. Сейчас не мы работаем на производительность а она работает на нас. Или в таком случае нужно писать на низкоуровневых языках и забросить PHP. Ведь так будет шустрее будет.
И все же
<input name="login" value="<?=$form['login']?>" type="text" /> vs
<input name="login" value="{$form.login}" type="text" />
Полюбил Twig. Очень нравится своей легкостью и всякими вкусными мелочами (о наследовании вообще молчу) :)
Я конечно новичек, но с шаблонизаторами теряются вкусности хелперов в codeigniter, например
echo heading('Доступные сайты', 2, 'class=""'); echo anchor('main', 'site.com');
vs
Мне кажется так проще, особенно учитывая, что все можно засунуть в переменную. echo form_submit(array('value'=>'Обновить', 'class'=>'reg_button'));