Get smarty

Куда тут писать?

Smarty – штука тонкая, настроить в ней можно все, что угодно. Даже место, где расположены шаблоны. Да, если ты не в курсе, Smarty – компилятор шаблонов, который берет шаблоны html страниц, и заполняет их необходимыми переменными из PHP.
Шаблоны, конечно могут лежать в любой из папок, но чаще всего – это папка templates (ну это со стандартными настройками), и если там нет шаблонов, или такой папки вовсе нет, лучше проконсультироваться с разработчиком системы, под которую нужно что-то сверстать.
В одной из папок, в той самой, которую определил разработчик, можно найти шаблоны. Они представляют собой нечто очень сильно похожее на HTML страницы. Некоторые шаблоны, могут быть полноценными страницами (с тэгами body, head, title, html) и выводяться полностью, а другие могут быть лиш шаблоном для вывода определенного div или таблицы, и будут выводиться в определенном месте другого более кропного шаблона.

Суть

Вся сложность понимания цикла {section} в том, что он не подчиняется здравой логике цикла for хотя и является его единственным аналогом в Smarty, у цикла {section} своя логика. Суть в том, что в заголовке цикла явно не задаются счётчики (переменные счётчиков), вроде $i = 0;, которые обычно в цикле используются в качестве ключей массива. Вместо счётчиков (ключей массива) тут название цикла определённое в параметре name, причём работает это только если указывать это название в квадратных скобках после имени итерируемого массива. Если просто так использовать это имя цикла (как счётчик), то ничего выведено не будет. Что бы получить текущий параметр счётчика (ключа массива) нужно использовать внутренние переменные цикла iteration, rownum и index. Обращаться к ним надо так {$smarty.section.customer.iteration}, {$smarty.section.customer.rownum} и {$smarty.section.customer.index} соответственно, где customer это название текущего цикла section определённое параметром name.

Переменные/свойства цикла

Секции так же имеют собственные переменные, которые содержат свойства секций. Они обозначаются так:

  • — текущий номер итерации цикла. Начинается с единицы.
  •  — счётчик цикла, счёт идёт с единицы, это синоним к свойству iteration, они работают одинаково.
  •  — счётчик цикла, счёт идёт с нуля. index используется для отображения текущего индекса массива, начиная с нуля (или с атрибута start, если он был указан) и увеличиваясь на единицу (или на значение атрибута step, если он был указан).
  •  — количество итераций, через которые пройдет эта секция. Это свойство может быть использовано как внутри, так и вне секции.
  •  — показывать или нет
  •  — последний номер индекса, по которому проходила итерация секции. Это свойство может быть использовано как внутри, так и вне секции.
  •  — параметр, который установлен в true, если текущая итерация секции является первой.
  •  — параметр, который установлен в true, если текущая итерация секции является последней.
  • используется для отображения предыдущего индекса цикла. На первой итерации он установлен в −1.
  • используется для отображения следующего индекса цикла. На последней итерации он всё же на единицу больше текущего (или на другое значение, если указан атрибут step).

Smarty 3 Overview

Rewritten for PHP 5

The Smarty 3 code base is a 100% rewrite, and contains many language features that do not
exist in PHP 4. This means Smarty 3 will NOT work with PHP 4. If you need
PHP 4 support, you will have to stick with Smarty 2 until you can upgrade PHP.

Design Goal

Smarty’s fundamental design goal remains the same: To separate application code from
the presentation. This implies that PHP is separated from the presentation.
A detailed explanation of why this is important can be found here.

New Lexer/Parser

Smarty has a new template parser, a real syntax lexer. This gives Smarty much finer
control over its template syntax. Things like in-template math,
line-precision error messages and recursive template functions are now possible.

PHP

$tpl = $smarty->createTemplate('my.tpl');
$tpl->assign('foo','bar');
$smarty->display($tpl); // or $tpl->display();

PHP

$data = new Smarty_Data;
$data->assign('foo','bar');
$smarty->display('my.tpl',$data);
$tpl = $smarty->createTemplate('my.tpl',$data);

PHP

$smarty->display('foo:bar.tpl');

or in a template call:

Smarty

{include file="foo:bar.tpl"}

Smarty will first look for a registered template resource named foo. If nothing is found, it
will check if a PHP stream is available. If foo://bar is available, Smarty
will use it to fetch the template. You can also use streams to call variables.
{$foo:bar} will use the foo://bar stream to get the template
variable.

Template Inheritance

Templates can now inherit from each other. You mark blocks of a template with
{block name=foo}{/block} tags, a template
can inherit with the {extend file=»my.tpl»} tag, and
then you can replace, change or append the blocked contents from the inheriting
template(s). Example:

parent .tpl

<html>
  <head>
  	<title>{block name=title}default title{/block}<title>
  </head>
  <body>
	{block name=body}default body{/block}
  </body>
</html>
<html>
  <head>
  	<title>My Child Title<title>
  </head>
  <body>
	My Child Body
  </body>
</html>

See more here.

«{» and «}» (Javascript) Auto-Escapement

In Smarty 2, you had to escape occurances of {} characters by
surrounding them with {literal}{/literal} blocks
or replacing them with {ldelim}{rdelim} tags.
With Smarty 3, the braces will be ignored so long as they are surrounded by white space.

javascript

<script>
   // the following braces are ignored by Smarty
   // since they are surrounded by whitespace
   function foobar {
	alert('foobar!');
   }
   // this one will need literal escapement
   {literal}
	function bazzy {alert('foobar!');}
   {/literal}
</script>

Variable Filters

The default template modifier feature of Smarty 2 has been replaced with variable
filters. A variable filter can be applied to the output of template variables globally.
We have pre, post, and output filters, now we have a fourth choice: ‘variable’.
When you apply the filter such as:

PHP

$smarty->registerFilter('variable','htmlspecialchars');

then all output from variables is HTML escaped. You can also selectively disable
this in-line with {$foo nofilter}.

In-Template Function Definitions

You can create functions within a template and call them just like a plugin
function. When you have a plugin that generates presentational content, keeping
it in the template is often a more manageable choice. It also simplifies
data traversal, such as deeply nested menus. Example:

Smarty

{* define the function *}
{function name=menu level=0}
  <ul class="level{$level}">
  {foreach $data as $entry}
    {if is_array($entry)}
      <li>{$entry@key}</li>
      {menu data=$entry level=$level+1}
    {else}
      <li>{$entry}</li>
    {/if}
  {/foreach}
  </ul>
{/function}

{* create an array to demonstrate *}
{$menu = ],'item4']}

{* run the array through the function *}
{menu data=$menu}

Backward-Compatibility with Smarty 2

Much of Smarty 3 is backward compatible with Smarty 2, except for the items noted in the
SMARTY2_BC_NOTES
file included with the Smarty 3 distribution. Please see that file for a detail breakdown of BC differences.

Примеры

Примеры использования Smarty цикла .

Пример 1

PHP:

<?php
$data = array(1000, 1001, 1002);
$smarty->assign('custid', $data);
?>

Smarty:
Этот пример напечатает все значения массива :

{section name=customer loop=$custid}
    id: {$custid}<br>
{/section}

Этот пример напечатает все значения массива в обратном порядке:

{section name=foo loop=$custid step=-1}
    {$custid}<br>
{/section}

Пример 2

{section name=foo start=10 loop=20 step=2}
    {$smarty.section.foo.index}
{/section}
{section name=bar loop=21 max=6 step=-2}
    {$smarty.section.bar.index}
{/section}

Пример 3

Выводим элементы массива . Если элемент последний, то выводим немного иначе (без ссылки). Последний элемент проверяем равенством текущего значения счётчика с общим количеством элементов в массиве.

{section name=section1 loop=$aBreadCrumbs}
	{if $smarty.section.section1.rownum != count($aBreadCrumbs)}
		<li><a href="{$aBreadCrumbs}">{$aBreadCrumbs}</a></li>
	{else}
		<li>{$aBreadCrumbs}</li>
	{/if}
{/section}

Тоже самое, что и в предыдущим примере, только последний элемент проверяем специальным свойством текущего цикла section.

{section name=section1 loop=$aBreadCrumbs}
	{if !$smarty.section.section1.last}
		<li><a href="{$aBreadCrumbs}">{$aBreadCrumbs}</a></li>
	{else}
		<li>{$aBreadCrumbs}</li>
	{/if}
{/section}

Разбитие элементов массива на две колонки списков:

  {section name=section1 loop=$aSomeItems}
  {if $smarty.section.section1.first}
  <div class="col-md-6">
	<ul class="list-unstyled">
  {/if}
		<li><a href="{$aSomeItems}" title="{$aSomeItems}">{$aSomeItems}</a></li>
  {if $smarty.section.section1.iteration == count($aSomeItems)/2}
    </ul>
  </div>
  <div class="col-md-6">
	<ul class="list-unstyled">
    {/if}
	{if $smarty.section.section1.last}
    </ul>
  </div>
  {/if}
  {/section}

Тоже самое, но более грамоздко:

{section name=section1 loop=$aSomeItems}
{if $smarty.section.section1.iteration == 1}
<div class="col-md-6">
<ul class="list-unstyled">
{/if}
{if $smarty.section.section1.iteration <= count($aSomeItems)/2}
	<li><a href="{$aSomeItems}" title="{$aSomeItems}">{$aSomeItems}</a></li>
{/if}
{if $smarty.section.section1.iteration == count($aSomeItems)/2}
</ul>
</div>
<div class="col-md-6">
<ul class="list-unstyled">
{/if}
	{if $smarty.section.section1.iteration > count($aSomeItems)/2}
	<li><a href="{$aSomeItems}" title="{$aSomeItems}">{$aSomeItems}</a></li>
	{/if}
{if $smarty.section.section1.iteration -1 == count($aSomeItems)}
</ul>
</div>
{/if}
{/section}

Пример кода

HTML-страница с тегами Smarty:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
   <title>{$title_text}</title>
   <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>

<body> {* Комментарий, которого не будет в HTML коде *}

<p>{$body_text}</p>

</body><!-- Комментарий, который будет в HTML коде -->
</html>

Логика работы в PHP-скрипте ниже:

define('SMARTY_DIR', 'smarty-2.6.22/' );
require_once(SMARTY_DIR . 'Smarty.class.php');

$smarty = new Smarty();
$smarty->template_dir = './templates/';
$smarty->compile_dir = './templates/compile/';
$smarty->cache_dir = './templates/cache/';
$smarty->caching = false;
$smarty->error_reporting = E_ALL; // LEAVE E_ALL DURING DEVELOPMENT
$smarty->debugging = true;

$smarty->assign('title_text', 'TITLE: Пример использования Smarty ...');
$smarty->assign('body_text', 'BODY: Это текст, выведенный ф-цией assign()');

$smarty->display('index.tpl');

Модификаторы переменных

Это вообще говоря не простая тема, и спокойно может занять целую статью, а не кусочек в конце, но я расскажу основные постулаты. В Smarty есть модификаторы переменных, это некие функции, которые могут преобразовать значение переменной в нужный формат, либо выдать какой-то результат. Так, например, есть модификатор number_format, которые как и функция в PHP преобразовывает число так, чтобы оно могло принимать либо вид валюты, либо целочисленной записи, либо десятичной дроби; или модификатор count для массивов, который возвращает количество элементов массива прямо в шаблоне, для дальнейших действий из шаблона, без PHP.

	{$my_text|my_modifier:params}

В Smarty есть встроенные модификаторы, многие из которых повторяют функции PHP. Но есть возможность добавлять и собственные модификаторы, которые программирует программист и дает возможность использовать верстальщикам.
Как видно из примера, модификатор Smarty вызывается прямым слешем и названием модификатора, а потом через двоеточие записыаются параметры модификатора.
Именно на технологии модификатор пееменных (между тем, встроенной в движок Smarty) и работает форматирование даты из предшествующей статьи.

483

Sample Application: Guestbook

This is an example of a full working PHP application using Smarty. The purpose of this example is to demonstrate how Smarty ties in with an application and how to separate your presentation. Once you understand the concepts of presentation separation, you should be able to apply them to any type of programming pattern. With that said, you may use the following code at your own discretion, and at your own risk.

You can download the source of this Sample Application here.
This is not a guide on how to setup Apache or MySQL. Be sure you know these things or have handy references to them. If you are using alternatives, you will need to make appropriate adjustments in the code.

We will be building a guestbook where users can sign it or view it. There is no administration interface. We will be covering a few programming topics that involve Smarty such as form processing and database data retrieval and display.

This example extends the guestbook application setup given in the installation guide for Smarty, so we’ll build on top of that. Here are the files we’ll start with for our app:

guestbook app files/directories

/web/www.example.com/docs/
/web/www.example.com/docs/guestbook/
/web/www.example.com/docs/guestbook/index.php

/web/www.example.com/smarty/guestbook/
/web/www.example.com/smarty/guestbook/templates/
/web/www.example.com/smarty/guestbook/templates_c/
/web/www.example.com/smarty/guestbook/configs/
/web/www.example.com/smarty/guestbook/cache/

/web/www.example.com/smarty/guestbook/libs/
/web/www.example.com/smarty/guestbook/libs/guestbook_setup.php
/web/www.example.com/smarty/guestbook/libs/guestbook.lib.php

Lets go over each one:

/web/www.example.com/docs/

The /docs/ directory is our web server document root.

/web/www.example.com/docs/guestbook/

/guestbook/ is the subdirectory where our application is accessed by the browser.

/web/www.example.com/docs/guestbook/index.php

index.php will be the entry point of our application. The web browser will be accessing this script directly via http://www.example.com/guestbook/index.php.

/web/www.example.com/smarty/guestbook/

This is the directory we will keep all files for our guestbook app that do not need to be under doc root. Whether you choose to keep files under doc root is up to you, but for this example we follow the practice of putting only files directly accessed by the browser there. You could also use Apache .htaccess or other dedicated server means to stop direct access to application files under doc root.

/web/www.example.com/smarty/guestbook/templates/

This where we will put our Smarty template files.

/web/www.example.com/smarty/guestbook/templates_c/

This is where Smarty places its compiled template files. If you installed this correctly, the web server user running PHP has write access here. You should not manipulate files in this directory, they are generated by Smarty.

/web/www.example.com/smarty/guestbook/configs/

This is where we keep config files for our application. Config files are a place to store information that you want accessible from either the templates or the application. These are not PHP scripts, they are text files parsed by the Smarty config file parser.

/web/www.example.com/smarty/guestbook/cache/

This is where Smarty puts its cache files. This directory is only used if Smarty caching features are enabled. If you installed this correctly, the web server user running PHP has write access here. You should not manipulate files in this directory, they are generated by Smarty.

/web/www.example.com/smarty/guestbook/libs/

/libs/ is the directory we’ll keep our main application files.

/web/www.example.com/smarty/guestbook/libs/guestbook_setup.php

guestbook_setup.php is where we’ll keep some basic initialization information for our application.

/web/www.example.com/smarty/guestbook/libs/guestbook.lib.php

guestbook.lib.php is where we’ll keep the bulk of our application logic.

Основной синтаксис Smarty

Smarty понимает не только переменные, но и классы, массивы, функции и даже операторы. Если тебе эти слова ничего не говорят, не переживай, это программистские термины.
Все переменные/действия/все_что_угодно в Smarty записываються в фигурных скобках:

{something smartious}

Любая запись в шаблоне, в фигурных скобках будет обработано движком Smarty, и при необходимости фигурные скобки будут заменены обработанным содержимым, либо сработает условие либо цикл, но что-то 100% произойдет.Переменные в Smarty записываються с предшествующим знакомо доллара (при этом имя переменной задаётся в программной части, программистом, и для нас это не важно (возможно в следующих статьях, затрону теме бек-енда Smarty)

{$some_smarty_variable}

Классы в Smarty представляются так же как и в чистом PHP:

{$some_smarty_class->some_class_element}

Класс — это как большая переменная, которая может хранить в себе много других переменных и даже функций. Их структуру должен знать разработчик.Массивы в Smarty не очень сильно отличаются от классов, а синтаксически выглядят вот так:

{$some_smarty_array.some_smarty_array_element}

Smarty поддерживает циклы 2-х типов, итерационные и перебирающие. Чаще всего нужно именно перебирать какой-то массив (например, вывести список всех комментариев на странице). Для таких случаев есть оператор foreach.

	{foreach from=$some_array item="my_item" name="foreach_name" key="my_key"}

{$my_key}){$my_item.title} — {$my_item.text}

{/foreach}

Эта запись выведет список дивов, с индексом записи, именем комментатора и текстом комментария. foreach принимает несколько параметров:from – переменная-массив, который будет обрабатываться перебиромitem – название переменной, в которой будет храниться текущий елемент перебораname — название цикла-перебора, в дальнейшем в любом месте Smarty можно обратиться к этому циклу, узнать его текущий индекс, обратиться к его элементам и т.п. при помощи конструкции:

{$smarty.foreach.foreach_name...}

Есть еще циклы Section которые принимают численные значение начало, шаг, и конец цикла, и просто последовательно прибываляют к началу шаг, до тех пор, поку не наступит конец цикла.
Очень интересно, что в Smarty есть директива foreachelse, которая срабатывает в том случае, если массив для обхода пуст:

	{foreach from=$list item='my_item'}

{$my_item}

{foreachelse} нет записей {/foreach}

Условия в Smarty. Часто бывает необходимо делать логические ветвления, например, для вывода формы входа или и имени пользователя, в зависимости от того, вошел он уже в систему или нет. Для этогу в Smarty есть отличный инструмент:

	{if $action=='hello'}

привет

{elseif count($actions)<1}

нет ни одного действия

{else} действие не определено {/if}

В целом все просто и логично. Можно использовать любую косбинацию страктор из примера выше. А еще очень приятно то, что в Smarty встроены все функции PHP, которые ты можешь легко использовать при логическом ветвелнии, такие как isset, is_array и т.п.

Аналоги

Начиная с 2008 года доступен последователь синтаксиса Smarty, шаблонизатор Quicky основной отличительной особенностью которого является иной подход к реализации разбора шаблонов (который по заверениям автора существенно быстрее работает) и расширение уже привычного многим синтаксиса: поддержка хелперов (функций, объявленных прямо в шаблоне), наличие «магических» констант циклов, упрощенный синтаксис присвоения значений переменных без использования {math}, компилируемые управляющие конструкции.

Интересным развитием идей Smarty является библиотека Twig, которую развивает и поддерживает Fabien Potencier, ведущий разработчик и идеолог Symfony.

Smarty-подобный синтаксис имеют также такие обработчики шаблонов, как Dwoo или обработчик, встроенный в eZ Publish / ezComponents (англ.).

До 2007 года также развивался «облегчённый» форк Smarty — Template Lite (в первых версиях Smarty Light).

Оцените статью
Рейтинг автора
5
Материал подготовил
Андрей Измаилов
Наш эксперт
Написано статей
116
Добавить комментарий