Смарти: продолжаем осваивать
![]() |
Сегодня я бы хотел подробнее рассмотреть механизм условий в смарти и коснуться еще чего-нибудь важного и интересного для данного этапа освоения этого шаблонизатора. Я уже слегка касался условий в предыдущей статье, а теперь хочу подробно рассказать о них, чтобы картина была полной. |
Условия в смарти
Как вы уже поняли из предыдущей статьи, смарти обладает своими тегами. Теги условий выглядят следующим образом:
B is less than A
{/if}
Это простое условие. Теперь простое ветвление:
B is less than A
{else}
A is less than or equal to B
{/if}
Но наверно во всех языках программирования есть конструкция elseif – не обделили ею и Smarty:
B is less than A
{elseif $a < $b}
A is less than B
{else}
A is equal to B
{/if}
Кстати, вместо знаков <,>,==, !=, <=, >=, !, % можно использовать соответственно lt, gt, eq, ne, lte (le), gte (ge), not, mod. Т.е. последний пример можно записать так:
B is less than A
{elseif $a lt $b}
A is less than B
{else}
A is equal to B
{/if}
В условиях еще можно использовать логические выражения: or (||), and (&&) и т.п. Вот например:
A is not equal to B
{/if}
Можно использовать скобки (для повышения приоритета логической операции): {if ($a > $b or $a < $b) and $a < $c && $a < $d}{/if}
Что меня удивило в условиях, так это возможность проверять числа на четность-нечетность и делимость на некоторые числа (подозреваю, что эти операции сделаны через mod):
{if $num is even}{$num} – четное число{else}{$num} – нечетное число{/if}
{if $num is not even}{$num} – нечетное число{else}{$num} – четное число{/if}
{if $num is odd}{$num} – нечетное число{else}{$num} – четное число{/if}
{if $num is div by 5}{$num} делится на 5 без остатка{/if}
{if $num is not div by 5}{$num} не делится на 5 без остатка{/if}
Каждый программер прекрасно знает, что проверить четность можно с помощью операции деления по модулю 2:
{if $num mod 2 eq 0}{$num} - четное число {/if}
Работа с переменными в шаблоне
Кстати, вот тут я использовал директиву assign для присвоения переменной значения в шаблоне. Интересно, а как быть, если нам нужно прибавить к переменной какое-то числовое значение?
Я пробовал {assign var=’num’ value=100+1}, но видимо это неправильно. Ок, тогда попробуем так:
{assign var=num value=$num+1}
{if $num mod 2 eq 0}{$num} - четное число {/if}
Сработало! То же самое можно проделать с любой арифметической операцией.
Хорошо, с числами понятно. А как насчет строк?
Попробуем соединить две строки в одну. С помощью assign у меня не получилось и я начал искать функцию, которая смогла бы это сделать. Оказывается в smarty есть полный аналог php-функции sprintf для форматирования строк:
{assign var='str' value=$world|string_format:'hello, %s'}
{$str}
Этот пример выведет знакомую до боли всем фразу. Этот же пример можно было укоротить:
{$world|string_format:'hello, %s'}
Работа со строками
Ну раз уж мы перешли к строкам, тогда посмотрим, что вообще с ними можно сделать в смарти. Я скажу одно – можно сделать все, что можно сделать в php:
- Сделать первую букву заглавной: {$str|capitalize}
- Присоединить одну строку к другой: {$str|cat: $str2} – кстати, замена рассмотренному выше с string_format варианту
- Подсчитать количество символов: {$str|count_characters:true}
- Подсчитать количество абзацев: {$str|count_paragraphs}
- Подсчитать количество предложений: {$str|count_sentences}
- Подсчитать количество слов: {$str|count_words}
- Поставить отступ перед строкой: {$str|indent}
- Сделать все буквы в строке строчными: {$str|lower}
- Сделать все буквы в строке прописными: {$str|upper}
- Аналог php-функции wordwrap для разбиения длинных предложений: {$str|wordwrap}
- и т.д.
Вот например интересная возможность есть. Допустим у нас есть очень длинная строка, которая не помещается в ограниченную ячейку таблицы. Что мы можем сделать в этом случае? Мы можем обрезать эту строку, да так, чтобы в конце стояло, например, многоточие:
{$str|truncate:30}
Выведет:
Оооочень длинная строка. Ну…
Этим мы сказали смарти, чтобы он обрезал строку, оставив в ней 27 символов и многоточие в конце (27+3=30). Если мы хотим вместо трех точек поставить что-нибудь свое или вообще ничего не ставить:
{$str|truncate:30:""}
Выведет:
Оооочень длинная строка. Ну===
Оооочень длинная строка. Ну пр
Эти три точки можно поставить и в середине строки:
Выведет:
Оооочень длинн… длииииииинная
Или вот еще очень полезная вещь. Допустим у нас есть какая-то переменная, которая может быть инициализирована в php-скрипте с помощью $smarty->assign. Но она же может быть и неинициализирована (пустая). Тогда в шаблоне выводить будет нечего. Но вместо пустоты иногда требуется все-таки вывести какую-то строку. Можно было бы конечно написать, например, так:
{$str}
{else}
No information
{/if}
Но гораздо компактнее вот так: {$str|default:’No information’}. Вместо строки с кавычками может быть переменная: {$str|default:$noinfo}.
Ага.. Нашел еще одну очень полезную вещь – обфускация email. Допустим, нам нужно вывести email, но чтобы пользователь видел его, а спаммерский скрипт, который ищет email-адреса на странице, не смог его определить (или затруднить ему определение). Рассмотрим несколько примеров:
{mailto address=”some@mail.ru”}
<a href=”mailto:some@mail.ru”>some@mail.ru</a>
{mailto address=”some@mail.ru” text=”мой ящик”}
<a href=”mailto:some@mail.ru”>мой ящик</a>
{mailto address=”some@mail.ru” text=”мой ящик” encode=”javascript”}
<script type=”text/javascript”>eval(unescape(’%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%73%6f%6d%65%40%6d%61%69%6c%2e%72%75%22%20%3e%ec%ee%e9%20%ff%f9%e8%ea%3c%2f%61%3e%27%29%3b’))</script>
Тут уже сложнее понять, что за адрес скрывается в этой куче шестнадцатеричных чисел, мягко говоря
На самом деле все рассмотренные (и еще много нерассмотренных) функции – не что иное, как плагины, которые расширяют функциональность smarty. Мы с вами тоже научимся их писать, только не в этой статье, а чуть позже.
Комментарии
Эх, что-то я совсем забыл про комментарии в Smarty
Надо было про них в первой статье рассказать. Ну ладно, лучше поздно, чем никогда:
{* Это
многострочный
комментарий *}
Вот, наверстал упущенное
Глобальная переменная $smarty
Во всех шаблонах можно использовать переменную $smarty. Она дает доступ к следующим глобальным массивам вызвавшего шаблон скрипта:
- $_GET, $_POST, $_REQUEST ($smarty.get, $smarty.post, $smarty.request)
- $_COOKIE ($smarty.cookie)
- $_SERVER ($smarty.server)
- $_ENV ($smarty.env)
- $_SESSION ($smarty.session)
Например, получим содержимое переменной $_REQUEST['id']: {$smarty.request.id}
Или определим имя скрипта: {$smarty.server.SCRIPT_NAME}
Кроме этого можно узнать текущее время: {$smarty.now} – возвращает количество секунд, прошедших с 1 января 1970 года. Это аналог php-функции timestamp (вообще, аналогами их называть неправильно, потому что на самом деле эти php-функции и вызываются; скорее – эквиваленты). Вывести текущее время можно с помощью модификатора date_format (эквивалент одноименной php-функции):
{$smarty.now|date_format:’%Y-%m-%d %H:%M:%S’}
С помощью $smarty.const можно получить доступ к любой константе вызвавшего скрипта, которая была объявлена с помощью define:
{$smarty.const.MY_CONST}
Ну и ради интереса можно посмотреть текущую версию Smarty: {$smarty.version}. У меня вывелось 2.6.18.
Итоги
На сегодня это все. Чувствуется, насколько мощнее и богаче возможности Smarty по сравнению с Blitz (который я рассматривал в этой статье)? Вот в Blitz кстати нет возможности писать к нему плагины, а значит функционал ограничен тем, что заложили в него его же собственные разработчики. Smarty же можно совершенствовать до бесконечности и подтачивать под собственные нужды. Вот наверно в одной из следующих статей про смарти я и расскажу о том, как писать плагины для него. Но сначала Novice сам повникает, как это делается
Удачи в дальнейших экспериментах!

Сентябрь 22nd, 2008
А что с дизайном? В Сафари ваще всё разъехалось…
Сентябрь 23rd, 2008
Спасибо за замечание! Дизайн исправлен.
Октябрь 6th, 2008
Каждый программер прекрасно знает, что проверить четность можно с помощью операции деления по модулю 2:
вообще-то это знает каждый математик =)
а каждый программер знает что проверить четность можно с помощью операции Логического Побитового И, не знаю уж присуще ли оно в smarty, если да то:
{if $num & 1}{$num} – нечетное число{else}{$num} – четное число{/if}
Октябрь 6th, 2008
Да, это работает
Всегда знал про модуль, но до такой элементарной вещи не додумывался. Спасибо!
Октябрь 8th, 2008
Ели нашел этот аналог substr –> truncate заманался искать, помню дет встречал но где….
Одним сломом СПАСИБО
Октябрь 12th, 2008
Как можно сделать file_exists для цикла?
Октябрь 12th, 2008
Не совсем понял суть вопроса. Подробнее?
Октябрь 12th, 2008
{section name=clients loop=$clients}
{counter}
{$clients[clients].name}
{$clients[clients].contact}
{$clients[clients].adres}
{* Вывести картинку если она существует… *}
{/if}
Октябрь 12th, 2008
Решил
{assign var=”file1″ value=$clients[clients].img}
{assign var=”file2″ value=images/clients/$file1}
{if file_exists($file2)}
_img src=”{$file2}” border=”0″_
{/if}
Декабрь 5th, 2008
Прикольно
Январь 16th, 2009
ОТЛИЧНАЯ СТАТЬЯ! ОЧЕНЬ ПОМОГЛА МНЕ! СПАСИБО
Январь 30th, 2009
А как сделать чтобы данные типа 7,8,9,10,11. Выводились как 07,08,09,10,11. Используя смарти???
Январь 31st, 2009
Посмотрите в сторону string_format
Февраль 28th, 2009
Скажите, пожалуйста, как при выборке всех объектов исключить объекты определенного типа?
Февраль 28th, 2009
Не совсем понял вопрос, Надежда. Можете пояснить что Вам нужно, приведя пример на PHP?
Февраль 28th, 2009
Нужно вывести все новые объекты разных NType, но исключить NType = city
примерный список объектов:
Array(
Array(
[NodId] => 19
[NName] => Василий Пупкин
[ParId] => 4
[NType] => people
…
)
Array(
[NodId] => 67
[NName] => Москва
[ParId] => 4
[NType] => city
…
)
Array(
[NodId] => 112
[NName] => Пупкин и со
[ParId] => 4
[NType] => company
…
)
Февраль 28th, 2009
Перечисляете все объекты и ставите условие внутри цикла. Например, так:
{foreach from=$array item=item}
{if $item.NType ne ‘city’}
{$item.NName}
{/if}
{/foreach}
Февраль 28th, 2009
Супер! Спасибо огромное!
А как сделать чтобы исключить два NType?
Просто нужно вывести одиннадцать а исключить два.
Можно конечно вывести перечисляя каждый из одиннадцати типов, но это очень много кода. А главное, нужно чтобы они были вперемешку
Февраль 28th, 2009
{if $item.NType ne ‘city’ && $item.NType ne ‘city2’}
{$item.NName}
{/if}
кажись так…
Февраль 28th, 2009
Точно! Ура!
Именно этого условия мне и не хватало для полного счастья!
Спасибо!!!
P.S. только кавычки нужно не косые, а прямые
Апрель 12th, 2009
Подсчитать количество предложений: {$str|count_sentences}
Подсчитать количество слов: {$str|count_sentences}
Во втором случае должно быть {$str|count_words} =)
Апрель 12th, 2009
Спасибо, исправил
Июль 2nd, 2009
Здравствуйте.
У меня почему-то $smarty.post.var вообще не работает. Ничего выводит, хотя переменная $_POST['var'] инициализирована.
Может нужно сделать какие либо настройки в смарти?
$request_use_auto_globals у меня установлено в true.
Что посоветуете? Заранее спасибо.
Июль 3rd, 2009
Добрый день. Из справки по PHP: если вы установите $request_use_auto_globals в true, variable.request.vars.order не учитывается, а вместо него используется значение gpc_order из настроек php. Может быть дело в ней.
Июль 3rd, 2009
Поставил $request_use_auto_globals = false;
Не помогло.
{$smarty.post|@var_dump}
выводит NULL
Октябрь 28th, 2009
Друзья поможите кто чем может )))
Использую цмску для сайта радио, вот в чём проблема…
В шаблоне списка постов в блоге выводится весь пост полностью вот таким образом : {$post.msg}
Хотелось бы выводить предпросмотр поста , а не весь пост полностью, как это реализвать ??? перелопатил половину гугла ))) Ваш сайт оказался более правильным чем у всех (никто не выпендривается и не говорит “гугл в помощь”)))
Вся беда в том что я не программер, я придурок диджей. Если не сложно – помогите
Апрель 16th, 2010
Спасибо за статью! Очень полезно!