Merge branch 'master' into develop

Conflicts:
	docs/ru/syntax.md
	sandbox/fenom.php
This commit is contained in:
bzick 2015-01-02 22:48:56 +03:00
commit bc73e5b733
20 changed files with 184 additions and 95 deletions

View File

@ -1,6 +1,24 @@
Changelog
=========
## 2.3.0 (2014-08-08)
- Add tags {set} and {add}
- Fix bug #97
- ++Docs
- --Bugs
- ++Tests
### 2.2.1 (2014-07-29)
- ++Docs
- --Bugs
## 2.2.0 (2014-07-11)
- Add new modifiers: match, ematch, replace, ereplace, split, esplit, join
- ++Docs
- ++Tests
### 2.1.2 (2014-07-03)
- Add test for bug #86

View File

@ -6,7 +6,7 @@ Fenom - Template Engine for PHP
[![Latest Stable Version](https://poser.pugx.org/fenom/fenom/v/stable.png)](https://packagist.org/packages/fenom/fenom)
[![Build Status](https://travis-ci.org/bzick/fenom.svg?branch=master)](https://travis-ci.org/bzick/fenom)
[![Coverage Status](https://coveralls.io/repos/bzick/fenom/badge.png?branch=master)](https://coveralls.io/r/bzick/fenom?branch=master)
[![Coverage Status](https://img.shields.io/coveralls/bzick/fenom.svg)](https://coveralls.io/r/bzick/fenom?branch=master)
[![Total Downloads](https://poser.pugx.org/fenom/fenom/downloads.png)](https://packagist.org/packages/fenom/fenom)
## [Quick start](./docs/en/start.md) :: [Documentation](./docs/readme.md) [[en](./docs/en/readme.md)|[ru](./docs/ru/readme.md)] :: [Benchmark](./docs/en/benchmark.md)
@ -14,7 +14,7 @@ Fenom - Template Engine for PHP
### What is it
**Fenom** *(from "fenomenal")* — lightweight template engine for PHP.
**Fenóm** — lightweight template engine for PHP.
It means:

View File

@ -1,5 +0,0 @@
Git conversation
================
Ветка `master` содержит стабильную последнюю версию проекта. В ветку `master` может сливаться новая версия проекта из `develop` или исправления.
Ветка `develop`, для разработки, содержит не стабильную версию проекта. Принимает все новшевства, изменения и исправления.

View File

@ -1,12 +1,15 @@
Develop
=======
If you want to discuss the enhancement of the Fenom, create an issue on Github or submit a pull request.
If you want to contribute to Fenom please feel free to create an issue or submit a pull request on Github.
There tho branches — master and develop.
The branch master for stable releases and hotfixes; the branch develop for development of features. Each tag names by rule `major.minor.fix` (1.4.9, 1.1.2 etc) and creates from master. Version changes by the rule of [semantic versioning](http://semver.org/).
There are two branches:
* `master` branch is for stable releases and hotfixes
* `develop` branch is for development of features
Each tag names by rule `major.minor.fix` (1.4.9, 1.1.2, etc.) and creates from master. Version changes by the rule of [semantic versioning](http://semver.org/).
For questions: a.cobest@gmail.com (English, Russian languages)
* the [scheme of work](schema.md)
* the [scheme of work](schema.md)

View File

@ -37,7 +37,7 @@ How it work
## Процесс работы
При вызове метода `Fenom::display($template, $vars)` шаблонизатор [ищет](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L712) в своем хранилище уже загруженный шаблон.
Если шаблона [нет](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L727) - либо [загружает](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L762) код шаблона с файловой системыб либо [инициирует](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L759) его [компиляцию](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L788).
Если шаблона [нет](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L727) - либо [загружает](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L762) код шаблона с файловой системы, либо [инициирует](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L759) его [компиляцию](https://github.com/bzick/fenom/blob/1.2.2/src/Fenom.php#L788).
### Компиляция шаблонов
@ -64,7 +64,7 @@ How it work
### Как работает токенайзер
Объек токенайзера принимает на вход любую строчку и разбирает ее при помощи функции token_get_all(). Полученные токен складываются в массив. Каждый токен прдсатвляет из себя числовой массив из 4-х элементов:
Объект токенайзера принимает на вход любую строчку и разбирает ее при помощи функции token_get_all(). Полученные токен складываются в массив. Каждый токен прдсатвляет из себя числовой массив из 4-х элементов:
* Код токена. Это либо число либо один символ.
* Тело токена. Содержимое токена.

View File

@ -4,7 +4,6 @@
# Добавление тегов
В шаблонизаторе принято различать два типа тегов: омпиляторы_ и ункции_.
Compilers invokes during compilation template to PHP source and have to
Компиляторы вызываются во время преобразования кода шаблона в PHP код и возвращяю PHP код который будет вставлен вместо тега.
А функции вызываются непременно в момент выполнения шаблона и возвращают непосредственно данные которые будут отображены.
Среди тегов как и в HTML есть строчные и блоковые теги.
@ -17,7 +16,7 @@ Compilers invokes during compilation template to PHP source and have to
$fenom->addFunction(string $function_name, callable $callback[, callable $parser]);
```
В данном случае запускается стандартный парсер, который автоматически разберет аргументы тега, которые должны быть в формате HTML аттрибутов и отдаст их в функцию ассоциативным массивом:
В данном случае запускается стандартный парсер, который автоматически разберет аргументы тега, которые должны быть в формате HTML атрибутов и отдаст их в функцию ассоциативным массивом:
```php
$fenom->addFunction("some_function", function (array $params) { /* ... */ });
```
@ -39,10 +38,10 @@ public static function calc($x, $y = 5) { /* ... */}
// ...
$fenom->addFunctionSmart('calc', 'XYCalcs::calc');
```
then
пример выше позволяет объявить тег `{calc}` и спользовать его:
```smarty
{calc x=$top y=50} or {calc y=50 x=$top} is XYCalcs::calc($top, 50)
{calc x=$top} or {calc $top} is XYCalcs::calc($top)
{calc x=$top y=50} или {calc y=50 x=$top} вызовет XYCalcs::calc($top, 50)
{calc x=$top} или {calc $top} вызовет XYCalcs::calc($top)
```
Таким образом вы успешно можете добавлять Ваши функции или методы.
@ -56,7 +55,7 @@ $fenom->addBlockFunction(string $function_name, callable $callback[, callable $p
Сам коллбек принимает первым аргументом контент между открывающим и закрывающим тегом, а вторым аргументом - ассоциативный массив из аргуметов тега:
```php
$fenom->addBlockFunction('some_block_function', function ($content, array $params) { /* ... */});
$fenom->addBlockFunction('some_block_function', function (array $params, $content) { /* ... */});
```
## Линейный компилятор
@ -100,7 +99,7 @@ $fenom->addModifier(string $modifier, callable $callback);
* `$modifier` - название модификатора, которое будет использоваться в шаблоне
* `$callback` - коллбек, который будет вызван для изменения данных
For example:
Например:
```smarty
{$variable|my_modifier:$param1:$param2}
@ -145,8 +144,8 @@ $fenom->addAccessor('project', function (Fenom\Tokenizer $tokens) { /* code */ }
который считывает шаблоны из указанной директории.
Источник шаблонов должен реализовать интерфейс `Fenom\ProviderInterface`.
Используйте метод `$fenom->setProvider(...)` что бы добавить источник в шаблонизатор, указав навание источника и, если есть необходимость,
задать директорию кеша для шаблонов из этого источника. Рассмотрим на примере, реализуем источик шаблонов из базы данных.
Используйте метод `$fenom->setProvider(...)` что бы добавить источник в шаблонизатор, указав название источника и, если есть необходимость,
задать директорию кеша для шаблонов из этого источника. Рассмотрим на примере, реализуем источник шаблонов из базы данных.
Создадим источник:
@ -178,11 +177,11 @@ $fenom->display("db:index.tpl", $vars);
# Расширение кеша (эксперементальное)
Изначально Fenom не расчитывался на то что кеш скомпиленых шаблонов может располагаться не на файловой системе.
Изначально Fenom не рассчитывался на то что кеш скомпиленых шаблонов может располагаться не на файловой системе.
Однако, в теории, есть возможность реализовать свое кеширование для скомпиленых шаблонов без переопределения шаблонизатора.
Речь идет о своем протоколе, отличным от `file://`, который [можно определить](http://php.net/manual/en/class.streamwrapper.php) в PHP.
Ваш протол должени иметь класс реализации протокола как указан в документации [Stream Wrapper](http://www.php.net/manual/en/class.streamwrapper.php).
Ваш протокол должен иметь класс реализации как указано в документации [Stream Wrapper](http://www.php.net/manual/en/class.streamwrapper.php).
Класс протокола может иметь не все указанные в документации методы. Вот список методов, необходимых шаблонизатору:
* [CacheStreamWrapper::stream_open](http://www.php.net/manual/en/streamwrapper.stream-open.php)
@ -190,14 +189,14 @@ $fenom->display("db:index.tpl", $vars);
* [CacheStreamWrapper::stream_close](http://www.php.net/manual/en/streamwrapper.stream-close.php)
* [CacheStreamWrapper::rename](http://www.php.net/manual/en/streamwrapper.rename.php)
For `include`:
Для работы через `include`:
* [CacheStreamWrapper::stream_stat](http://www.php.net/manual/en/streamwrapper.stream-stat.php)
* [CacheStreamWrapper::stream_read](http://www.php.net/manual/en/streamwrapper.stream-read.php)
* [CacheStreamWrapper::stream_eof](http://www.php.net/manual/en/streamwrapper.stream-eof.php)
**Note**
(On 2014-05-13) Zend OpCacher кроме `file://` и `phar://` не поддеривает другие протоколы.
(On 2014-05-13) Zend OpCacher кроме `file://` и `phar://` не поддерживает другие протоколы.
Пример работы кеша

View File

@ -1,4 +1,4 @@
Наследование шаблонов
=====================
Документации пока нет, почитайте на хабре пока
Документации пока нет, [почитайте на хабре](http://habrahabr.ru/post/169525/) пока

View File

@ -7,7 +7,7 @@
* `-$a` - отрицание знака, смена знака `$a`.
* `$a + $b` - сложение, сумма `$a` и `$b`.
* `$a - $b` - вычитаение, разность `$a` и `$b`.
* `$a - $b` - вычитание, разность `$a` и `$b`.
* `$a * $b` - умножение, произведение `$a` и `$b`.
* `$a / $b` - деление, частное от деления `$a` на `$b`.
* `$a % $b` - деление по модулю, целочисленный остаток от деления `$a` на `$b`.
@ -64,13 +64,13 @@
| Тип операнда 1 | Тип операнда 2 | Результат |
|-------------------|-------------------|-----------|
| null или string | string | NULL преобразуется в "", числовое или лексическое сравнение |
| bool или null | что угодно | Преобразуется в bool, FALSE < TRUE |
| object | object | Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, объекты одного класса - сравниваются свойства тем же способом, что и в массивах |
| string или number | string или number | Строки переводятся в числа, обычная математика |
| array | array | Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений |
| object | что угодно | object всегда больше |
| array | что угодно | array всегда больше |
| null или строка | строка | NULL преобразуется в "", числовое или лексическое сравнение |
| булев или null | что угодно | Преобразуется в bool, FALSE < TRUE |
| объект | объект | Встроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, объекты одного класса - сравниваются свойства тем же способом, что и в массивах |
| строка или число | строка или число | Строки переводятся в числа, обычная математика |
| массив | массив | Массивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений |
| объект | что угодно | object всегда больше |
| массим | что угодно | array всегда больше |
### Побитовые операторы
@ -129,7 +129,7 @@ Fenom поддерживает префиксные и постфиксные о
### Строковые операторы
Оператор конкатенации `~` возвращает строку, представляющую собой соединение левого и правого аргумента.
Оператор объединения `~` возвращает строку, представляющую собой соединение левого и правого аргумента.
* `$a ~ $b` - возвращает результат объединения сток `$a` и `$b`
* `$a ~~ $b` - возвращает результат объединения сток `$a` и `$b` через пробел
@ -177,7 +177,7 @@ Fenom поддерживает префиксные и постфиксные о
{$request.action !: 'default'}
```
Как видно, оператор `:?` более расширенный чем `:!` и включает в себя функциональность опертора `!:`.
Как видно, оператор `:?` более расширенный чем `:!` и включает в себя функциональность оператора `!:`.
Для упрощения понимания можно подвести итог:
@ -196,7 +196,7 @@ Fenom поддерживает префиксные и постфиксные о
### Операторы проверки
Оператор проверки это упрощенный тернарный оператор от которого осталась только часть проверки без возвращаемых вариантов.
Суть операторов — быстро произвести проверку на не пустое занчение и существование пременной.
Суть операторов — быстро произвести проверку на не пустое значение и существование пременной.
* `$a?` - вернет `TRUE` если `$a` не пустое
* `$a!` - вернет `TRUE` если `$a` существует
@ -208,7 +208,7 @@ Fenom поддерживает префиксные и постфиксные о
### Оператор тестирования
Оператор `is` производит тесты над перменными или выражением. Левый операнд считается тестируемым, а правый операнд — название теста:
Оператор `is` производит тесты над переменными или выражением. Левый операнд считается тестируемым, а правый операнд — название теста:
```smarty
{* проверка переменной на не четность *}
@ -219,7 +219,7 @@ Fenom поддерживает префиксные и постфиксные о
Результат тестирования может быть инвертирован с помощью `is not` оператора:
```smarty
{* проверяем переменную что ее значение не явдяется числом *}
{* проверяем переменную что ее значение не является числом *}
{$a is not integer}
```
@ -236,7 +236,7 @@ Fenom поддерживает префиксные и постфиксные о
* `string` — строка
* `callback`, `callable` — функция
* `number`, `numeric` — число, в общем понимании
* `$a is iterable` - тестирует переменную на возможность итеративного обхода.
* `$a is iterable` - тестирует переменную на возможность итеративного обхода (для `foreach`).
* `$a is template` - переменная `$a` содержит название существующего шаблона.
* `$a is empty` - переменная пустая.
* `$a is set` - переменная существует.
@ -247,7 +247,7 @@ Fenom поддерживает префиксные и постфиксные о
### Оператор присутствия
Оператор `in` проверяет присутвие скалярного значения слева в массиве или строке справа.
Оператор `in` проверяет присутствие скалярного значения слева в массиве или строке справа.
Результат тестирования может быть инвертирован с помощью `not ni` оператора.
* `$a in list $b` - значение `$a` содержится в массиве значений `$b`
@ -255,10 +255,10 @@ Fenom поддерживает префиксные и постфиксные о
* `$a in string $b` - значение `$a` содержится в `$b` как подстрока.
* `$a in $b` - значение `$a` содержится в `$b`, где `$b` может быть строкой, обычным или ассоциативным массивом.
Этот вариант долгий так как требуется проверить типы переменной `$b`.
Однако если вместо $b явно задан массив иили строка то оператор сам адаптируется для быстрого поиска.
Однако если вместо $b явно задан массив или строка то оператор сам адаптируется для быстрого поиска.
```smarty
{'df' in 'abcdefg'}
{5 in [1, 5, 25, 125]}
{99 in keys [1, 5, 25, 99 => 125]}
```
```

View File

@ -1,6 +1,10 @@
Документация
=============
<img style="float:right" src="http://aco.oml.ru/thumb/2Tdrgd9_ttbaBvqKcsSKIA/100r100/188321/gif-%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0-grammar-nazi-412594.jpg" alt="grammar nazi required">
**Внимание! Документация в режиме беты, тексты могут содержать опечатки**
### Fenom
* [Быстрый старт](./start.md)

View File

@ -5,7 +5,7 @@
### Composer
Fenom зарегестирован на [packagist.org](https://packagist.org/) как пакет [fenom/fenom](https://packagist.org/packages/fenom/fenom).
Fenom зарегистрирован на [packagist.org](https://packagist.org/) как пакет [fenom/fenom](https://packagist.org/packages/fenom/fenom).
Что бы установить Fenom через composer пропишите в `composer.json` списке пакетов:
```json
{
@ -16,15 +16,15 @@ Fenom зарегестирован на [packagist.org](https://packagist.org/)
```
и обновите зависимости: `composer update`.
### Custom loader
### Произвольная подгрузка
Склонируйте Fenom в любую директорию Вашего проекта: `git clone https://github.com/bzick/fenom.git`. Рекомендуется использовать последнюю версию.
Клонируйте Fenom в любую директорию Вашего проекта: `git clone https://github.com/bzick/fenom.git`. Рекомендуется использовать последнюю версию.
Для загрузки классов Fenom использует [psr-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md#autoloading-standard) стандарт.
Таким образом вы можете:
* использовать Ваш загрузчик, который понимает `psr-0` формат для загрузки классов Fenom из директории `src/` с пространством имен `Fenom`.
* или использовать строенный загрузчик Fenom: `Fenom::registerAutoload();` для загрузки самого себя.
* использовать Ваш автозагрузчик, который понимает `psr-0` формат для загрузки классов Fenom из директории `src/` с пространством имен `Fenom`.
* или использовать встроенный автозагрузчик Fenom: `Fenom::registerAutoload();` для загрузки самого себя.
Так же вы можете использовать встроенный в Fenom загрузчик для загрузки других классов в `psr-0` формате наименования класса и файла:
Так же вы можете использовать встроенный в Fenom автозагрузчик для загрузки других классов в `psr-0` формате:
```php
Fenom::registerAutoload(PROJECT_DIR."/classes");
```
@ -66,7 +66,7 @@ $fenom->display("template/name.tpl", $vars);
$result = $fenom->fetch("template/name.tpl", $vars);
```
Для отрисовки большого количества данных можно использовать поток
Для вывода большого количества данных можно использовать поток
```php
// $fenom->pipe(string $template, array $variables, callable $callback, int $chunk_size) : void
@ -82,3 +82,29 @@ $fenom->pipe(
Поток позволяет обрабатывать большой результат по кускам, размер куска указывается в байтах аргументом `$chunk_size`.
Каждый кусок передается в `$callback` для обработки или вывода.
<!--
## Пример простого приложения
```
App/ (ROOT_DIR)
┠─ configs/ (файлы конфигурации приложения)
┠─ src/ (классы приложения)
┠─ templates/ (шаблоны приложения)
┠─ public/ (DOCUMENT_ROOT)
┃ ┠─ static/ (папка со статикой)
┃ ┖─ index.php (скрипт обработки всех динамических запросов)
┠─ tmp/ (папка доступная для записи web-серверу для хранения временных файлов)
┃ ┖─ compiled/ (кеша шаблонов)
┠─ vendor/ (строронние бибилиотеки)
┖─ composer.json (описание зависимостей для composer)
```
`index.php`:
```php
define('ROOT_DIR', dirname(__DIR__));
$fenom = Fenom::factory(ROOT_DIR.'/templates', ROOT_DIR.'/cache', Fenom::FORCE_VERIFY | Fenom::AUTO_RELOAD);
```
-->

View File

@ -49,20 +49,20 @@
```smarty
{set $v}
Some long {$text|trim}
{/var}
{/set}
```
Такой вариант создания позволяет применить модификаторы к данным переде тем как они будут сохранены в переменную:
Такой вариант создания позволяет применить модификаторы к данным перед тем как они будут сохранены в переменную:
```smarty
{set $v|escape} {* применение можификатора к значению *}
Some long {$text|trim}
{/var}
{/set}
```
### {add}
Тег {add} делает тоже самое что и тег {set} за исключением того что сначало проверяет наличие переменной и если переменной нет — задет новое значение.
Тег {add} делает тоже самое что и тег {set} за исключением того что сначала проверяет наличие переменной и если переменной нет — задет новое значение.
```smarty
{add $var = 'value'}
@ -78,4 +78,3 @@
Тег {var} старое название тега {set}, сейчас это одно и тоже.

View File

@ -1,2 +0,0 @@
Some eval:
{$dop_content = ": some texta"}

View File

@ -1,13 +0,0 @@
{extends 'extends/75-parent.tpl'}
{block 'child'}
{macro child_test(v, i)}
child test - {$v}, i = {$i};<br/>
{var $i = $i -1}
{if $i > 0}
{macro.child_test v=$v i=$i}
{/if}
{/macro}
child call: <br/>
{macro.child_test v = 'ok' i = 5}
{/block}

View File

@ -1,12 +0,0 @@
{macro parent_test(v, i)}
parent test - {$v}, i = {$i};<br/>
{var $i = $i -1}
{if $i > 0}
{macro.parent_test v=$v i=$i}
{/if}
{/macro}
{block 'child'}{/block}
parent call:<br/>
{macro.parent_test v = 'ok' i = 5} <br/>

View File

@ -0,0 +1,8 @@
<div class="footer">
<p>&copy; Company 2014</p>
</div>
</div> <!-- /container -->
</body>
</html>

View File

@ -1,7 +1,40 @@
{var:escape $a}
asdasd
{/var}
{include "header.tpl" title=""}
{*{Ts\Math::multi x=34 y=44}*}
{*{$a + Ts\Math::multi(34, 44)}*}
{*{34|Ts\Math::multi:44}*}
{import 'macros.tpl' as menu}
{menu.pills active='sandbox' items=$items}
<div class="jumbotron">
<h1>Jumbotron heading</h1>
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<p><a class="btn btn-lg btn-success" href="#" role="button">Sign up today</a></p>
</div>
<div class="row marketing">
{set $text}
<div class="col-lg-6">
<h4>Subheading</h4>
<p>Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.</p>
<h4>Subheading</h4>
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.</p>
<h4>Subheading</h4>
<p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
</div>
{/set}
{$text}
<div class="col-lg-6">
<h4>Subheading</h4>
<p>Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.</p>
<h4>Subheading</h4>
<p>Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.</p>
<h4>Subheading</h4>
<p>Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
</div>
</div>
{include "footer.tpl"}

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Bzick">
<title>{$title}</title>
<!-- Bootstrap core CSS -->
<link href="//yastatic.net/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//yastatic.net/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<!-- Custom styles for this template -->
<link href="jumbotron-narrow.css" rel="stylesheet">
</head>
<body>
<div class="container">

View File

@ -1,5 +1,14 @@
{macro factorial(num)}
{if $num}
{$num} {macro.factorial num=$num-1} {$num}
{/if}
{macro pills($title, $items, $active)}
<div class="header">
<ul class="nav nav-pills pull-right" role="tablist">
{foreach $items as $code => $item}
{if $code == $active}
<li role="presentation" class="{$code}"><a href="">{$item.name}</a></li>
{else}
<li role="presentation" class="active {$code}"><a href="{$item.url}">{$item.name}</a></li>
{/if}
{/foreach}
</ul>
<h3 class="text-muted">{$title}</h3>
</div>
{/macro}

View File

@ -193,7 +193,7 @@ class Template extends Render
$this->_src = call_user_func($filter, $this, $this->_src);
}
while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags
switch ($this->_src[$start + 1]) { // check next character
switch (substr($this->_src, $start + 1, 1)) { // check next character
case "\n":
case "\r":
case "\t":