mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Add checking nested level for {use} and {extends}
Add more docs
This commit is contained in:
parent
27d7110690
commit
c76f5c8be0
10
README.md
10
README.md
@ -1,12 +1,12 @@
|
|||||||
Fenom - awesome template engine for PHP
|
Fenom - Template Engine for PHP
|
||||||
==========================
|
===============================
|
||||||
|
|
||||||
> Composer package: `{"bzick/fenom": "dev-master"}`. See on [Packagist.org](https://packagist.org/packages/bzick/fenom)
|
> Composer package: `{"fenom/fenom": "dev-master"}`. See on [Packagist.org](https://packagist.org/packages/bzick/fenom)
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/bzick/fenom.png?branch=master)](https://travis-ci.org/bzick/fenom)
|
[![Build Status](https://travis-ci.org/bzick/fenom.png?branch=master)](https://travis-ci.org/bzick/fenom)
|
||||||
## [About](./docs/about.md) :: [Documentation](./docs/main.md) :: [Benchmark](./docs/benchmark.md) :: [Articles](./docs/articles.md)
|
## [Usage](./docs/usage.md) :: [Documentation](./docs/main.md) :: [Benchmark](./docs/benchmark.md) :: [Articles](./docs/articles.md)
|
||||||
|
|
||||||
* Simplest known [syntax](./docs/syntax.md)
|
* Simple [syntax](./docs/syntax.md)
|
||||||
* [Fast](./docs/benchmark.md)
|
* [Fast](./docs/benchmark.md)
|
||||||
* [Secure](./docs/settings.md)
|
* [Secure](./docs/settings.md)
|
||||||
* [Simple](./ideology.md)
|
* [Simple](./ideology.md)
|
||||||
|
@ -14,27 +14,27 @@ echo "Testing a lot output...\n";
|
|||||||
Benchmark::runs("smarty3", 'echo/smarty.tpl', __DIR__.'/templates/echo/data.json');
|
Benchmark::runs("smarty3", 'echo/smarty.tpl', __DIR__.'/templates/echo/data.json');
|
||||||
Benchmark::runs("twig", 'echo/twig.tpl', __DIR__.'/templates/echo/data.json');
|
Benchmark::runs("twig", 'echo/twig.tpl', __DIR__.'/templates/echo/data.json');
|
||||||
Benchmark::runs("fenom", 'echo/smarty.tpl', __DIR__.'/templates/echo/data.json');
|
Benchmark::runs("fenom", 'echo/smarty.tpl', __DIR__.'/templates/echo/data.json');
|
||||||
if(extension_loaded("phalcon")) {
|
//if(extension_loaded("phalcon")) {
|
||||||
Benchmark::runs("volt", 'echo/twig.tpl', __DIR__.'/templates/echo/data.json');
|
// Benchmark::runs("volt", 'echo/twig.tpl', __DIR__.'/templates/echo/data.json');
|
||||||
}
|
//}
|
||||||
|
|
||||||
echo "\nTesting 'foreach' of big array...\n";
|
echo "\nTesting 'foreach' of big array...\n";
|
||||||
|
|
||||||
Benchmark::runs("smarty3", 'foreach/smarty.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("smarty3", 'foreach/smarty.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
Benchmark::runs("twig", 'foreach/twig.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("twig", 'foreach/twig.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
Benchmark::runs("fenom", 'foreach/smarty.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("fenom", 'foreach/smarty.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
if(extension_loaded("phalcon")) {
|
//if(extension_loaded("phalcon")) {
|
||||||
Benchmark::runs("volt", 'foreach/twig.tpl', __DIR__.'/templates/foreach/data.json');
|
// Benchmark::runs("volt", 'foreach/twig.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
}
|
//}
|
||||||
|
|
||||||
echo "\nTesting deep 'inheritance'...\n";
|
echo "\nTesting deep 'inheritance'...\n";
|
||||||
|
|
||||||
Benchmark::runs("smarty3", 'inheritance/smarty/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("smarty3", 'inheritance/smarty/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
Benchmark::runs("twig", 'inheritance/twig/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("twig", 'inheritance/twig/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
Benchmark::runs("fenom", 'inheritance/smarty/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
Benchmark::runs("fenom", 'inheritance/smarty/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
if(extension_loaded("phalcon")) {
|
//if(extension_loaded("phalcon")) {
|
||||||
Benchmark::runs("volt", 'inheritance/twig/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
// Benchmark::runs("volt", 'inheritance/twig/b100.tpl', __DIR__.'/templates/foreach/data.json');
|
||||||
}
|
//}
|
||||||
|
|
||||||
echo "\nDone. Cleanup.\n";
|
echo "\nDone. Cleanup.\n";
|
||||||
//passthru("rm -rf ".__DIR__."/compile/*");
|
//passthru("rm -rf ".__DIR__."/compile/*");
|
||||||
|
@ -77,7 +77,7 @@ class Benchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function run($engine, $template, $data, $double, $message) {
|
public static function run($engine, $template, $data, $double, $message) {
|
||||||
passthru(sprintf("php -dmemory_limit=512M -dxdebug.max_nesting_level=1024 %s/run.php --engine '%s' --template '%s' --data '%s' --message '%s' %s", __DIR__, $engine, $template, $data, $message, $double ? '--double' : ''));
|
passthru(sprintf(PHP_BINARY." -dmemory_limit=512M -dxdebug.max_nesting_level=1024 %s/run.php --engine '%s' --template '%s' --data '%s' --message '%s' %s", __DIR__, $engine, $template, $data, $message, $double ? '--double' : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "bzick/fenom",
|
"name": "fenom/fenom",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"description": "Fenom - fast template engine for PHP",
|
"description": "Fenom - fast template engine for PHP",
|
||||||
"homepage": "http://bzick.github.io/fenom/",
|
"homepage": "http://bzick.github.io/fenom/",
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
About Fenom [RU]
|
|
||||||
================
|
|
||||||
|
|
||||||
Fenom - самый быстрый, гибкий и тонкий шаблонизатор для PHP, унаследовавший синтаксис от Smarty3 и улучшив его.
|
|
||||||
Пожалуй это единственный шаблонизатор, который не использет ни регулярные выражения, как Twig, ни лексер от BISON, как Smarty3.
|
|
||||||
Вы не найдёте ни одного регулярного выражения в ядре Fenom, но тем не менее ядро простое, компактное и очень быстрое.
|
|
||||||
|
|
||||||
* Скорость. Разбор шаблонов постоен на основе нативного [токенайзера](http://docs.php.net/tokenizer). Шаблон преобразуется в исполняемый PHP код,
|
|
||||||
который может быть закеширован на файловой системе.
|
|
||||||
* Безопасность. Разборщик шаблон кроптоливо проверяет каждый токен, тем самым не пропуская возможные уязвимоти и фатальные ошибки при исполнении шпблона.
|
|
||||||
* Гибкость. Любой компонент можно переопределить, по желанию.
|
|
@ -5,11 +5,11 @@ For installation use [composer](http://getcompoer.org). Add in your `composer.js
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"bzick/fenom": "dev-master"
|
"fenom/fenom": "dev-master"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
or use shell
|
or use shell
|
||||||
`composer require bzick/fenom`
|
`composer require fenom/fenom`
|
||||||
|
|
||||||
If you do not use composer - use `psr-0` format for loading Fenom's classes.
|
If you do not use composer - use `psr-0` format for loading Fenom's classes.
|
||||||
|
@ -1,22 +1,67 @@
|
|||||||
Operators
|
Operators
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Math
|
### Math
|
||||||
|
|
||||||
`+ - / *`
|
Operators: `+ - / *`
|
||||||
|
|
||||||
Bitwize
|
```smarty
|
||||||
|
{$a + $b * $c/$d - $e*5 + 1e3}
|
||||||
|
```
|
||||||
|
|
||||||
`| & << >> |= &= <<= >>=`
|
### Boolean
|
||||||
|
|
||||||
Unary
|
Operators: `|| && and or < > <= >= == === !== !=`
|
||||||
|
|
||||||
`^ ~ - !`
|
```smarty
|
||||||
|
{if $a && $b >= 5 && $c != 3} {/if}
|
||||||
|
```
|
||||||
|
|
||||||
Boolean
|
### Bitwize
|
||||||
|
|
||||||
`|| && and or < > <= >= == === !== !=`
|
Operators: `| & << >> |= &= <<= >>=`
|
||||||
|
|
||||||
Ternar
|
```smarty
|
||||||
|
{if $a & 1} {var $b |= $flags} {/if}
|
||||||
|
```
|
||||||
|
|
||||||
`? :`
|
### Unary
|
||||||
|
|
||||||
|
Operators: `^ ~ - !`
|
||||||
|
|
||||||
|
```smarty
|
||||||
|
{var $b |= $flags & ^$c}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ternar
|
||||||
|
|
||||||
|
Operators: `? :`
|
||||||
|
|
||||||
|
```smarty
|
||||||
|
{var $a = true}
|
||||||
|
{$a ? 5 : 10} {* outputs 5 *}
|
||||||
|
{var $a = false}
|
||||||
|
{$a ? 5 : 10} {* outputs 10 *}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variable operator
|
||||||
|
|
||||||
|
Checking variable value
|
||||||
|
```smarty
|
||||||
|
{if $a?} {* instead of {if !empty($a)} *}
|
||||||
|
```
|
||||||
|
|
||||||
|
Checking variable existence
|
||||||
|
```smarty
|
||||||
|
{if $a!} {* instead of {if isset($a)} *}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get default if variable is empty
|
||||||
|
```smarty
|
||||||
|
{$a?:"some text"} {* instead of {if empty($a) ? "some text" : $a} *}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get default if variable doesn't exist
|
||||||
|
```smarty
|
||||||
|
{$a!:"some text"} {* instead of {if isset($a) ? $a : "some text"} *}
|
||||||
|
```
|
||||||
|
@ -25,6 +25,7 @@ $fenom->setOptions($options);
|
|||||||
* **auto_reload**, `Fenom::AUTO_RELOAD`, пересобирать шаблон если его оригинал был изменён (замедляет работу шаблонизатора).
|
* **auto_reload**, `Fenom::AUTO_RELOAD`, пересобирать шаблон если его оригинал был изменён (замедляет работу шаблонизатора).
|
||||||
* **force_compile**, `Fenom::FORCE_COMPILE`, пересобирать шаблон при каждом вызове (сильно замедляет работу шаблонизатора).
|
* **force_compile**, `Fenom::FORCE_COMPILE`, пересобирать шаблон при каждом вызове (сильно замедляет работу шаблонизатора).
|
||||||
* **force_include**, `Fenom::FORCE_INCLUDE`, оптимизировать вставку шаблона в шаблон. Это увеличит производительность и размер собранного шаблона.
|
* **force_include**, `Fenom::FORCE_INCLUDE`, оптимизировать вставку шаблона в шаблон. Это увеличит производительность и размер собранного шаблона.
|
||||||
|
Опция активируется если имя шаблона задано явно и скалярно.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$fenom->setOptions(array(
|
$fenom->setOptions(array(
|
||||||
|
@ -1,20 +1,38 @@
|
|||||||
Basic usage
|
Basic usage
|
||||||
===========
|
===========
|
||||||
|
|
||||||
### Creating template engine
|
### Initialize Fenom
|
||||||
|
|
||||||
|
Use factory method
|
||||||
```php
|
```php
|
||||||
$fenom = Fenom::factory('/path/to/templates', '/path/to/template/cache', $options);
|
$fenom = Fenom::factory('/path/to/templates', '/path/to/compiled/template', $options);
|
||||||
|
```
|
||||||
|
|
||||||
//or
|
Use `new` operator
|
||||||
|
```php
|
||||||
$fenom = new Fenom(new FSProvider('/path/to/templates'));
|
$fenom = new Fenom(new Provider('/path/to/templates'));
|
||||||
$fenom->setCompileDir('/path/to/template/cache');
|
$fenom->setCompileDir('/path/to/template/cache');
|
||||||
$fenom->setOptions($options);
|
$fenom->setOptions($options);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Output template result
|
### Render template
|
||||||
|
|
||||||
|
Output template
|
||||||
```php
|
```php
|
||||||
$fenom->display("template/name.tpl", $vars);
|
$fenom->display("template/name.tpl", $vars);
|
||||||
|
```
|
||||||
|
|
||||||
|
Get template into the variable
|
||||||
|
```php
|
||||||
|
$result = $fenom->fetch("template/name.tpl", $vars);
|
||||||
|
```
|
||||||
|
|
||||||
|
Create pipe-line into callback
|
||||||
|
```php
|
||||||
|
$fenom->export(
|
||||||
|
"template/sitemap.tpl",
|
||||||
|
$vars,
|
||||||
|
$callback = [new SplFileObject("/tmp/sitemap.xml", "w"), "fwrite"], // pipe to file /tmp/sitemap.xml
|
||||||
|
$chunk_size = 1e6 // chunk size for callback
|
||||||
|
);
|
||||||
```
|
```
|
@ -23,7 +23,7 @@ class Compiler {
|
|||||||
* @static
|
* @static
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Template $tpl
|
* @param Template $tpl
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagInclude(Tokenizer $tokens, Template $tpl) {
|
public static function tagInclude(Tokenizer $tokens, Template $tpl) {
|
||||||
@ -68,12 +68,12 @@ class Compiler {
|
|||||||
* @static
|
* @static
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagElseIf(Tokenizer $tokens, Scope $scope) {
|
public static function tagElseIf(Tokenizer $tokens, Scope $scope) {
|
||||||
if($scope["else"]) {
|
if($scope["else"]) {
|
||||||
throw new ImproperUseException('Incorrect use of the tag {elseif}');
|
throw new InvalidUsageException('Incorrect use of the tag {elseif}');
|
||||||
}
|
}
|
||||||
return '} elseif('.$scope->tpl->parseExp($tokens, true).') {';
|
return '} elseif('.$scope->tpl->parseExp($tokens, true).') {';
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ class Compiler {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @throws UnexpectedTokenException
|
* @throws UnexpectedTokenException
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function foreachOpen(Tokenizer $tokens, Scope $scope) {
|
public static function foreachOpen(Tokenizer $tokens, Scope $scope) {
|
||||||
@ -132,7 +132,7 @@ class Compiler {
|
|||||||
while($token = $tokens->key()) {
|
while($token = $tokens->key()) {
|
||||||
$param = $tokens->get(T_STRING);
|
$param = $tokens->get(T_STRING);
|
||||||
if(!isset($p[ $param ])) {
|
if(!isset($p[ $param ])) {
|
||||||
throw new ImproperUseException("Unknown parameter '$param' in {foreach}");
|
throw new InvalidUsageException("Unknown parameter '$param' in {foreach}");
|
||||||
}
|
}
|
||||||
$tokens->getNext("=");
|
$tokens->getNext("=");
|
||||||
$tokens->next();
|
$tokens->next();
|
||||||
@ -197,7 +197,7 @@ class Compiler {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @return string
|
* @return string
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public static function forOpen(Tokenizer $tokens, Scope $scope) {
|
public static function forOpen(Tokenizer $tokens, Scope $scope) {
|
||||||
$p = array("index" => false, "first" => false, "last" => false, "step" => 1, "to" => false, "max" => false, "min" => false);
|
$p = array("index" => false, "first" => false, "last" => false, "step" => 1, "to" => false, "max" => false, "min" => false);
|
||||||
@ -218,7 +218,7 @@ class Compiler {
|
|||||||
$condition = "$var >= {$p['to']}";
|
$condition = "$var >= {$p['to']}";
|
||||||
if($p["last"]) $c = "($var + {$p['step']}) < {$p['to']}";
|
if($p["last"]) $c = "($var + {$p['step']}) < {$p['to']}";
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Invalid step value if {for}");
|
throw new InvalidUsageException("Invalid step value if {for}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$condition = "({$p['step']} > 0 && $var <= {$p['to']} || {$p['step']} < 0 && $var >= {$p['to']})";
|
$condition = "({$p['step']} > 0 && $var <= {$p['to']} || {$p['step']} < 0 && $var >= {$p['to']})";
|
||||||
@ -323,14 +323,14 @@ class Compiler {
|
|||||||
* @static
|
* @static
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagContinue($tokens, Scope $scope) {
|
public static function tagContinue($tokens, Scope $scope) {
|
||||||
if(empty($scope["no-continue"])) {
|
if(empty($scope["no-continue"])) {
|
||||||
return 'continue;';
|
return 'continue;';
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Improper usage of the tag {continue}");
|
throw new InvalidUsageException("Improper usage of the tag {continue}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,14 +358,14 @@ class Compiler {
|
|||||||
* @static
|
* @static
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagBreak($tokens, Scope $scope) {
|
public static function tagBreak($tokens, Scope $scope) {
|
||||||
if(empty($scope["no-break"])) {
|
if(empty($scope["no-break"])) {
|
||||||
return 'break;';
|
return 'break;';
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Improper usage of the tag {break}");
|
throw new InvalidUsageException("Improper usage of the tag {break}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,12 +373,14 @@ class Compiler {
|
|||||||
* Dispatch {extends} tag
|
* Dispatch {extends} tag
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Template $tpl
|
* @param Template $tpl
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagExtends(Tokenizer $tokens, Template $tpl) {
|
public static function tagExtends(Tokenizer $tokens, Template $tpl) {
|
||||||
if(!empty($tpl->_extends)) {
|
if(!empty($tpl->_extends)) {
|
||||||
throw new ImproperUseException("Only one {extends} allowed");
|
throw new InvalidUsageException("Only one {extends} allowed");
|
||||||
|
} elseif($tpl->getStackSize()) {
|
||||||
|
throw new InvalidUsageException("Tags {extends} can not be nested");
|
||||||
}
|
}
|
||||||
$tpl_name = $tpl->parsePlainArg($tokens, $name);
|
$tpl_name = $tpl->parsePlainArg($tokens, $name);
|
||||||
if(empty($tpl->_extended)) {
|
if(empty($tpl->_extended)) {
|
||||||
@ -446,10 +448,13 @@ class Compiler {
|
|||||||
* Tag {use ...}
|
* Tag {use ...}
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Template $tpl
|
* @param Template $tpl
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagUse(Tokenizer $tokens, Template $tpl) {
|
public static function tagUse(Tokenizer $tokens, Template $tpl) {
|
||||||
|
if($tpl->getStackSize()) {
|
||||||
|
throw new InvalidUsageException("Tags {use} can not be nested");
|
||||||
|
}
|
||||||
$cname = $tpl->parsePlainArg($tokens, $name);
|
$cname = $tpl->parsePlainArg($tokens, $name);
|
||||||
if($name) {
|
if($name) {
|
||||||
$donor = $tpl->getStorage()->getRawTemplate()->load($name, false);
|
$donor = $tpl->getStorage()->getRawTemplate()->load($name, false);
|
||||||
@ -469,11 +474,12 @@ class Compiler {
|
|||||||
$tpl->addDepend($donor);
|
$tpl->addDepend($donor);
|
||||||
return '?>'.$donor->getBody().'<?php ';
|
return '?>'.$donor->getBody().'<?php ';
|
||||||
} else {
|
} else {
|
||||||
$tpl->_compatible = true;
|
// throw new InvalidUsageException('template name must be given explicitly yet');
|
||||||
return '$donor = $tpl->getStorage()->getTemplate('.$cname.', \Fenom\Template::EXTENDED);'.PHP_EOL.
|
// under construction
|
||||||
|
$tpl->_compatible = true;
|
||||||
|
return '$donor = $tpl->getStorage()->getTemplate('.$cname.', \Fenom\Template::EXTENDED);'.PHP_EOL.
|
||||||
'$donor->fetch((array)$tpl);'.PHP_EOL.
|
'$donor->fetch((array)$tpl);'.PHP_EOL.
|
||||||
'$tpl->b += (array)$donor->b';
|
'$tpl->b += (array)$donor->b';
|
||||||
// throw new ImproperUseException('template name must be given explicitly');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,9 +488,13 @@ class Compiler {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @return string
|
* @return string
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public static function tagBlockOpen(Tokenizer $tokens, Scope $scope) {
|
public static function tagBlockOpen(Tokenizer $tokens, Scope $scope) {
|
||||||
|
if($scope->level > 0) {
|
||||||
|
var_dump("".$scope->tpl);
|
||||||
|
$scope->tpl->_compatible = true;
|
||||||
|
}
|
||||||
$scope["cname"] = $scope->tpl->parsePlainArg($tokens, $name);
|
$scope["cname"] = $scope->tpl->parsePlainArg($tokens, $name);
|
||||||
$scope["name"] = $name;
|
$scope["name"] = $name;
|
||||||
}
|
}
|
||||||
@ -553,7 +563,7 @@ class Compiler {
|
|||||||
|
|
||||||
public static function tagParent($tokens, Scope $scope) {
|
public static function tagParent($tokens, Scope $scope) {
|
||||||
if(empty($scope->tpl->_extends)) {
|
if(empty($scope->tpl->_extends)) {
|
||||||
throw new ImproperUseException("Tag {parent} may be declared in childs");
|
throw new InvalidUsageException("Tag {parent} may be declared in childs");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +720,7 @@ class Compiler {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Template $tpl
|
* @param Template $tpl
|
||||||
* @return string
|
* @return string
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public static function tagCycle(Tokenizer $tokens, Template $tpl) {
|
public static function tagCycle(Tokenizer $tokens, Template $tpl) {
|
||||||
if($tokens->is("[")) {
|
if($tokens->is("[")) {
|
||||||
@ -721,7 +731,7 @@ class Compiler {
|
|||||||
if($tokens->valid()) {
|
if($tokens->valid()) {
|
||||||
$p = $tpl->parseParams($tokens);
|
$p = $tpl->parseParams($tokens);
|
||||||
if(empty($p["index"])) {
|
if(empty($p["index"])) {
|
||||||
throw new ImproperUseException("Cycle may contain only index attribute");
|
throw new InvalidUsageException("Cycle may contain only index attribute");
|
||||||
} else {
|
} else {
|
||||||
return 'echo '.__CLASS__.'::cycle('.$exp.', '.$p["index"].')';
|
return 'echo '.__CLASS__.'::cycle('.$exp.', '.$p["index"].')';
|
||||||
}
|
}
|
||||||
@ -747,7 +757,7 @@ class Compiler {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Template $tpl
|
* @param Template $tpl
|
||||||
* @throws UnexpectedTokenException
|
* @throws UnexpectedTokenException
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function tagImport(Tokenizer $tokens, Template $tpl) {
|
public static function tagImport(Tokenizer $tokens, Template $tpl) {
|
||||||
@ -775,7 +785,7 @@ class Compiler {
|
|||||||
|
|
||||||
$tpl->parsePlainArg($tokens, $name);
|
$tpl->parsePlainArg($tokens, $name);
|
||||||
if(!$name) {
|
if(!$name) {
|
||||||
throw new ImproperUseException("Invalid usage tag {import}");
|
throw new InvalidUsageException("Invalid usage tag {import}");
|
||||||
}
|
}
|
||||||
if($tokens->is(T_AS)) {
|
if($tokens->is(T_AS)) {
|
||||||
$alias = $tokens->next()->get(Tokenizer::MACRO_STRING);
|
$alias = $tokens->next()->get(Tokenizer::MACRO_STRING);
|
||||||
@ -812,7 +822,7 @@ class Compiler {
|
|||||||
*
|
*
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param Scope $scope
|
* @param Scope $scope
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public static function macroOpen(Tokenizer $tokens, Scope $scope) {
|
public static function macroOpen(Tokenizer $tokens, Scope $scope) {
|
||||||
$scope["name"] = $tokens->get(Tokenizer::MACRO_STRING);
|
$scope["name"] = $tokens->get(Tokenizer::MACRO_STRING);
|
||||||
@ -832,7 +842,7 @@ class Compiler {
|
|||||||
if($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) {
|
if($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) {
|
||||||
$scope["defaults"][ $param ] = $tokens->getAndNext();
|
$scope["defaults"][ $param ] = $tokens->getAndNext();
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Macro parameters may have only scalar defaults");
|
throw new InvalidUsageException("Macro parameters may have only scalar defaults");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$tokens->skipIf(',');
|
$tokens->skipIf(',');
|
||||||
|
@ -106,6 +106,14 @@ class Template extends Render {
|
|||||||
$this->_options = $options;
|
$this->_options = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get tag stack size
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getStackSize() {
|
||||||
|
return count($this->_stack);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load source from provider
|
* Load source from provider
|
||||||
* @param string $name
|
* @param string $name
|
||||||
@ -408,7 +416,7 @@ class Template extends Render {
|
|||||||
} else {
|
} else {
|
||||||
return $code = "echo ".$this->parseExp($tokens).";";
|
return $code = "echo ".$this->parseExp($tokens).";";
|
||||||
}
|
}
|
||||||
} catch (ImproperUseException $e) {
|
} catch (InvalidUsageException $e) {
|
||||||
throw new CompileException($e->getMessage()." in {$this} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $e);
|
throw new CompileException($e->getMessage()." in {$this} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $e);
|
||||||
} catch (\LogicException $e) {
|
} catch (\LogicException $e) {
|
||||||
throw new SecurityException($e->getMessage()." in {$this} line {$this->_line}, near '{".$tokens->getSnippetAsString(0,0)."' <- there", 0, E_ERROR, $this->_name, $this->_line, $e);
|
throw new SecurityException($e->getMessage()." in {$this} line {$this->_line}, near '{".$tokens->getSnippetAsString(0,0)."' <- there", 0, E_ERROR, $this->_name, $this->_line, $e);
|
||||||
@ -937,7 +945,7 @@ class Template extends Render {
|
|||||||
*
|
*
|
||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @return string
|
* @return string
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public function parseConst(Tokenizer $tokens) {
|
public function parseConst(Tokenizer $tokens) {
|
||||||
$tokens->get('#');
|
$tokens->get('#');
|
||||||
@ -956,7 +964,7 @@ class Template extends Render {
|
|||||||
if(defined($name)) {
|
if(defined($name)) {
|
||||||
return $name;
|
return $name;
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Use undefined constant $name");
|
throw new InvalidUsageException("Use undefined constant $name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,7 +972,7 @@ class Template extends Render {
|
|||||||
* @param Tokenizer $tokens
|
* @param Tokenizer $tokens
|
||||||
* @param $name
|
* @param $name
|
||||||
* @return string
|
* @return string
|
||||||
* @throws ImproperUseException
|
* @throws InvalidUsageException
|
||||||
*/
|
*/
|
||||||
public function parseMacro(Tokenizer $tokens, $name) {
|
public function parseMacro(Tokenizer $tokens, $name) {
|
||||||
if(isset($this->macros[ $name ])) {
|
if(isset($this->macros[ $name ])) {
|
||||||
@ -977,13 +985,13 @@ class Template extends Render {
|
|||||||
} elseif(isset($macro["defaults"][ $arg ])) {
|
} elseif(isset($macro["defaults"][ $arg ])) {
|
||||||
$args[ $arg ] = $macro["defaults"][ $arg ];
|
$args[ $arg ] = $macro["defaults"][ $arg ];
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Macro '$name' require '$arg' argument");
|
throw new InvalidUsageException("Macro '$name' require '$arg' argument");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$args = $args ? '$tpl = '.Compiler::toArray($args).';' : '';
|
$args = $args ? '$tpl = '.Compiler::toArray($args).';' : '';
|
||||||
return '$_tpl = $tpl; '.$args.' ?>'.$macro["body"].'<?php $tpl = $_tpl; unset($_tpl);';
|
return '$_tpl = $tpl; '.$args.' ?>'.$macro["body"].'<?php $tpl = $_tpl; unset($_tpl);';
|
||||||
} else {
|
} else {
|
||||||
throw new ImproperUseException("Undefined macro '$name'");
|
throw new InvalidUsageException("Undefined macro '$name'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,5 +1096,5 @@ class Template extends Render {
|
|||||||
|
|
||||||
class CompileException extends \ErrorException {}
|
class CompileException extends \ErrorException {}
|
||||||
class SecurityException extends CompileException {}
|
class SecurityException extends CompileException {}
|
||||||
class ImproperUseException extends \LogicException {}
|
class InvalidUsageException extends \LogicException {}
|
||||||
class ReparseTagException extends \Exception {}
|
class ReparseTagException extends \Exception {}
|
Loading…
Reference in New Issue
Block a user