mirror of
https://github.com/fenom-template/fenom.git
synced 2023-08-10 21:13:07 +03:00
Add filters for templates (#30)
This commit is contained in:
parent
e68f3dd99a
commit
f1d252a3cc
@ -7,8 +7,8 @@
|
||||
* For the full copyright and license information, please view the license.md
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
use Fenom\Template,
|
||||
Fenom\ProviderInterface;
|
||||
use Fenom\ProviderInterface;
|
||||
use Fenom\Template;
|
||||
|
||||
/**
|
||||
* Fenom Template Engine
|
||||
@ -67,10 +67,26 @@ class Fenom
|
||||
"disable_statics" => self::DENY_STATICS,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
public $pre_filters = array();
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
public $filters = array();
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
public $post_filters = array();
|
||||
|
||||
/**
|
||||
* @var Fenom\Render[] Templates storage
|
||||
*/
|
||||
protected $_storage = array();
|
||||
|
||||
/**
|
||||
* @var string compile directory
|
||||
*/
|
||||
@ -81,10 +97,6 @@ class Fenom
|
||||
*/
|
||||
protected $_options = 0;
|
||||
|
||||
protected $_on_pre_cmp = array();
|
||||
protected $_on_cmp = array();
|
||||
protected $_on_post_cmp = array();
|
||||
|
||||
/**
|
||||
* @var ProviderInterface
|
||||
*/
|
||||
@ -98,28 +110,28 @@ class Fenom
|
||||
* @var string[] list of modifiers [modifier_name => callable]
|
||||
*/
|
||||
protected $_modifiers = array(
|
||||
"upper" => 'strtoupper',
|
||||
"up" => 'strtoupper',
|
||||
"lower" => 'strtolower',
|
||||
"low" => 'strtolower',
|
||||
"upper" => 'strtoupper',
|
||||
"up" => 'strtoupper',
|
||||
"lower" => 'strtolower',
|
||||
"low" => 'strtolower',
|
||||
"date_format" => 'Fenom\Modifier::dateFormat',
|
||||
"date" => 'Fenom\Modifier::date',
|
||||
"truncate" => 'Fenom\Modifier::truncate',
|
||||
"escape" => 'Fenom\Modifier::escape',
|
||||
"e" => 'Fenom\Modifier::escape', // alias of escape
|
||||
"unescape" => 'Fenom\Modifier::unescape',
|
||||
"strip" => 'Fenom\Modifier::strip',
|
||||
"length" => 'Fenom\Modifier::length',
|
||||
"iterable" => 'Fenom\Modifier::isIterable'
|
||||
"date" => 'Fenom\Modifier::date',
|
||||
"truncate" => 'Fenom\Modifier::truncate',
|
||||
"escape" => 'Fenom\Modifier::escape',
|
||||
"e" => 'Fenom\Modifier::escape', // alias of escape
|
||||
"unescape" => 'Fenom\Modifier::unescape',
|
||||
"strip" => 'Fenom\Modifier::strip',
|
||||
"length" => 'Fenom\Modifier::length',
|
||||
"iterable" => 'Fenom\Modifier::isIterable'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array of allowed PHP functions
|
||||
*/
|
||||
protected $_allowed_funcs = array(
|
||||
"count" => 1, "is_string" => 1, "is_array" => 1, "is_numeric" => 1, "is_int" => 1,
|
||||
"is_object" => 1, "strtotime" => 1, "gettype" => 1, "is_double" => 1, "json_encode" => 1, "json_decode" => 1,
|
||||
"ip2long" => 1, "long2ip" => 1, "strip_tags" => 1, "nl2br" => 1, "explode" => 1, "implode" => 1
|
||||
"count" => 1, "is_string" => 1, "is_array" => 1, "is_numeric" => 1, "is_int" => 1,
|
||||
"is_object" => 1, "strtotime" => 1, "gettype" => 1, "is_double" => 1, "json_encode" => 1, "json_decode" => 1,
|
||||
"ip2long" => 1, "long2ip" => 1, "strip_tags" => 1, "nl2br" => 1, "explode" => 1, "implode" => 1
|
||||
);
|
||||
|
||||
/**
|
||||
@ -292,27 +304,47 @@ class Fenom
|
||||
/**
|
||||
*
|
||||
* @param callable $cb
|
||||
* @return self
|
||||
*/
|
||||
public function addPreCompileFilter($cb)
|
||||
public function addPreFilter($cb)
|
||||
{
|
||||
$this->_on_pre_cmp[] = $cb;
|
||||
$this->pre_filters[] = $cb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPreFilters() {
|
||||
return $this->pre_filters;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param callable $cb
|
||||
* @return self
|
||||
*/
|
||||
public function addPostCompileFilter($cb)
|
||||
public function addPostFilter($cb)
|
||||
{
|
||||
$this->_on_post_cmp[] = $cb;
|
||||
$this->post_filters[] = $cb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function getPostFilters() {
|
||||
return $this->post_filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $cb
|
||||
* @return self
|
||||
*/
|
||||
public function addCompileFilter($cb)
|
||||
public function addFilter($cb)
|
||||
{
|
||||
$this->_on_cmp[] = $cb;
|
||||
$this->filters[] = $cb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function getFilters() {
|
||||
return $this->filters;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,8 +8,8 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
namespace Fenom;
|
||||
use Fenom,
|
||||
Fenom\Error\UnexpectedTokenException;
|
||||
use Fenom;
|
||||
use Fenom\Error\UnexpectedTokenException;
|
||||
use Fenom\Error\CompileException;
|
||||
use Fenom\Error\InvalidUsageException;
|
||||
use Fenom\Error\SecurityException;
|
||||
@ -97,7 +97,7 @@ class Template extends Render
|
||||
|
||||
private $_before;
|
||||
|
||||
private $_filter = array();
|
||||
private $_filters = array();
|
||||
|
||||
private static $_checkers = array(
|
||||
'integer' => 'is_int(%s)',
|
||||
@ -136,6 +136,7 @@ class Template extends Render
|
||||
{
|
||||
$this->_fenom = $fenom;
|
||||
$this->_options = $options;
|
||||
$this->_filters = $this->_fenom->getFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,6 +197,9 @@ class Template extends Render
|
||||
{
|
||||
$end = $pos = 0;
|
||||
$this->escape = $this->_options & Fenom::AUTO_ESCAPE;
|
||||
foreach($this->_fenom->getPreFilters() as $filter) {
|
||||
$this->_src = call_user_func($filter, $this->_src, $this);
|
||||
}
|
||||
|
||||
while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags
|
||||
switch ($this->_src[$start + 1]) { // check next character
|
||||
@ -275,11 +279,15 @@ class Template extends Render
|
||||
}
|
||||
}
|
||||
$this->addDepend($this); // for 'verify' performance
|
||||
foreach($this->_fenom->getPostFilters() as $filter) {
|
||||
$this->_body = call_user_func($filter, $this->_body, $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute some code in loading cache
|
||||
* Execute some code at loading cache
|
||||
* @param $code
|
||||
* @return void
|
||||
*/
|
||||
public function before($code)
|
||||
{
|
||||
@ -303,15 +311,18 @@ class Template extends Render
|
||||
private function _appendText($text)
|
||||
{
|
||||
$this->_line += substr_count($text, "\n");
|
||||
if ($this->_filter) {
|
||||
if ($this->_filters) {
|
||||
if (strpos($text, "<?") === false) {
|
||||
foreach ($this->_filters as $filter) {
|
||||
$text = call_user_func($filter, $text, $this);
|
||||
}
|
||||
$this->_body .= $text;
|
||||
} else {
|
||||
$fragments = explode("<?", $text);
|
||||
foreach ($fragments as &$fragment) {
|
||||
if ($fragment) {
|
||||
foreach ($this->_filter as $filter) {
|
||||
$fragment = call_user_func($filter, $fragment);
|
||||
foreach ($this->_filters as $filter) {
|
||||
$fragment = call_user_func($filter, $fragment, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class MacrosTest extends TestCase
|
||||
|
||||
$this->tpl("macro_recursive.tpl", '{macro factorial(num)}
|
||||
{if $num}
|
||||
{$num} {macro.factorial num=$num-1}
|
||||
{$num} {macro.factorial num=$num-1} {$num}
|
||||
{/if}
|
||||
{/macro}
|
||||
|
||||
@ -104,6 +104,6 @@ class MacrosTest extends TestCase
|
||||
$this->fenom->compile('macro_recursive.tpl');
|
||||
$this->fenom->flush();
|
||||
$tpl = $this->fenom->getTemplate('macro_recursive.tpl');
|
||||
$this->assertSame("10 9 8 7 6 5 4 3 2 1", Modifier::strip($tpl->fetch(array()), true));
|
||||
$this->assertSame("10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10", Modifier::strip($tpl->fetch(array()), true));
|
||||
}
|
||||
}
|
||||
|
@ -114,4 +114,24 @@ class FenomTest extends \Fenom\TestCase
|
||||
// printf("remove %010b from option %010b, flags %010b\n", $option, $this->fenom->getOptions(), $flags & ~$option);
|
||||
// $this->assertSame($this->fenom->getOptions(), $flags & ~$option);
|
||||
}
|
||||
|
||||
public function testFilter() {
|
||||
$punit = $this;
|
||||
$this->fenom->addPreFilter(function ($src, $tpl) use ($punit) {
|
||||
$this->assertInstanceOf('Fenom\Template', $tpl);
|
||||
return "== $src ==";
|
||||
});
|
||||
|
||||
$this->fenom->addPostFilter(function ($code, $tpl) use ($punit) {
|
||||
$this->assertInstanceOf('Fenom\Template', $tpl);
|
||||
return "+++ $code +++";
|
||||
});
|
||||
|
||||
$this->fenom->addFilter(function ($text, $tpl) use ($punit) {
|
||||
$this->assertInstanceOf('Fenom\Template', $tpl);
|
||||
return "|--- $text ---|";
|
||||
});
|
||||
|
||||
$this->assertSame('+++ |--- == hello ---||--- world == ---| +++', $this->fenom->compileCode('hello {var $user} god {/var} world')->fetch(array()));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user