Mass refactory

Rename project
This commit is contained in:
bzick
2013-04-04 10:56:44 +04:00
parent 281757b902
commit 1e97857ea8
56 changed files with 478 additions and 1302 deletions

View File

@@ -1,9 +1,9 @@
Aspect - awesome template engine for PHP Cytro - awesome template engine for PHP
========================== ==========================
> Composer package: `{"bzick/aspect": "dev-master"}`. See on [Packagist.org](https://packagist.org/packages/bzick/aspect) > Composer package: `{"bzick/cytro": "dev-master"}`. See on [Packagist.org](https://packagist.org/packages/bzick/aspect)
[![Build Status](https://travis-ci.org/bzick/aspect.png?branch=master)](https://travis-ci.org/bzick/aspect) [![Build Status](https://travis-ci.org/bzick/aspect.png?branch=master)](https://travis-ci.org/bzick/cytro)
## [About](./docs/about.md) :: [Documentation](./docs/main.md) :: [Benchmark](./docs/benchmark.md) :: [Articles](./docs/articles.md) ## [About](./docs/about.md) :: [Documentation](./docs/main.md) :: [Benchmark](./docs/benchmark.md) :: [Articles](./docs/articles.md)
* Simplest known [syntax](./docs/syntax.md) * Simplest known [syntax](./docs/syntax.md)
@@ -20,11 +20,11 @@ Simple template
```smarty ```smarty
<html> <html>
<head> <head>
<title>Aspect</title> <title>Cytro</title>
</head> </head>
<body> <body>
{if $templaters.aspect?} {if $templaters.cytro?}
{var $tpl = $templaters.aspect} {var $tpl = $templaters.cytro}
<div>Name: {$tpl.name}</div> <div>Name: {$tpl.name}</div>
<div>Description: {$tpl.name|truncate:80}</div> <div>Description: {$tpl.name|truncate:80}</div>
<ul> <ul>
@@ -41,24 +41,24 @@ Display template
```php ```php
<?php <?php
$aspect = Aspect::factory('./templates', './compiled', Aspect::CHECK_MTIME); $cytro = Cytro::factory('./templates', './compiled', Cytro::CHECK_MTIME);
$aspect->display("pages/about.tpl", $data); $cytro->display("pages/about.tpl", $data);
``` ```
Get content Get content
```php ```php
<?php <?php
$aspect = Aspect::factory('./templates', './compiled', Aspect::CHECK_MTIME); $cytro = Cytro::factory('./templates', './compiled', Cytro::CHECK_MTIME);
$content = $aspect->fetch("pages/about.tpl", $data); $content = $cytro->fetch("pages/about.tpl", $data);
``` ```
Runtime compilation Runtime compilation
```php ```php
<?php <?php
$aspect = new Aspect(); $cytro = new Cytro();
$tempate = $aspect->compileCode('Hello {$user.name}! {if $user.email?} Your email: {$user.email} {/if}'); $tempate = $cytro->compileCode('Hello {$user.name}! {if $user.email?} Your email: {$user.email} {/if}');
$tempate->display($data); $tempate->display($data);
// or // or
$content = $tempate->fetch($data); $content = $tempate->fetch($data);

View File

@@ -1,22 +0,0 @@
<?php
use MF\Aspect;
require_once __DIR__ . "/../../../lib/Autoload.php";
Aspect::addTemplateDir(__DIR__.'/../templates');
Aspect::setCompileDir(__DIR__.'/../compiled');
$total = 0;
$t = microtime(1);
$tpl = Aspect::compile('syntax.tpl');
$t = microtime(1) - $t;
var_dump("First compile: ".$t);
$t = microtime(1);
$tpl = Aspect::compile('syntax.tpl');
$t = microtime(1) - $t;
var_dump("Second compile: ".$t);
var_dump("Pick memory: ".memory_get_peak_usage());
?>

View File

@@ -1,23 +0,0 @@
<?php
require_once "/data/downloads/Smarty3/libs/Smarty.class.php";
$smarty = new Smarty();
$smarty->addTemplateDir(__DIR__.'/../templates');
$smarty->setCompileDir(__DIR__.'/../compiled');
$t = microtime(1);
$tpl = $smarty->createTemplate('syntax.tpl');
/* @var Smarty_Internal_Template $tpl */
$tpl->compileTemplateSource();
$t = microtime(1) - $t;
var_dump("First compile: ".$t);
$t = microtime(1);
$tpl = $smarty->createTemplate('syntax.tpl');
/* @var Smarty_Internal_Template $tpl */
$tpl->compileTemplateSource();
$t = microtime(1) - $t;
var_dump("Second compile: ".$t);
var_dump("Pick memory: ".memory_get_peak_usage());

View File

@@ -1,87 +0,0 @@
<?php
class obj {
public $value = "obj.value property";
public $num = 777;
public function method() {
return "object method";
}
public function methodArgs($i, $j, $k, $str, $value) {
return "object method with ars $i, $j, $k, $str, $value";
}
public function __toString() {
return "object";
}
public function getSelf() {
return $this;
}
}
return array(
"title" => "syntax test page",
"user" => array(
"email" => 'bzick@megagroup.ru',
"name" => 'Ivan'
),
"data" => array(
1 => array(
"foo" => "data.1.foo value"
),
2 => 4,
4 => "data.four value",
5 => array(
"bar" => "data.5.baz value",
"baz" => array(
"foo" => "data.5.baz.foo value"
)
),
6 => array(
"foo" => "data.6.foo value"
),
"bar" => "data.bar value",
"barz" => "data.barz value",
"baz_key" => "baz",
"foo" => array(
"bar" => "data.foo.baz value",
"baz" => array(
"foo" => "data.foo.baz.foo value",
"ls" => array(
4 => "data.foo.baz.ls.4 value",
5 => 555
)
)
),
"obj" => new obj(),
"tpl_name" => 'subdir/subtpl'
),
"foo_key" => "foo",
"bar_key" => "bar",
"barz_key" => "barz",
"baz_key" => "baz",
"item" => "some item",
"x" => 1,
"y" => 2,
"tpl_name" => "subtpl",
"contacts" => array(
array(
"foo" => "bar",
"foo1" => "bar1",
"foo2" => "bar2",
),
array(
"baz" => "buh",
"baz1" => "buh1",
"baz2" => "buh2",
)
),
"logged_in" => false
);

View File

@@ -1,25 +0,0 @@
<?php
use MF\Aspect;
require_once __DIR__ . "/../../../lib/Autoload.php";
Aspect::addTemplateDir(__DIR__.'/../templates');
Aspect::setCompileDir(__DIR__.'/../compiled');
/*$ct = microtime(1);
$data = Aspect::compile('syntax.tpl',0);
$ct = microtime(1) - $ct;
echo "\n=====================\nCompile: $ct\n";*/
$_data = require_once __DIR__.'/data.php';
$data = Aspect::fetch('syntax.tpl', $_data, 0);
$dt = microtime(1);
$data = Aspect::fetch('syntax.tpl', $_data, 0);
$dt = microtime(1) - $dt;
$data = MF\Misc\Str::strip($data, true);
echo "$data\n====\n".md5($data)."\n=====================\nDisplay: $dt\n";
var_dump("Pick memory: ".memory_get_peak_usage());
?>

View File

@@ -1,23 +0,0 @@
<?php
use MF\Aspect;
require_once __DIR__ . "/../../../lib/Autoload.php";
$tpl = require_once __DIR__.'/data.php';
require __DIR__.'/../templates/syntax.php';
require __DIR__.'/../templates/subdir/subtpl.php';
ob_start();
template_syntax($tpl);
$data = ob_get_clean();
$dt = microtime(1);
ob_start();
template_syntax($tpl);
$data = ob_get_clean();
$dt = microtime(1) - $dt;
$data = MF\Misc\Str::strip($data, true);
echo "$data\n====\n".md5($data)."\n=====================\nDisplay: $dt\n";
var_dump("Pick memory: ".memory_get_peak_usage());
?>

View File

@@ -1,25 +0,0 @@
<?php
use MF\Aspect;
require_once __DIR__ . "/../../../lib/Autoload.php";
Aspect::setTemplateDir(__DIR__.'/../templates');
Aspect::setCompileDir(__DIR__.'/../compiled');
$ct = microtime(1);
$data = Aspect::compile('simple.tpl',0);
$ct = microtime(1) - $ct;
$_data = array(
"name" => "Ivan",
"email" => "bzick@megagroup.ru"
);
$data = Aspect::fetch('simple.tpl', $_data, 0);
$dt = microtime(1);
$data = Aspect::fetch('simple.tpl', $_data, 0);
$dt = microtime(1) - $dt;
echo "\n=====================\nCompile: $ct\nDisplay: $dt\n";
?>

View File

@@ -1,29 +0,0 @@
<?php
require_once "/data/downloads/Smarty3/libs/Smarty.class.php";
$smarty = new Smarty();
$smarty->addTemplateDir(__DIR__.'/../templates');
$smarty->setCompileDir(__DIR__.'/../compiled');
$ct = microtime(1);
$tpl = $smarty->createTemplate('simple.tpl');
/* @var Smarty_Internal_Template $tpl */
$tpl->compileTemplateSource();
$ct = microtime(1) - $ct;
$_data = array(
"name" => "Ivan",
"email" => "bzick@megagroup.ru"
);
$smarty->assign($_data);
$data = $smarty->fetch('simple.tpl');
$t = microtime(1);
$smarty->assign($_data);
$data = $smarty->fetch('simple.tpl');
$dt = microtime(1) - $t;
echo "\n=====================\nCompile: $ct\nDisplay: $dt\n";

View File

@@ -1,29 +0,0 @@
<?php
require_once "/data/downloads/Smarty3/libs/Smarty.class.php";
require_once __DIR__ . "/../../../lib/Autoload.php";
$smarty = new Smarty();
$smarty->addTemplateDir(__DIR__.'/../templates');
$smarty->setCompileDir(__DIR__.'/../compiled');
/*$ct = microtime(1);
$tpl = $smarty->createTemplate('syntax.tpl');
/* @var Smarty_Internal_Template $tpl */
/*$tpl->compileTemplateSource();
$ct = microtime(1) - $ct;
echo "\n=====================\nCompile: $ct\n";
*/
$_data = require_once __DIR__.'/data.php';
$smarty->assign($_data);
$data = $smarty->fetch('syntax.tpl');
$t = microtime(1);
$smarty->assign($_data);
$data = $smarty->fetch('syntax.tpl');
$dt = microtime(1) - $t;
$data = MF\Misc\Str::strip($data, true);
echo "$data\n====\n".md5($data)."\n=====================\nDisplay: $dt\n";
var_dump("Pick memory: ".memory_get_peak_usage());

View File

@@ -1,47 +0,0 @@
<?php
$a = new ArrayIterator(str_split(str_pad("", 4, "a")));
$_t = null;
$t = microtime(1);
reset($a);
while($v = current($a)) {
$k = key($a);
next($a);
if(key($a) === null) {
var_dump("last");
}
//var_dump($v);
}
print_r("\n\nWhile: ".(microtime(1) - $t)."\n\n");
$t = microtime(1);
$c = count($a);
foreach($a as $k => $v) {
if(!--$c) var_dump("last");
//var_dump($v);
}
print_r("\n\nforeach + count: ".(microtime(1) - $t)."\n\n");
$t = microtime(1);
reset($a);
while(list($k, $v) = each($a)) {
if(key($a) === null) {
var_dump("last");
}
/*next($a);
if(key($a) === null) {
var_dump("last");
}*/
//var_dump($v);
}
print_r("\neach: ".(microtime(1) - $t)."\n\n");
$t = microtime(1);
foreach($a as $k => $v) {
//var_dump($v);
}
print_r("\n\nforeach: ".(microtime(1) - $t)."\n\n");
?>

View File

@@ -1,94 +0,0 @@
{*
data.value = "TXT value";
data.arr.dot.4.retval = "Four";
data.arr.dot.5 = "FiVe";
data.arr.i = 4;
data.arr.retval = "Retval key";
data.set->get = "Get props";
data.iam->getName(...) == "return Name";
data.iam->getFormat(...)== "return Format";
data.num = 777;
data.k = 0;
data.ls = array("a" => "lit A", "c" => "lit C", "d" => "lit D");
*}
Hello <b>world</b>!
My Name is {$data.value}...
Yeah
Hello <b>world</b>!
My Name is {$data.arr.dot|json_encode|lower}...
Yeah
Hello <b>world</b>, {$data.value|upper}!
My Name is {$data.arr[dot].5|upper}...
My Name is {$data.arr.dot[ $data.arr.i|round ]."retval"|upper}...
My Name is {$data.arr."retval"|upper}...
Yeah
Hello <b>world</b>!
My Name is {$data.set->get|upper}...
Yeah
Hello <b>world</b>!
My Name is {$data.iam->getName()|upper}...
Your Name is {$data.you->getFormat(1, 0.4, "%dth", 'grade', $data.arr[dot].5|lower)|upper}?
Yeah
Hello <b>world</b>!
{if isset($data.iam) && !empty($data.set->get)}
My Name is {$data.set->get}...
{/if}
Yeah
Hello <b>world</b>!
{if $data.num >= 5 && $data.k++ || foo($data.value) && !bar($data.num) + 3 || $data.k?}
My Name is {$data->user|upper}...
{/if}
Yeah
Hello <b>world</b>!
{foreach from=$data.ls key=k item=e}
My Name is {$e|upper} ({$k})...
{/foreach}
Yeah
Hello <b>world</b>!
{switch $data.num}
{case "dotted"}
dotted lines<br>
{break}
{case 777}
numeric lines<br>
{break}
{case $data[arr]["dot"].4.retval|upper}
lister<br>
{break}
{/switch}
Yeah
Hello <b>world</b>!
{* if !empty($data.num) *}
{if $data.num?}
dotted lines<br>
{elseif $data[arr]["dot"].4.retval|lower}
lister<br>
{/if}
Yeah
Check system variable<br/>
Current timestamp {$aspect.now}...<br/>
$_GET {$aspect.get.item}...<br/>
$_POST {$aspect.post.myval|upper}...<br/>
$_COOKIES {$aspect.cookies["uid"]}...<br/>
$_REQUEST {$aspect.request?}...<br/>
Consts {$data.number|round:$aspect.const.PHP_INT_MAX}...<br/>
Ok
Hello <b>world</b>!
{for from=1 to=$data.ls|count}
<div>Go</div>
{/for}
Yeah

View File

@@ -1,17 +0,0 @@
<html>
<head>
<title>Simple template about {$name|upper}</title>
</head>
<body>
{if $name}
My name is {$name}
{else}
I haven't name :(
{/if}
Ok.
My email {$email}. It is great!
</body>
</html>

View File

@@ -1,18 +0,0 @@
<?php
function template_subtpl($tpl) {
if($tpl["user"]["name"]) {
echo 'My name is '.$tpl["user"]["name"];
} else {
echo 'I haven\'t name :(';
};
?>
Ok.
My email <?php echo $tpl["user"]["name"].'. It is great!'; ?>
<?php
}
?>

View File

@@ -1,9 +0,0 @@
{if $user.name}
My name is {$user.name}
{else}
I haven't name :(
{/if}
Ok.
My email {$user.name}. It is great!

View File

@@ -1,184 +0,0 @@
<?php
function template_syntax($tpl) {
?><html>
<head>
<title><?php echo $tpl["title"]; ?></title>
</head>
<body>
Simple manipulations
<?php echo $tpl["item"]; ?>
<?php echo $tpl["data"][4]; ?>
<?php echo $tpl["data"]["bar"]; ?>
<?php echo $tpl["data"]["bar"]; ?>
<?php echo $tpl["data"]["bar"]; ?>
<?php echo $tpl["data"]['bar']; ?>
<?php echo $tpl["data"][ $tpl["bar_key"] ]; ?>
<?php echo $tpl["data"]["obj"]->value; ?>
<?php echo $tpl["data"]["obj"]->method(); ?>
Many other combinations are allowed
<?php echo $tpl["data"]["foo"]["bar"]; ?>
<?php echo $tpl["data"]["foo"][ $tpl["baz_key"] ][ $tpl["foo_key"] ]; ?>
<?php echo $tpl["data"]["foo"][ $tpl["bar_key"] ]; ?>
<?php echo $tpl["data"][ $tpl["foo_key"] ]["bar"]; ?>
<?php echo $tpl["data"][5]["bar"]; ?>
<?php echo $tpl["data"][5][ $tpl["bar_key"] ]; ?>
<?php echo $tpl["data"]["foo"][ $tpl["baz_key"] ]["ls"][4]; ?>
<?php echo $tpl["data"]["obj"]->methodArgs($tpl["baz_key"], 2, 2.3, "some string", $tpl["bar_key"]); ?> <-- passing parameters
Math and embedding tags:
<?php echo $tpl["x"] + $tpl["y"]; ?> // will output the sum of x and y.
<?php echo $tpl["data"][$tpl["x"] + 3]; ?>
<?php echo $tpl["item"] = 4 + 3; ?> // tags within tags
<?php echo $tpl["data"][4] = 4 + 3; ?>
<?php echo $tpl["item"] = "this is message"; ?> // tags within double quoted strings
Short variable assignment:
<?php echo $tpl["item"] = $tpl["y"] + 2; ?>
<?php echo $tpl["item"] = strlen($tpl["bar_key"]); ?> // function in assignment
<?php echo $tpl["item"] = intval(($tpl["x"] + $tpl["y"]) * 3); ?> // as function parameter
<?php echo $tpl["data"]["bar"] = 1; ?> // assign to specific array element
<?php echo $tpl["data"]["foo"]["bar"] = "data.foo.bar: tpl value"; ?>
Smarty "dot" syntax (note: embedded {} are used to address ambiguities):
<?php echo $tpl["data"]["foo"]["baz"]["foo"]; ?>
<?php echo $tpl["data"]["foo"][ $tpl["baz_key"] ]["foo"]; ?>
<?php echo $tpl["data"][$tpl["y"] + 4]["foo"]; ?>
<?php echo $tpl["data"]["foo"][$tpl["data"]["baz_key"]]["foo"]; ?>
Object chaining:
<?php echo $tpl["data"]["obj"]->getSelf($tpl["x"])->method($tpl["y"]); ?>
Direct PHP function access:
<?php echo strlen("hi!"); ?>
<?php
if($tpl["logged_in"]) {
echo 'Welcome, <span style="color: '.$tpl["fontColor"].'">'.$tpl["name"].'</span>';
} else {
echo "hi, ".$tpl["user"]["name"];
}
?>
Embedding Vars in Double Quotes
<?php echo MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".$tpl["item"]." test"), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".$tpl["foo_key"]." test"), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".($tpl["data"][4])." test"), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".$tpl["item"].".bar test"), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => 'test {$data.barz} test'), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".($tpl["data"]["barz"])." test"), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => strtoupper("test ".($tpl["data"]["barz"])." test")), $tpl).
MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "test ".(strtoupper($tpl["data"]["barz"]))." test"), $tpl); ?>
will replace $tpl_name with value
<?php template_subtpl($tpl); ?>
does NOT replace $tpl_name
<?php echo MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => "one,two"), $tpl); ?>
<?php template_subtpl($tpl); ?>
Math
some more complicated examples
<?php echo $tpl["data"][2] - $tpl["data"]["obj"]->num * !$tpl["data"]["foo"]["baz"]["ls"][4] - 3 * 7 % $tpl["data"][2]; ?>
<?php
if($tpl["data"][2] - $tpl["data"]["obj"]->num * $tpl["data"]["foo"]["baz"]["ls"][4] - 3 * 7 % $tpl["data"][2]) {
echo MF\Misc\Str::truncate($tpl["data"]["barz"], "".($tpl["data"][2] / 2 - 1)."")."\n".
MF\Misc\Str::truncate($tpl["data"]["barz"], ($tpl["data"][2] / 2 - 1));
}
?>
Escaping Smarty Parsing
<script>
// the following braces are ignored by Smarty
// since they are surrounded by whitespace
function foobar() {
alert('foobar!');
}
// this one will need literal escapement
<?php ?>
function bazzy() {alert('foobar!');}
</script>
name: <?php echo $tpl["user"]["name"]; ?><br />
email: <?php echo $tpl["user"]["email"]; ?><br />
Modifier examples
apply modifier to a variable
<?php echo strtoupper($tpl["user"]["name"]); ?>
modifier with parameters
<?php echo MF\Misc\Str::truncate($tpl["user"]["name"], 40, "..."); ?>
apply modifier to a function parameter
<?php echo MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => strtoupper($tpl["user"]["name"])), $tpl); ?>
with parameters
<?php echo MF\Aspect\Func::mailto(array("address" => $tpl["user"]["email"],"text" => MF\Misc\Str::truncate($tpl["user"]["name"], 40, "...")), $tpl); ?>
apply modifier to literal string
using date_format to format the current date
<?php echo MF\Aspect\Modifier::dateFormat(time(), "%Y/%m/%d"); ?>
apply modifier to a custom function
Foreach
<?php
if($tpl["contacts"]) {
foreach($tpl["contacts"] as $tpl["contact"]) {
if($tpl["contact"]) {
foreach($tpl["contact"] as $tpl["key"] => $tpl["value"]) {
echo $tpl["key"].": ".$tpl["value"]." ";
}
} else {
echo "no items";
}
}
}
?>
If condition
<?php
if(isset($tpl["user"]["name"]) && $tpl["user"]["name"] == 'yandex') {
echo "do something";
} elseif($tpl["user"]["name"] == $tpl["data"]["foo"]["bar"]) {
echo "do something2";
}
?>
<?php
if(is_array($tpl["data"]["foo"]) && count($tpl["data"]["foo"]) > 0) {
echo "do a foreach loop";
}
?>
</body>
</html>
<?php
}
?>

View File

@@ -1,179 +0,0 @@
<html>
<head>
<title>{$title}</title>
</head>
<body>
{* this is a comment *}
Simple manipulations
{$item}
{$data[4]}
{$data.bar}
{*$data[bar]*}
{$data["bar"]}
{$data['bar']}
{$data.$bar_key}
{$data.obj->value}
{$data.obj->method()}
Many other combinations are allowed
{$data.foo.bar}
{$data.foo.$baz_key.$foo_key}
{$data.foo.$bar_key}
{$data.$foo_key.bar}
{$data[5].bar}
{$data[5].$bar_key}
{$data.foo.$baz_key.ls[4]}
{$data.obj->methodArgs($baz_key, 2, 2.3, "some string", $bar_key)} <-- passing parameters
{*"foo"*}
Math and embedding tags:
{$x+$y} // will output the sum of x and y.
{$data[$x+3]}
{$item=4+3} // tags within tags
{$data[4]=4+3}
{$item="this is message"} // tags within double quoted strings
Short variable assignment:
{$item=$y+2}
{$item = strlen($bar_key)} // function in assignment
{$item = intval( ($x+$y)*3 )} // as function parameter
{$data.bar=1} // assign to specific array element
{$data.foo.bar="data.foo.bar: tpl value"}
Smarty "dot" syntax (note: embedded {} are used to address ambiguities):
{$data.foo.baz.foo}
{$data.foo.$baz_key.foo}
{$data[$y+4].foo}
{$data.foo[$data.baz_key].foo}
Object chaining:
{$data.obj->getSelf($x)->method($y)}
Direct PHP function access:
{strlen("hi!")}
{if $logged_in}
Welcome, <span style="color:{$fontColor}">{$name}!</span>
{else}
hi, {$user.name}
{/if}
Embedding Vars in Double Quotes
{mailto address=$user.email text="test $item test"}
{mailto address=$user.email text="test $foo_key test"}
{mailto address=$user.email text="test {$data[4]} test"}
{*mailto address=$user.email text="test {$data[barz]} test"*}
{mailto address=$user.email text="test $item.bar test"}
{mailto address=$user.email text='test {$data.barz} test'}
{mailto address=$user.email text="test {$data.barz} test"}
{mailto address=$user.email text="test {$data.barz} test"|upper}
{mailto address=$user.email text="test {$data.barz|upper} test"}
will replace $tpl_name with value
{include file="subdir/$tpl_name.tpl"}
does NOT replace $tpl_name
{mailto address=$user.email text="one,two"}
{include file="{$data.tpl_name}.tpl"}
Math
some more complicated examples
{$data[2] - $data.obj->num * !$data.foo.baz.ls[4] - 3 * 7 % $data[2]}
{if $data[2] - $data.obj->num * $data.foo.baz.ls[4] - 3 * 7 % $data[2]}
{$data.barz|truncate:"{$data[2]/2-1}"}
{$data.barz|truncate:($data[2]/2-1)}
{/if}
Escaping Smarty Parsing
<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>
name: {$user.name}<br />
email: {$user.email}<br />
Modifier examples
apply modifier to a variable
{$user.name|upper}
modifier with parameters
{$user.name|truncate:40:"..."}
apply modifier to a function parameter
{mailto address=$user.email text=$user.name|upper}
with parameters
{mailto address=$user.email text=$user.name|truncate:40:"..."}
apply modifier to literal string
{*"foobar"|upper*}
using date_format to format the current date
{$smarty.now|date_format:"%Y/%m/%d"}
apply modifier to a custom function
{*mailto|upper address="smarty@example.com"*}
Foreach
{foreach $contacts as $contact}
{foreach $contact as $key => $value}
{$key}: {$value}
{foreachelse}
no items
{/foreach}
{/foreach}
If condition
{if isset($user.name) && $user.name == 'yandex'}
do something
{elseif $user.name == $data.foo.bar}
do something2
{/if}
{*switch $item}
{case 1}
item 1
{break}
{case 2}
item 2
{break}
{default}
on item
{/switch*}
{if is_array($data.foo) && count($data.foo) > 0}
do a foreach loop
{/if}
</body>
</html>

View File

@@ -1,103 +0,0 @@
<?php
use MF\Misc\Tokenizer;
require_once __DIR__ . "/../../lib/Autoload.php";
$tokens = new \MF\Misc\Tokenizer('$data.value[5].dot|json_decode|lower');
$tpl[0] = 'Hello <b>world</b>!
My Name is {$data.value}...
Yeah';
$tpl[1] = 'Hello <b>world</b>!
My Name is {$data.value[label].dot|json_decode|lower|truncate:80:"...":true:null:0.22:$a.keyz|upper}...
Yeah';
$tpl[2] = 'Hello <b>world</b>, {$user.name|upper}!
My Name is {$data.user1.5.$i."return"[ $hello.world|lower ]|upper}...
Yeah';
$tpl[3] = 'Hello <b>world</b>!
My Name is {$data->set->get|upper}...
Yeah';
$tpl[4] = 'Hello <b>world</b>!
My Name is {$iam->getName()|upper}...
Your Name is {$you->getFromat(1, 0.4, "%dth", \'grade\', $global->name.k|lower)|upper}?
Yeah';
$tpl[5] = 'Hello <b>world</b>!
{if isset($data.user) && !empty($data->value)}
My Name is {$data->user|upper}...
{/if}
Yeah';
$tpl[6] = 'Hello <b>world</b>!
{if $data.user >= 5 && $k++ || foo($data->value) && !bar($d) + 3 || $show.go?}
My Name is {$data->user|upper}...
{/if}
Yeah';
$tpl[7] = 'Hello <b>world</b>!
{foreach from=$users."list" key=k item=e}
My Name is {$e|upper} ({$k})...
{/foreach}
Yeah';
$tpl[8] = 'Hello <b>world</b>!
{switch $data->enum}
{case "dotted"}
dotted lines<br>
{break}
{case 7}
numeric lines<br>
{break}
{case $list|truncate}
lister<br>
{break}
{/switch}
Yeah';
$tpl[9] = 'Hello <b>world</b>!
{if $data->enum?}
dotted lines<br>
{elseif $list|truncate}
lister<br>
{/if}
Yeah';
$tpl[10] = 'Check system variable<br/>
Current timestamp {$aspect.now}...<br/>
$_GET {$aspect.get.item}...<br/>
$_POST {$aspect.post.myval|upper}...<br/>
$_COOKIES {$aspect.cookies["uid"]}...<br/>
$_REQUEST {$aspect.request?}...<br/>
Consts {$number|round:$aspect.const.PHP_INT_MAX|}...<br/>
Ok';
$tpl[11] = 'Hello <b>world</b>!
{for from=1 to=$e|count}
<div>Go</div>
{/for}
Yeah';
$tpl_ = '
Hello <b>world</b>!
My Name is {$data|upper}...
<script>$.dotted({
items: "sorted"
});</script> {* comment *}
I have
<ul>
{foreach $items as $key => $item}
<li>{$item}</li>
{/foreach}
</ul>
';
$template = new MF\Aspect\Template($tpl[7], 'my.tpl');
//var_dump(Tokenizer::decode('case 6:'));
//exit;
echo "\n".$template->getBody()."\n";
//var_dump($template->fetch(array("data" => array("value" => "Yohoho"))));
?>

View File

@@ -2,7 +2,7 @@
require_once __DIR__.'/scripts/bootstrap.php'; require_once __DIR__.'/scripts/bootstrap.php';
exec("rm -rf ".__DIR__."/compile/*"); exec("rm -rf ".__DIR__."/compile/*");
echo "Smarty3 vs Twig vs Aspect\n\n"; echo "Smarty3 vs Twig vs Cytro\n\n";
echo "Generate templates... "; echo "Generate templates... ";
passthru("php ".__DIR__."/templates/inheritance/smarty.gen.php"); passthru("php ".__DIR__."/templates/inheritance/smarty.gen.php");
@@ -32,6 +32,6 @@ echo "\nDone. Cleanup.\n";
passthru("rm -f ".__DIR__."/templates/inheritance/smarty/*"); passthru("rm -f ".__DIR__."/templates/inheritance/smarty/*");
passthru("rm -f ".__DIR__."/templates/inheritance/twig/*"); passthru("rm -f ".__DIR__."/templates/inheritance/twig/*");
echo "\nSmarty3 vs Aspect (more details)\n\n"; echo "\nSmarty3 vs Cytro (more details)\n\n";
echo "Coming soon\n"; echo "Coming soon\n";

View File

@@ -45,13 +45,13 @@ class Benchmark {
public static function aspect($tpl, $data, $double, $message) { public static function aspect($tpl, $data, $double, $message) {
$aspect = Aspect::factory(__DIR__.'/../templates', __DIR__."/../compile/"); $cytro = Cytro::factory(__DIR__.'/../templates', __DIR__."/../compile/");
if($double) { if($double) {
$aspect->fetch($tpl, $data); $cytro->fetch($tpl, $data);
} }
$_SERVER["t"] = $start = microtime(true); $_SERVER["t"] = $start = microtime(true);
$aspect->fetch($tpl, $data); $cytro->fetch($tpl, $data);
printf(self::$t, __FUNCTION__, $message, round(microtime(true)-$start, 4), round(memory_get_peak_usage()/1024/1024, 2)); printf(self::$t, __FUNCTION__, $message, round(microtime(true)-$start, 4), round(memory_get_peak_usage()/1024/1024, 2));
} }

View File

@@ -53,13 +53,13 @@ $template = $twig->loadTemplate('echo/twig.tpl');
$template->render($data); $template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start)); var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::AUTO_RELOAD); $cytro = Cytro::factory(__DIR__, __DIR__."/../compile/", Cytro::AUTO_RELOAD);
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('echo/smarty.tpl', $data); $template = $cytro->fetch('echo/smarty.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start)); var_dump("Cytro: ".(microtime(true)-$start));
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('echo/smarty.tpl', $data); $template = $cytro->fetch('echo/smarty.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start)); var_dump("Cytro cached: ".(microtime(true)-$start));

View File

@@ -38,13 +38,13 @@ $template = $twig->loadTemplate('foreach/twig.tpl');
$template->render($data); $template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start)); var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::AUTO_RELOAD | Aspect::INCLUDE_SOURCES); $cytro = Cytro::factory(__DIR__, __DIR__."/../compile/", Cytro::AUTO_RELOAD);
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('foreach/smarty.tpl', $data); $template = $cytro->fetch('foreach/smarty.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start)); var_dump("Cytro: ".(microtime(true)-$start));
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('foreach/smarty.tpl', $data); $template = $cytro->fetch('foreach/smarty.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start)); var_dump("Cytro cached: ".(microtime(true)-$start));

View File

@@ -49,13 +49,13 @@ $template = $twig->loadTemplate('inheritance/twig/b100.tpl');
$template->render($data); $template->render($data);
var_dump("Twig cached: ".(microtime(true)-$start)); var_dump("Twig cached: ".(microtime(true)-$start));
$aspect = Aspect::factory(__DIR__, __DIR__."/../compile/", Aspect::AUTO_RELOAD); $cytro = Cytro::factory(__DIR__, __DIR__."/../compile/", Cytro::AUTO_RELOAD);
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('inheritance/smarty/b100.tpl', $data); $template = $cytro->fetch('inheritance/smarty/b100.tpl', $data);
var_dump("Aspect: ".(microtime(true)-$start)); var_dump("Cytro: ".(microtime(true)-$start));
$start = microtime(true); $start = microtime(true);
$template = $aspect->fetch('inheritance/smarty/b100.tpl', $data); $template = $cytro->fetch('inheritance/smarty/b100.tpl', $data);
var_dump("Aspect cached: ".(microtime(true)-$start)); var_dump("Cytro cached: ".(microtime(true)-$start));

View File

@@ -1,9 +1,9 @@
{ {
"name": "bzick/aspect", "name": "bzick/cytro",
"type": "library", "type": "library",
"description": "Aspect - fast template engine for PHP", "description": "Cytro - fast template engine for PHP",
"homepage": "https://github.com/bzick/aspect", "homepage": "http://cytro.org/",
"keywords": ["aspect", "template", "templating"], "keywords": ["cytro", "template", "templating"],
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@@ -21,7 +21,7 @@
"twig/twig": "1.*" "twig/twig": "1.*"
}, },
"autoload": { "autoload": {
"psr-0": { "Aspect\\": "src/" }, "psr-0": { "Cytro\\": "src/" },
"classmap": [ "src/Aspect.php" ] "classmap": [ "src/Cytro.php" ]
} }
} }

View File

@@ -1,7 +1,7 @@
About Aspect [RU] About Cytro [RU]
================= ================
Aspect - самый быстрый, гибкий и тонкий шаблонизатор для PHP, унаследовавший синтаксис от Smarty3 и улучшив его. Cytro - самый быстрый, гибкий и тонкий шаблонизатор для PHP, унаследовавший синтаксис от Smarty3 и улучшив его.
Пожалуй это единственный шаблонизатор, который не использет ни регулярные выражения, как Twig, ни лексер от BISON, как Smarty3. Пожалуй это единственный шаблонизатор, который не использет ни регулярные выражения, как Twig, ни лексер от BISON, как Smarty3.
Вы не найдёте ни одного регулярного выражения в ядре Aspect, но тем не менее ядро простое, компактное и очень быстрое. Вы не найдёте ни одного регулярного выражения в ядре Aspect, но тем не менее ядро простое, компактное и очень быстрое.

View File

@@ -15,9 +15,9 @@ To start benchmark run script `benchmark/run.php`.
twig: compiled and !loaded 0.0337 sec, 16.1 MiB twig: compiled and !loaded 0.0337 sec, 16.1 MiB
twig: compiled and loaded 0.0027 sec, 16.1 MiB twig: compiled and loaded 0.0027 sec, 16.1 MiB
aspect: !compiled and !loaded 1.0142 sec, 8.8 MiB cytro: !compiled and !loaded 1.0142 sec, 8.8 MiB
aspect: compiled and !loaded 0.0167 sec, 6.1 MiB cytro: compiled and !loaded 0.0167 sec, 6.1 MiB
aspect: compiled and loaded 0.0024 sec, 6.1 MiB cytro: compiled and loaded 0.0024 sec, 6.1 MiB
Iterates array Iterates array
@@ -29,9 +29,9 @@ To start benchmark run script `benchmark/run.php`.
twig: compiled and !loaded 0.0605 sec, 2.9 MiB twig: compiled and !loaded 0.0605 sec, 2.9 MiB
twig: compiled and loaded 0.0550 sec, 2.9 MiB twig: compiled and loaded 0.0550 sec, 2.9 MiB
aspect: !compiled and !loaded 0.0093 sec, 3.0 MiB cytro: !compiled and !loaded 0.0093 sec, 3.0 MiB
aspect: compiled and !loaded 0.0033 sec, 2.4 MiB cytro: compiled and !loaded 0.0033 sec, 2.4 MiB
aspect: compiled and loaded 0.0027 sec, 2.4 MiB cytro: compiled and loaded 0.0027 sec, 2.4 MiB
templates inheritance templates inheritance
@@ -43,9 +43,9 @@ To start benchmark run script `benchmark/run.php`.
twig: compiled and !loaded 0.0255 sec, 6.3 MiB twig: compiled and !loaded 0.0255 sec, 6.3 MiB
twig: compiled and loaded 0.0038 sec, 6.3 MiB twig: compiled and loaded 0.0038 sec, 6.3 MiB
aspect: !compiled and !loaded 0.1222 sec, 3.9 MiB cytro: !compiled and !loaded 0.1222 sec, 3.9 MiB
aspect: compiled and !loaded 0.0004 sec, 2.4 MiB cytro: compiled and !loaded 0.0004 sec, 2.4 MiB
aspect: compiled and loaded 0.0000 sec, 2.4 MiB cytro: compiled and loaded 0.0000 sec, 2.4 MiB
* **!compiled and !loaded** - template engine object created but parsers not initialized and templates not compiled * **!compiled and !loaded** - template engine object created but parsers not initialized and templates not compiled
* **compiled and !loaded** - template engine object created, template compiled but not loaded * **compiled and !loaded** - template engine object created, template compiled but not loaded

View File

@@ -5,11 +5,11 @@ For installation use [composer](http://getcompoer.org). Add in your `composer.js
```json ```json
{ {
"require": { "require": {
"bzick/aspect": "dev-master" "bzick/cytro": "dev-master"
} }
} }
``` ```
or use shell or use shell
`composer require bzick/aspect` `composer require bzick/cytro`
If you do not use composer - use `psr-0` format for loading Aspect's classes. If you do not use composer - use `psr-0` format for loading Cytro's classes.

View File

@@ -1,7 +1,7 @@
Documentation Documentation
============= =============
### Aspect ### Cytro
* [About](./about.md) * [About](./about.md)
* [Install](./install.md) * [Install](./install.md)

View File

@@ -5,4 +5,5 @@ Modifier length [RU]
* если массив - длина массива * если массив - длина массива
* если итератор - длина итератора * если итератор - длина итератора
* если строка - длина строки (поддерживается UTF8 и не требует `mbstring`) * если строка - длина строки (поддерживается UTF8 и не требует `mbstring`)
* для других значений возвращается 0

View File

@@ -6,31 +6,31 @@ Settings [RU]
Что бы установить папку для хранения кеша собранных шаблонов Что бы установить папку для хранения кеша собранных шаблонов
```php ```php
$aspect->setCompileDir($dir); $cytro->setCompileDir($dir);
``` ```
### Template settings ### Template settings
```php ```php
// set options using factory // set options using factory
$aspect = Aspect::factory($tpl_dir, $compile_dir, $options); $cytro = Cytro::factory($tpl_dir, $compile_dir, $options);
// or inline using method setOptions // or inline using method setOptions
$aspect->setOptions($options); $cytro->setOptions($options);
``` ```
Параметры могут быть массивом `'option_name' => true` (если ключ не указан автоматически задаётся false) или битовой маской. Параметры могут быть массивом `'option_name' => true` (если ключ не указан автоматически задаётся false) или битовой маской.
* **disable_methods**, `Aspect::DENY_METHODS`, запретить вызов методов у объектов * **disable_methods**, `Cytro::DENY_METHODS`, запретить вызов методов у объектов
* **disable_native_funcs**, `Aspect::DENY_INLINE_FUNCS`, запретить использование PHP функций, кроме разрешенных * **disable_native_funcs**, `Cytro::DENY_INLINE_FUNCS`, запретить использование PHP функций, кроме разрешенных
* **auto_reload**, `Aspect::AUTO_RELOAD`, пересобирать шаблон если его оригинал был изменён (замедляет работу шаблонизатора). * **auto_reload**, `Cytro::AUTO_RELOAD`, пересобирать шаблон если его оригинал был изменён (замедляет работу шаблонизатора).
* **force_compile**, `Aspect::FORCE_COMPILE`, пересобирать шаблон при каждом вызове (сильно замедляет работу шаблонизатора). * **force_compile**, `Cytro::FORCE_COMPILE`, пересобирать шаблон при каждом вызове (сильно замедляет работу шаблонизатора).
* **force_include**, `Aspect::FORCE_INCLUDE`, оптимизировать вставку шаблона в шаблон. Это увеличит производительность и размер собранного шаблона. * **force_include**, `Cytro::FORCE_INCLUDE`, оптимизировать вставку шаблона в шаблон. Это увеличит производительность и размер собранного шаблона.
```php ```php
$aspect->setOptions(array( $cytro->setOptions(array(
"compile_check" => true, "compile_check" => true,
"force_include" => true "force_include" => true
)); ));
// same // same
$aspect->setOptions(Aspect::AUTO_RELOAD | Aspect::FORCE_INCLUDE); $cytro->setOptions(Cytro::AUTO_RELOAD | Cytro::FORCE_INCLUDE);
``` ```

View File

@@ -1,11 +1,11 @@
<?php <?php
use Aspect\Template, use Cytro\Template,
Aspect\ProviderInterface; Cytro\ProviderInterface;
/** /**
* Aspect Template Engine * Cytro Template Engine
*/ */
class Aspect { class Cytro {
const VERSION = '1.0.1'; const VERSION = '1.0.1';
const INLINE_COMPILER = 1; const INLINE_COMPILER = 1;
@@ -22,11 +22,11 @@ class Aspect {
const FORCE_COMPILE = 0xF0; const FORCE_COMPILE = 0xF0;
const DISABLE_CACHE = 0x1F0; const DISABLE_CACHE = 0x1F0;
const DEFAULT_CLOSE_COMPILER = 'Aspect\Compiler::stdClose'; const DEFAULT_CLOSE_COMPILER = 'Cytro\Compiler::stdClose';
const DEFAULT_FUNC_PARSER = 'Aspect\Compiler::stdFuncParser'; const DEFAULT_FUNC_PARSER = 'Cytro\Compiler::stdFuncParser';
const DEFAULT_FUNC_OPEN = 'Aspect\Compiler::stdFuncOpen'; const DEFAULT_FUNC_OPEN = 'Cytro\Compiler::stdFuncOpen';
const DEFAULT_FUNC_CLOSE = 'Aspect\Compiler::stdFuncClose'; const DEFAULT_FUNC_CLOSE = 'Cytro\Compiler::stdFuncClose';
const SMART_FUNC_PARSER = 'Aspect\Compiler::smartFuncParser'; const SMART_FUNC_PARSER = 'Cytro\Compiler::smartFuncParser';
/** /**
* @var array of possible options, as associative array * @var array of possible options, as associative array
@@ -64,7 +64,7 @@ class Aspect {
*/ */
private $_provider; private $_provider;
/** /**
* @var array of Aspect\ProviderInterface * @var array of Cytro\ProviderInterface
*/ */
protected $_providers = array(); protected $_providers = array();
@@ -76,14 +76,14 @@ class Aspect {
"up" => 'strtoupper', "up" => 'strtoupper',
"lower" => 'strtolower', "lower" => 'strtolower',
"low" => 'strtolower', "low" => 'strtolower',
"date_format" => 'Aspect\Modifier::dateFormat', "date_format" => 'Cytro\Modifier::dateFormat',
"date" => 'Aspect\Modifier::date', "date" => 'Cytro\Modifier::date',
"truncate" => 'Aspect\Modifier::truncate', "truncate" => 'Cytro\Modifier::truncate',
"escape" => 'Aspect\Modifier::escape', "escape" => 'Cytro\Modifier::escape',
"e" => 'Aspect\Modifier::escape', // alias of escape "e" => 'Cytro\Modifier::escape', // alias of escape
"unescape" => 'Aspect\Modifier::unescape', "unescape" => 'Cytro\Modifier::unescape',
"strip" => 'Aspect\Modifier::strip', "strip" => 'Cytro\Modifier::strip',
"default" => 'Aspect\Modifier::defaultValue' "default" => 'Cytro\Modifier::defaultValue'
); );
/** /**
@@ -101,116 +101,116 @@ class Aspect {
protected $_actions = array( protected $_actions = array(
'foreach' => array( // {foreach ...} {break} {continue} {foreachelse} {/foreach} 'foreach' => array( // {foreach ...} {break} {continue} {foreachelse} {/foreach}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::foreachOpen', 'open' => 'Cytro\Compiler::foreachOpen',
'close' => 'Aspect\Compiler::foreachClose', 'close' => 'Cytro\Compiler::foreachClose',
'tags' => array( 'tags' => array(
'foreachelse' => 'Aspect\Compiler::foreachElse', 'foreachelse' => 'Cytro\Compiler::foreachElse',
'break' => 'Aspect\Compiler::tagBreak', 'break' => 'Cytro\Compiler::tagBreak',
'continue' => 'Aspect\Compiler::tagContinue', 'continue' => 'Cytro\Compiler::tagContinue',
), ),
'float_tags' => array('break' => 1, 'continue' => 1) 'float_tags' => array('break' => 1, 'continue' => 1)
), ),
'if' => array( // {if ...} {elseif ...} {else} {/if} 'if' => array( // {if ...} {elseif ...} {else} {/if}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::ifOpen', 'open' => 'Cytro\Compiler::ifOpen',
'close' => 'Aspect\Compiler::stdClose', 'close' => 'Cytro\Compiler::stdClose',
'tags' => array( 'tags' => array(
'elseif' => 'Aspect\Compiler::tagElseIf', 'elseif' => 'Cytro\Compiler::tagElseIf',
'else' => 'Aspect\Compiler::tagElse', 'else' => 'Cytro\Compiler::tagElse',
) )
), ),
'switch' => array( // {switch ...} {case ...} {break} {default} {/switch} 'switch' => array( // {switch ...} {case ...} {break} {default} {/switch}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::switchOpen', 'open' => 'Cytro\Compiler::switchOpen',
'close' => 'Aspect\Compiler::stdClose', 'close' => 'Cytro\Compiler::stdClose',
'tags' => array( 'tags' => array(
'case' => 'Aspect\Compiler::tagCase', 'case' => 'Cytro\Compiler::tagCase',
'default' => 'Aspect\Compiler::tagDefault', 'default' => 'Cytro\Compiler::tagDefault',
'break' => 'Aspect\Compiler::tagBreak', 'break' => 'Cytro\Compiler::tagBreak',
), ),
'float_tags' => array('break' => 1) 'float_tags' => array('break' => 1)
), ),
'for' => array( // {for ...} {break} {continue} {/for} 'for' => array( // {for ...} {break} {continue} {/for}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::forOpen', 'open' => 'Cytro\Compiler::forOpen',
'close' => 'Aspect\Compiler::forClose', 'close' => 'Cytro\Compiler::forClose',
'tags' => array( 'tags' => array(
'forelse' => 'Aspect\Compiler::forElse', 'forelse' => 'Cytro\Compiler::forElse',
'break' => 'Aspect\Compiler::tagBreak', 'break' => 'Cytro\Compiler::tagBreak',
'continue' => 'Aspect\Compiler::tagContinue', 'continue' => 'Cytro\Compiler::tagContinue',
), ),
'float_tags' => array('break' => 1, 'continue' => 1) 'float_tags' => array('break' => 1, 'continue' => 1)
), ),
'while' => array( // {while ...} {break} {continue} {/while} 'while' => array( // {while ...} {break} {continue} {/while}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::whileOpen', 'open' => 'Cytro\Compiler::whileOpen',
'close' => 'Aspect\Compiler::stdClose', 'close' => 'Cytro\Compiler::stdClose',
'tags' => array( 'tags' => array(
'break' => 'Aspect\Compiler::tagBreak', 'break' => 'Cytro\Compiler::tagBreak',
'continue' => 'Aspect\Compiler::tagContinue', 'continue' => 'Cytro\Compiler::tagContinue',
), ),
'float_tags' => array('break' => 1, 'continue' => 1) 'float_tags' => array('break' => 1, 'continue' => 1)
), ),
'include' => array( // {include ...} 'include' => array( // {include ...}
'type' => self::INLINE_COMPILER, 'type' => self::INLINE_COMPILER,
'parser' => 'Aspect\Compiler::tagInclude' 'parser' => 'Cytro\Compiler::tagInclude'
), ),
'var' => array( // {var ...} 'var' => array( // {var ...}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::varOpen', 'open' => 'Cytro\Compiler::varOpen',
'close' => 'Aspect\Compiler::varClose' 'close' => 'Cytro\Compiler::varClose'
), ),
'block' => array( // {block ...} {parent} {/block} 'block' => array( // {block ...} {parent} {/block}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::tagBlockOpen', 'open' => 'Cytro\Compiler::tagBlockOpen',
'close' => 'Aspect\Compiler::tagBlockClose', 'close' => 'Cytro\Compiler::tagBlockClose',
'tags' => array( 'tags' => array(
'parent' => 'Aspect\Compiler::tagParent' 'parent' => 'Cytro\Compiler::tagParent'
), ),
'float_tags' => array('parent' => 1) 'float_tags' => array('parent' => 1)
), ),
'extends' => array( // {extends ...} 'extends' => array( // {extends ...}
'type' => self::INLINE_COMPILER, 'type' => self::INLINE_COMPILER,
'parser' => 'Aspect\Compiler::tagExtends' 'parser' => 'Cytro\Compiler::tagExtends'
), ),
'use' => array( // {use} 'use' => array( // {use}
'type' => self::INLINE_COMPILER, 'type' => self::INLINE_COMPILER,
'parser' => 'Aspect\Compiler::tagUse' 'parser' => 'Cytro\Compiler::tagUse'
), ),
'capture' => array( // {capture ...} {/capture} 'capture' => array( // {capture ...} {/capture}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::captureOpen', 'open' => 'Cytro\Compiler::captureOpen',
'close' => 'Aspect\Compiler::captureClose' 'close' => 'Cytro\Compiler::captureClose'
), ),
'filter' => array( // {filter} ... {/filter} 'filter' => array( // {filter} ... {/filter}
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::filterOpen', 'open' => 'Cytro\Compiler::filterOpen',
'close' => 'Aspect\Compiler::filterClose' 'close' => 'Cytro\Compiler::filterClose'
), ),
'macro' => array( 'macro' => array(
'type' => self::BLOCK_COMPILER, 'type' => self::BLOCK_COMPILER,
'open' => 'Aspect\Compiler::macroOpen', 'open' => 'Cytro\Compiler::macroOpen',
'close' => 'Aspect\Compiler::macroClose' 'close' => 'Cytro\Compiler::macroClose'
), ),
'import' => array( 'import' => array(
'type' => self::INLINE_COMPILER, 'type' => self::INLINE_COMPILER,
'parser' => 'Aspect\Compiler::tagImport' 'parser' => 'Cytro\Compiler::tagImport'
) )
); );
/** /**
* Just factory * Just factory
* *
* @param string|Aspect\ProviderInterface $source path to templates or custom provider * @param string|Cytro\ProviderInterface $source path to templates or custom provider
* @param string $compile_dir path to compiled files * @param string $compile_dir path to compiled files
* @param int $options * @param int $options
* @throws InvalidArgumentException * @throws InvalidArgumentException
* @return Aspect * @return Cytro
*/ */
public static function factory($source, $compile_dir = '/tmp', $options = 0) { public static function factory($source, $compile_dir = '/tmp', $options = 0) {
if(is_string($source)) { if(is_string($source)) {
$provider = new \Aspect\FSProvider($source); $provider = new Cytro\FSProvider($source);
} elseif($source instanceof Aspect\ProviderInterface) { } elseif($source instanceof ProviderInterface) {
$provider = $source; $provider = $source;
} else { } else {
throw new InvalidArgumentException("Source must be a valid path or provider object"); throw new InvalidArgumentException("Source must be a valid path or provider object");
@@ -224,16 +224,16 @@ class Aspect {
} }
/** /**
* @param Aspect\ProviderInterface $provider * @param Cytro\ProviderInterface $provider
*/ */
public function __construct(Aspect\ProviderInterface $provider) { public function __construct(Cytro\ProviderInterface $provider) {
$this->_provider = $provider; $this->_provider = $provider;
} }
/** /**
* Set compile directory * Set compile directory
* @param string $dir directory to store compiled templates in * @param string $dir directory to store compiled templates in
* @return Aspect * @return Cytro
*/ */
public function setCompileDir($dir) { public function setCompileDir($dir) {
$this->_compile_dir = $dir; $this->_compile_dir = $dir;
@@ -268,7 +268,7 @@ class Aspect {
* *
* @param string $modifier * @param string $modifier
* @param string $callback * @param string $callback
* @return Aspect * @return Cytro
*/ */
public function addModifier($modifier, $callback) { public function addModifier($modifier, $callback) {
$this->_modifiers[$modifier] = $callback; $this->_modifiers[$modifier] = $callback;
@@ -280,7 +280,7 @@ class Aspect {
* *
* @param string $compiler * @param string $compiler
* @param callable $parser * @param callable $parser
* @return Aspect * @return Cytro
*/ */
public function addCompiler($compiler, $parser) { public function addCompiler($compiler, $parser) {
$this->_actions[$compiler] = array( $this->_actions[$compiler] = array(
@@ -312,7 +312,7 @@ class Aspect {
* @param callable $open_parser * @param callable $open_parser
* @param callable|string $close_parser * @param callable|string $close_parser
* @param array $tags * @param array $tags
* @return Aspect * @return Cytro
*/ */
public function addBlockCompiler($compiler, $open_parser, $close_parser = self::DEFAULT_CLOSE_COMPILER, array $tags = array()) { public function addBlockCompiler($compiler, $open_parser, $close_parser = self::DEFAULT_CLOSE_COMPILER, array $tags = array()) {
$this->_actions[$compiler] = array( $this->_actions[$compiler] = array(
@@ -330,7 +330,7 @@ class Aspect {
* @param array $tags * @param array $tags
* @param array $floats * @param array $floats
* @throws LogicException * @throws LogicException
* @return Aspect * @return Cytro
*/ */
public function addBlockCompilerSmart($compiler, $storage, array $tags, array $floats = array()) { public function addBlockCompilerSmart($compiler, $storage, array $tags, array $floats = array()) {
$c = array( $c = array(
@@ -366,7 +366,7 @@ class Aspect {
* @param string $function * @param string $function
* @param callable $callback * @param callable $callback
* @param callable|string $parser * @param callable|string $parser
* @return Aspect * @return Cytro
*/ */
public function addFunction($function, $callback, $parser = self::DEFAULT_FUNC_PARSER) { public function addFunction($function, $callback, $parser = self::DEFAULT_FUNC_PARSER) {
$this->_actions[$function] = array( $this->_actions[$function] = array(
@@ -380,7 +380,7 @@ class Aspect {
/** /**
* @param string $function * @param string $function
* @param callable $callback * @param callable $callback
* @return Aspect * @return Cytro
*/ */
public function addFunctionSmart($function, $callback) { public function addFunctionSmart($function, $callback) {
$this->_actions[$function] = array( $this->_actions[$function] = array(
@@ -396,7 +396,7 @@ class Aspect {
* @param callable $callback * @param callable $callback
* @param callable|string $parser_open * @param callable|string $parser_open
* @param callable|string $parser_close * @param callable|string $parser_close
* @return Aspect * @return Cytro
*/ */
public function addBlockFunction($function, $callback, $parser_open = self::DEFAULT_FUNC_OPEN, $parser_close = self::DEFAULT_FUNC_CLOSE) { public function addBlockFunction($function, $callback, $parser_open = self::DEFAULT_FUNC_OPEN, $parser_close = self::DEFAULT_FUNC_CLOSE) {
$this->_actions[$function] = array( $this->_actions[$function] = array(
@@ -410,7 +410,7 @@ class Aspect {
/** /**
* @param array $funcs * @param array $funcs
* @return Aspect * @return Cytro
*/ */
public function addAllowedFunctions(array $funcs) { public function addAllowedFunctions(array $funcs) {
$this->_allowed_funcs = $this->_allowed_funcs + array_flip($funcs); $this->_allowed_funcs = $this->_allowed_funcs + array_flip($funcs);
@@ -478,9 +478,9 @@ class Aspect {
* Add source template provider by scheme * Add source template provider by scheme
* *
* @param string $scm scheme name * @param string $scm scheme name
* @param Aspect\ProviderInterface $provider provider object * @param Cytro\ProviderInterface $provider provider object
*/ */
public function addProvider($scm, \Aspect\ProviderInterface $provider) { public function addProvider($scm, \Cytro\ProviderInterface $provider) {
$this->_providers[$scm] = $provider; $this->_providers[$scm] = $provider;
} }
@@ -511,7 +511,7 @@ class Aspect {
/** /**
* @param bool|string $scm * @param bool|string $scm
* @return Aspect\ProviderInterface * @return Cytro\ProviderInterface
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function getProvider($scm = false) { public function getProvider($scm = false) {
@@ -529,10 +529,10 @@ class Aspect {
/** /**
* Return empty template * Return empty template
* *
* @return Aspect\Template * @return Cytro\Template
*/ */
public function getRawTemplate() { public function getRawTemplate() {
return new \Aspect\Template($this); return new \Cytro\Template($this, $this->_options);
} }
/** /**
@@ -540,7 +540,7 @@ class Aspect {
* *
* @param string $template name of template * @param string $template name of template
* @param array $vars array of data for template * @param array $vars array of data for template
* @return Aspect\Render * @return Cytro\Render
*/ */
public function display($template, array $vars = array()) { public function display($template, array $vars = array()) {
return $this->getTemplate($template)->display($vars); return $this->getTemplate($template)->display($vars);
@@ -562,13 +562,13 @@ class Aspect {
* *
* @param string $template * @param string $template
* @param int $options * @param int $options
* @return Aspect\Template * @return Cytro\Template
*/ */
public function getTemplate($template, $options = 0) { public function getTemplate($template, $options = 0) {
$options = $this->_options | $options; $options = $this->_options | $options;
$key = $template.".".dechex($options); $key = $template.".".dechex($options);
if(isset($this->_storage[ $key ])) { if(isset($this->_storage[ $key ])) {
/** @var Aspect\Template $tpl */ /** @var Cytro\Template $tpl */
$tpl = $this->_storage[ $key ]; $tpl = $this->_storage[ $key ];
if(($this->_options & self::AUTO_RELOAD) && !$tpl->isValid()) { if(($this->_options & self::AUTO_RELOAD) && !$tpl->isValid()) {
return $this->_storage[ $key ] = $this->compile($template, true, $options); return $this->_storage[ $key ] = $this->compile($template, true, $options);
@@ -584,10 +584,10 @@ class Aspect {
/** /**
* Add custom template into storage * Add custom template into storage
* @param Aspect\Render $template * @param Cytro\Render $template
*/ */
public function addTemplate(Aspect\Render $template, $options = 0) { public function addTemplate(Cytro\Render $template) {
$this->_storage[ $template->getName().".".dechex($options) ] = $template; $this->_storage[ $template->getName().".".dechex($template->getOptions()) ] = $template;
} }
/** /**
@@ -595,7 +595,7 @@ class Aspect {
* *
* @param string $tpl * @param string $tpl
* @param int $opts * @param int $opts
* @return Aspect\Render * @return Cytro\Render
*/ */
protected function _load($tpl, $opts) { protected function _load($tpl, $opts) {
$file_name = $this->_getCacheName($tpl, $opts); $file_name = $this->_getCacheName($tpl, $opts);
@@ -624,14 +624,15 @@ class Aspect {
* *
* @param string $tpl * @param string $tpl
* @param bool $store store template on disk * @param bool $store store template on disk
* @param int $opts * @param int $options
* @throws RuntimeException * @throws RuntimeException
* @return \Aspect\Template * @return \Cytro\Template
*/ */
public function compile($tpl, $store = true, $opts = 0) { public function compile($tpl, $store = true, $options = 0) {
$template = Template::factory($this)->load($tpl); $options = $this->_options | $options;
$template = Template::factory($this, $options)->load($tpl);
if($store) { if($store) {
$cache = $this->_getCacheName($tpl, $opts); $cache = $this->_getCacheName($tpl, $options);
$tpl_tmp = tempnam($this->_compile_dir, $cache); $tpl_tmp = tempnam($this->_compile_dir, $cache);
$tpl_fp = fopen($tpl_tmp, "w"); $tpl_fp = fopen($tpl_tmp, "w");
if(!$tpl_fp) { if(!$tpl_fp) {
@@ -673,7 +674,7 @@ class Aspect {
* *
*/ */
public function clearAllCompiles() { public function clearAllCompiles() {
\Aspect\FSProvider::clean($this->_compile_dir); \Cytro\FSProvider::clean($this->_compile_dir);
} }
/** /**
@@ -681,10 +682,10 @@ class Aspect {
* *
* @param string $code * @param string $code
* @param string $name * @param string $name
* @return Aspect\Template * @return Cytro\Template
*/ */
public function compileCode($code, $name = 'Runtime compile') { public function compileCode($code, $name = 'Runtime compile') {
return Template::factory($this)->source($name, $code); return Template::factory($this, $this->_options)->source($name, $code);
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect\Tokenizer; use Cytro\Tokenizer;
use Aspect\Template; use Cytro\Template;
use Aspect\Scope; use Cytro\Scope;
/** /**
* Compilers collection * Compilers collection
@@ -21,7 +21,7 @@ class Compiler {
$cname = $tpl->parseFirstArg($tokens, $name); $cname = $tpl->parseFirstArg($tokens, $name);
$p = $tpl->parseParams($tokens); $p = $tpl->parseParams($tokens);
if($p) { // if we have additionally variables if($p) { // if we have additionally variables
if($name && ($tpl->getStorage()->getOptions() & \Aspect::FORCE_INCLUDE)) { // if FORCE_INCLUDE enabled and template name known if($name && ($tpl->getStorage()->getOptions() & \Cytro::FORCE_INCLUDE)) { // if FORCE_INCLUDE enabled and template name known
$inc = $tpl->getStorage()->compile($name, false); $inc = $tpl->getStorage()->compile($name, false);
$tpl->addDepend($inc); $tpl->addDepend($inc);
return '$_tpl = (array)$tpl; $tpl->exchangeArray('.self::toArray($p).'+$_tpl); ?>'.$inc->_body.'<?php $tpl->exchangeArray($_tpl); unset($_tpl);'; return '$_tpl = (array)$tpl; $tpl->exchangeArray('.self::toArray($p).'+$_tpl); ?>'.$inc->_body.'<?php $tpl->exchangeArray($_tpl); unset($_tpl);';
@@ -29,7 +29,7 @@ class Compiler {
return '$tpl->getStorage()->getTemplate('.$cname.')->display('.self::toArray($p).'+(array)$tpl);'; return '$tpl->getStorage()->getTemplate('.$cname.')->display('.self::toArray($p).'+(array)$tpl);';
} }
} else { } else {
if($name && ($tpl->getStorage()->getOptions() & \Aspect::FORCE_INCLUDE)) { // if FORCE_INCLUDE enabled and template name known if($name && ($tpl->getStorage()->getOptions() & \Cytro::FORCE_INCLUDE)) { // if FORCE_INCLUDE enabled and template name known
$inc = $tpl->getStorage()->compile($name, false); $inc = $tpl->getStorage()->compile($name, false);
$tpl->addDepend($inc); $tpl->addDepend($inc);
return '$_tpl = (array)$tpl; ?>'.$inc->_body.'<?php $tpl->exchangeArray($_tpl); unset($_tpl);'; return '$_tpl = (array)$tpl; ?>'.$inc->_body.'<?php $tpl->exchangeArray($_tpl); unset($_tpl);';
@@ -375,14 +375,19 @@ class Compiler {
if(empty($tpl->_extended)) { if(empty($tpl->_extended)) {
$tpl->addPostCompile(__CLASS__."::extendBody"); $tpl->addPostCompile(__CLASS__."::extendBody");
} }
/*if($tpl->getOptions() & Template::EXTENDED) {
$tpl->_compatible = true;
} else {
$tpl->_compatible = false;
}*/
if($name) { // static extends if($name) { // static extends
$tpl->_extends = $tpl->getStorage()->getRawTemplate()->load($name, false); $tpl->_extends = $tpl->getStorage()->getRawTemplate()->load($name, false);
$tpl->_compatible = &$tpl->_extends->_compatible; $tpl->_compatible = &$tpl->_extends->_compatible;
$tpl->addDepend($tpl->_extends); // for valid compile-time need take template from storage $tpl->addDepend($tpl->_extends);
return ""; return "";
} else { // dynamic extends } else { // dynamic extends
$tpl->_extends = $tpl_name; $tpl->_extends = $tpl_name;
return '$parent = $tpl->getStorage()->getTemplate('.$tpl_name.', \Aspect\Template::EXTENDED);'; return '$parent = $tpl->getStorage()->getTemplate('.$tpl_name.', \Cytro\Template::EXTENDED);';
} }
} }

View File

@@ -1,7 +1,7 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect\ProviderInterface; use Cytro\ProviderInterface;
/** /**
* Templates provider * Templates provider
* @author Ivan Shalganov * @author Ivan Shalganov

View File

@@ -1,13 +1,13 @@
<?php <?php
/* /*
* This file is part of Aspect. * This file is part of Cytro.
* *
* (c) 2013 Ivan Shalganov * (c) 2013 Ivan Shalganov
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Aspect; namespace Cytro;
/** /**
* Collection of modifiers * Collection of modifiers
@@ -140,7 +140,7 @@ class Modifier {
return strlen(preg_replace('#[\x00-\x7F]|[\x80-\xDF][\x00-\xBF]|[\xE0-\xEF][\x00-\xBF]{2}#s', ' ', $item)); return strlen(preg_replace('#[\x00-\x7F]|[\x80-\xDF][\x00-\xBF]|[\xE0-\xEF][\x00-\xBF]{2}#s', ' ', $item));
} elseif (is_array($item)) { } elseif (is_array($item)) {
return count($item); return count($item);
} elseif(is_object($item) && ($item instanceof \Countable)) { } elseif($item instanceof \Countable) {
return count($item); return count($item);
} else { } else {
return 0; return 0;

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace Aspect; namespace Cytro;
interface ProviderInterface { interface ProviderInterface {
/** /**

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect; use Cytro;
/** /**
* Primitive template * Primitive template
@@ -25,7 +25,7 @@ class Render extends \ArrayObject {
protected $_scm = false; protected $_scm = false;
protected $_base_name = 'runtime'; protected $_base_name = 'runtime';
/** /**
* @var Aspect * @var Cytro
*/ */
protected $_aspect; protected $_aspect;
/** /**
@@ -36,6 +36,8 @@ class Render extends \ArrayObject {
protected $_depends = array(); protected $_depends = array();
protected $_options = 0;
/** /**
* Template provider * Template provider
* @var ProviderInterface * @var ProviderInterface
@@ -43,11 +45,11 @@ class Render extends \ArrayObject {
protected $_provider; protected $_provider;
/** /**
* @param Aspect $aspect * @param Cytro $aspect
* @param callable $code template body * @param callable $code template body
* @param array $props * @param array $props
*/ */
public function __construct(Aspect $aspect, \Closure $code, $props = array()) { public function __construct(Cytro $aspect, \Closure $code, $props = array()) {
$this->_aspect = $aspect; $this->_aspect = $aspect;
$props += self::$_props; $props += self::$_props;
$this->_name = $props["name"]; $this->_name = $props["name"];
@@ -60,7 +62,7 @@ class Render extends \ArrayObject {
/** /**
* Get template storage * Get template storage
* @return Aspect * @return Cytro
*/ */
public function getStorage() { public function getStorage() {
return $this->_aspect; return $this->_aspect;
@@ -82,6 +84,10 @@ class Render extends \ArrayObject {
return $this->_base_name; return $this->_base_name;
} }
public function getOptions() {
return $this->_options;
}
/** /**
* @return string * @return string
*/ */

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace Aspect; namespace Cytro;
/** /**
* Scope for blocks tags * Scope for blocks tags

View File

@@ -1,14 +1,14 @@
<?php <?php
/* /*
* This file is part of Aspect. * This file is part of Cytro.
* *
* (c) 2013 Ivan Shalganov * (c) 2013 Ivan Shalganov
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Aspect; namespace Cytro;
use Aspect; use Cytro;
/** /**
* Template compiler * Template compiler
@@ -58,32 +58,26 @@ class Template extends Render {
*/ */
private $_pos = 0; private $_pos = 0;
private $_line = 1; private $_line = 1;
private $_trim = false;
private $_post = array(); private $_post = array();
/** /**
* @var bool * @var bool
*/ */
private $_ignore = false; private $_ignore = false;
/**
* Options
* @var int
*/
private $_options = 0;
/** /**
* Just factory * Just factory
* *
* @param \Aspect $aspect * @param \Cytro $aspect
* @return Template * @return Template
*/ */
public static function factory(Aspect $aspect) { public static function factory(Cytro $aspect, $options) {
return new static($aspect); return new static($aspect, $options);
} }
/** /**
* @param Aspect $aspect Template storage * @param Cytro $aspect Template storage
*/ */
public function __construct(Aspect $aspect) { public function __construct(Cytro $aspect, $options) {
$this->_aspect = $aspect; $this->_aspect = $aspect;
$this->_options = $this->_aspect->getOptions(); $this->_options = $this->_aspect->getOptions();
} }
@@ -92,7 +86,7 @@ class Template extends Render {
* Load source from provider * Load source from provider
* @param string $name * @param string $name
* @param bool $compile * @param bool $compile
* @return \Aspect\Template * @return \Cytro\Template
*/ */
public function load($name, $compile = true) { public function load($name, $compile = true) {
$this->_name = $name; $this->_name = $name;
@@ -115,7 +109,7 @@ class Template extends Render {
* @param string $name template name * @param string $name template name
* @param string $src template source * @param string $src template source
* @param bool $compile * @param bool $compile
* @return \Aspect\Template * @return \Cytro\Template
*/ */
public function source($name, $src, $compile = true) { public function source($name, $src, $compile = true) {
$this->_name = $name; $this->_name = $name;
@@ -275,8 +269,8 @@ class Template extends Render {
*/ */
public function getTemplateCode() { public function getTemplateCode() {
return "<?php \n". return "<?php \n".
"/** Aspect template '".$this->_name."' compiled at ".date('Y-m-d H:i:s')." */\n". "/** Cytro template '".$this->_name."' compiled at ".date('Y-m-d H:i:s')." */\n".
"return new Aspect\\Render(\$aspect, ".$this->_getClosureSource().", ".var_export(array( "return new Cytro\\Render(\$aspect, ".$this->_getClosureSource().", ".var_export(array(
"options" => $this->_options, "options" => $this->_options,
"provider" => $this->_scm, "provider" => $this->_scm,
"name" => $this->_name, "name" => $this->_name,
@@ -422,18 +416,18 @@ class Template extends Render {
if($act = $this->_aspect->getFunction($action)) { // call some function if($act = $this->_aspect->getFunction($action)) { // call some function
switch($act["type"]) { switch($act["type"]) {
case Aspect::BLOCK_COMPILER: case Cytro::BLOCK_COMPILER:
$scope = new Scope($action, $this, $this->_line, $act, count($this->_stack), $this->_body); $scope = new Scope($action, $this, $this->_line, $act, count($this->_stack), $this->_body);
$code = $scope->open($tokens); $code = $scope->open($tokens);
if(!$scope->is_closed) { if(!$scope->is_closed) {
array_push($this->_stack, $scope); array_push($this->_stack, $scope);
} }
return $code; return $code;
case Aspect::INLINE_COMPILER: case Cytro::INLINE_COMPILER:
return call_user_func($act["parser"], $tokens, $this); return call_user_func($act["parser"], $tokens, $this);
case Aspect::INLINE_FUNCTION: case Cytro::INLINE_FUNCTION:
return call_user_func($act["parser"], $act["function"], $tokens, $this); return call_user_func($act["parser"], $act["function"], $tokens, $this);
case Aspect::BLOCK_FUNCTION: case Cytro::BLOCK_FUNCTION:
$scope = new Scope($action, $this, $this->_line, $act, count($this->_stack), $this->_body); $scope = new Scope($action, $this, $this->_line, $act, count($this->_stack), $this->_body);
$scope->setFuncName($act["function"]); $scope->setFuncName($act["function"]);
array_push($this->_stack, $scope); array_push($this->_stack, $scope);
@@ -641,7 +635,7 @@ class Template extends Render {
} elseif($t === T_OBJECT_OPERATOR) { } elseif($t === T_OBJECT_OPERATOR) {
$prop = $tokens->getNext(T_STRING); $prop = $tokens->getNext(T_STRING);
if($tokens->isNext("(")) { if($tokens->isNext("(")) {
if($this->_options & Aspect::DENY_METHODS) { if($this->_options & Cytro::DENY_METHODS) {
throw new \LogicException("Forbidden to call methods"); throw new \LogicException("Forbidden to call methods");
} }
$pure_var = false; $pure_var = false;

View File

@@ -1,13 +1,13 @@
<?php <?php
/* /*
* This file is part of Aspect. * This file is part of Cytro.
* *
* (c) 2013 Ivan Shalganov * (c) 2013 Ivan Shalganov
* *
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Aspect; namespace Cytro;
defined('T_INSTEADOF') || define('T_INSTEADOF', 341); defined('T_INSTEADOF') || define('T_INSTEADOF', 341);
defined('T_TRAIT') || define('T_TRAIT', 355); defined('T_TRAIT') || define('T_TRAIT', 355);

View File

@@ -1,32 +1,41 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect, Aspect\FSProvider as FS; use Cytro, Cytro\FSProvider as FS;
class TestCase extends \PHPUnit_Framework_TestCase { class TestCase extends \PHPUnit_Framework_TestCase {
/** /**
* @var Aspect * @var Cytro
*/ */
public $aspect; public $cytro;
public $values = array(
"one" => 1,
"two" => 2,
"three" => 3,
1 => "one value",
2 => "two value",
3 => "three value",
);
public function setUp() { public function setUp() {
if(!file_exists(ASPECT_RESOURCES.'/compile')) { if(!file_exists(CYTRO_RESOURCES.'/compile')) {
mkdir(ASPECT_RESOURCES.'/compile', 0777, true); mkdir(CYTRO_RESOURCES.'/compile', 0777, true);
} else { } else {
FS::clean(ASPECT_RESOURCES.'/compile/'); FS::clean(CYTRO_RESOURCES.'/compile/');
} }
$this->aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile'); $this->cytro = Cytro::factory(CYTRO_RESOURCES.'/template', CYTRO_RESOURCES.'/compile');
} }
public static function setUpBeforeClass() { public static function setUpBeforeClass() {
if(!file_exists(ASPECT_RESOURCES.'/template')) { if(!file_exists(CYTRO_RESOURCES.'/template')) {
mkdir(ASPECT_RESOURCES.'/template', 0777, true); mkdir(CYTRO_RESOURCES.'/template', 0777, true);
} else { } else {
FS::clean(ASPECT_RESOURCES.'/template/'); FS::clean(CYTRO_RESOURCES.'/template/');
} }
} }
public function tpl($name, $code) { public function tpl($name, $code) {
file_put_contents(ASPECT_RESOURCES.'/template/'.$name, $code); file_put_contents(CYTRO_RESOURCES.'/template/'.$name, $code);
} }
/** /**
@@ -38,7 +47,7 @@ class TestCase extends \PHPUnit_Framework_TestCase {
* @param bool $dump dump source and result code (for debug) * @param bool $dump dump source and result code (for debug)
*/ */
public function exec($code, $vars, $result, $dump = false) { public function exec($code, $vars, $result, $dump = false) {
$tpl = $this->aspect->compileCode($code, "runtime.tpl"); $tpl = $this->cytro->compileCode($code, "runtime.tpl");
if($dump) { if($dump) {
echo "\n========= DUMP BEGIN ===========\n".$code."\n--- to ---\n".$tpl->getBody()."\n========= DUMP END =============\n"; echo "\n========= DUMP BEGIN ===========\n".$code."\n--- to ---\n".$tpl->getBody()."\n========= DUMP END =============\n";
} }
@@ -47,7 +56,7 @@ class TestCase extends \PHPUnit_Framework_TestCase {
public function execTpl($name, $code, $vars, $result, $dump = false) { public function execTpl($name, $code, $vars, $result, $dump = false) {
$this->tpl($name, $code); $this->tpl($name, $code);
$tpl = $this->aspect->getTemplate($name); $tpl = $this->cytro->getTemplate($name);
if($dump) { if($dump) {
echo "\n========= DUMP BEGIN ===========\n".$code."\n--- to ---\n".$tpl->getBody()."\n========= DUMP END =============\n"; echo "\n========= DUMP BEGIN ===========\n".$code."\n--- to ---\n".$tpl->getBody()."\n========= DUMP END =============\n";
} }
@@ -59,20 +68,49 @@ class TestCase extends \PHPUnit_Framework_TestCase {
* @param string $code source of the template * @param string $code source of the template
* @param string $exception exception class * @param string $exception exception class
* @param string $message exception message * @param string $message exception message
* @param int $options Aspect's options * @param int $options Cytro's options
*/ */
public function execError($code, $exception, $message, $options = 0) { public function execError($code, $exception, $message, $options = 0) {
$opt = $this->aspect->getOptions(); $opt = $this->cytro->getOptions();
$this->aspect->setOptions($options); $this->cytro->setOptions($options);
try { try {
$this->aspect->compileCode($code, "inline.tpl"); $this->cytro->compileCode($code, "inline.tpl");
} catch(\Exception $e) { } catch(\Exception $e) {
$this->assertSame($exception, get_class($e), "Exception $code"); $this->assertSame($exception, get_class($e), "Exception $code");
$this->assertStringStartsWith($message, $e->getMessage()); $this->assertStringStartsWith($message, $e->getMessage());
$this->aspect->setOptions($opt); $this->cytro->setOptions($opt);
return; return;
} }
self::$aspect->setOptions($opt); $this->cytro->setOptions($opt);
$this->fail("Code $code must be invalid"); $this->fail("Code $code must be invalid");
} }
public function assertRender($tpl, $result) {
$template = $this->cytro->compileCode($tpl);
$this->assertSame($result, $template->fetch($this->values));
}
}
class Fake implements \ArrayAccess {
public $vars;
public function offsetExists($offset) {
return true;
}
public function offsetGet($offset) {
if($offset == "object") {
return new self();
} else {
return new self($offset);
}
}
public function offsetSet($offset, $value) {
$this->vars[$offset] = $value;
}
public function offsetUnset($offset) {
unset($this->vars[$offset]);
}
} }

View File

@@ -4,9 +4,9 @@ require_once __DIR__."/../vendor/autoload.php";
define('ASPECT_RESOURCES', __DIR__."/resources"); define('CYTRO_RESOURCES', __DIR__."/resources");
require_once ASPECT_RESOURCES."/actions.php"; require_once CYTRO_RESOURCES."/actions.php";
require_once __DIR__."/TestCase.php"; require_once __DIR__."/TestCase.php";
function drop() { function drop() {

View File

@@ -0,0 +1,17 @@
<?php
namespace Cytro;
class CustomProvider extends TestCase {
public function setUp() {
$this->setUp();
$this->cytro->addProvider("my", new FSProvider(CYTRO_RESOURCES.'/provider'));
}
public function testCustom() {
$this->render("start: {include 'my:include.tpl'}", 'start: include template');
$this->render("start: {import 'my:macros.tpl' as ops} {ops.add a=3 b=6}");
}
}

View File

@@ -1,10 +1,11 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect, Aspect\Modifier, Aspect\TestCase; use Cytro, Cytro\TestCase;
use Symfony\Component\Process\Exception\LogicException;
class ExtendsTemplateTest extends TestCase { class ExtendsTemplateTest extends TestCase {
public static function providerExtends() {
$a = array("one" => 1, "two" => 2, "three" => 3); public static function providerExtends($items) {
return array( return array(
array("parent.tpl", "Parent. B1: {block b1}{/block}\nB2: {block 'b2'}empty {\$iteration}{/block}", $a, array("parent.tpl", "Parent. B1: {block b1}{/block}\nB2: {block 'b2'}empty {\$iteration}{/block}", $a,
"Parent. B1: \nB2: empty 0"), "Parent. B1: \nB2: empty 0"),
@@ -23,6 +24,10 @@ class ExtendsTemplateTest extends TestCase {
return $data; return $data;
} }
public function setUp() {
$this->cytro = Cytro::factory(CYTRO_RESOURCES.'/template', CYTRO_RESOURCES.'/compile');
}
/** /**
* @dataProvider providerExtends * @dataProvider providerExtends
* @param $name * @param $name
@@ -30,7 +35,7 @@ class ExtendsTemplateTest extends TestCase {
* @param $vars * @param $vars
* @param $result * @param $result
*/ */
public function testStaticExtends($name, $code, $vars, $result) { public function _testStaticExtends($name, $code, $vars, $result) {
static $i = 0; static $i = 0;
$vars["iteration"] = $i++; $vars["iteration"] = $i++;
$this->execTpl($name, $code, $vars, $result); $this->execTpl($name, $code, $vars, $result);
@@ -43,7 +48,7 @@ class ExtendsTemplateTest extends TestCase {
* @param $vars * @param $vars
* @param $result * @param $result
*/ */
public function testDynamicExtends($name, $code, $vars, $result) { public function _testDynamicExtends($name, $code, $vars, $result) {
static $i = 0; static $i = 0;
$vars["iteration"] = $i++; $vars["iteration"] = $i++;
$this->execTpl($name, $code, $vars, $result, 0); $this->execTpl($name, $code, $vars, $result, 0);
@@ -54,7 +59,7 @@ class ExtendsTemplateTest extends TestCase {
*/ */
public function _testParentLevel() { public function _testParentLevel() {
//echo($this->aspect->getTemplate("parent.tpl")->_body); exit; //echo($this->aspect->getTemplate("parent.tpl")->_body); exit;
$this->assertSame($this->aspect->fetch("parent.tpl", array("a" => "a char")), "Parent template\nBlock1: Block2: Block3: default"); $this->assertSame($this->cytro->fetch("parent.tpl", array("a" => "a char")), "Parent template\nBlock1: Block2: Block3: default");
} }
/** /**
@@ -68,7 +73,7 @@ class ExtendsTemplateTest extends TestCase {
* @group extends * @group extends
*/ */
public function _testChildLevel3() { public function _testChildLevel3() {
echo($this->aspect->getTemplate("child3.tpl")->getBody()); exit; echo($this->cytro->getTemplate("child3.tpl")->getBody()); exit;
} }
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace Aspect; namespace Cytro;
class MacrosTest extends TestCase { class MacrosTest extends TestCase {
@@ -45,30 +45,30 @@ class MacrosTest extends TestCase {
} }
public function testMacros() { public function testMacros() {
$tpl = $this->aspect->compile('math.tpl'); $tpl = $this->cytro->compile('math.tpl');
$this->assertStringStartsWith('x + y = ', trim($tpl->macros["plus"]["body"])); $this->assertStringStartsWith('x + y = ', trim($tpl->macros["plus"]["body"]));
$this->assertSame('Math: x + y = 5 , x - y - z = 6', Modifier::strip($tpl->fetch(array()), true)); $this->assertSame('Math: x + y = 5 , x - y - z = 6', Modifier::strip($tpl->fetch(array()), true));
} }
public function testImport() { public function testImport() {
$tpl = $this->aspect->compile('import.tpl'); $tpl = $this->cytro->compile('import.tpl');
$this->assertSame('Imp: x + y = 3 , x - y - z = 3', Modifier::strip($tpl->fetch(array()), true)); $this->assertSame('Imp: x + y = 3 , x - y - z = 3', Modifier::strip($tpl->fetch(array()), true));
} }
public function testImportCustom() { public function testImportCustom() {
$tpl = $this->aspect->compile('import_custom.tpl'); $tpl = $this->cytro->compile('import_custom.tpl');
$this->assertSame('a: x + y = 3 , x - y - z = 3 , new minus macros .', Modifier::strip($tpl->fetch(array()), true)); $this->assertSame('a: x + y = 3 , x - y - z = 3 , new minus macros .', Modifier::strip($tpl->fetch(array()), true));
} }
/** /**
* @expectedExceptionMessage Undefined macro 'plus' * @expectedExceptionMessage Undefined macro 'plus'
* @expectedException \Aspect\CompileException * @expectedException \Cytro\CompileException
*/ */
public function testImportMiss() { public function testImportMiss() {
$tpl = $this->aspect->compile('import_miss.tpl'); $tpl = $this->cytro->compile('import_miss.tpl');
$this->assertSame('a: x + y = 3 , x - y - z = 3 , new minus macros .', Modifier::strip($tpl->fetch(array()), true)); $this->assertSame('a: x + y = 3 , x - y - z = 3 , new minus macros .', Modifier::strip($tpl->fetch(array()), true));
} }

View File

@@ -1,5 +1,5 @@
<?php <?php
namespace Aspect; namespace Cytro;
class ModifiersTest extends TestCase { class ModifiersTest extends TestCase {
@@ -32,7 +32,7 @@ class ModifiersTest extends TestCase {
* @param bool $by_word * @param bool $by_word
*/ */
public function testTruncate($in, $out, $count, $delim = '...', $by_words = false, $middle = false) { public function testTruncate($in, $out, $count, $delim = '...', $by_words = false, $middle = false) {
$tpl = $this->aspect->compileCode('{$text|truncate:$count:$delim:$by_words:$middle}'); $tpl = $this->cytro->compileCode('{$text|truncate:$count:$delim:$by_words:$middle}');
$this->assertEquals($out, $tpl->fetch(array( $this->assertEquals($out, $tpl->fetch(array(
"text" => $in, "text" => $in,
"count" => $count, "count" => $count,

View File

@@ -1,8 +1,8 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect; use Cytro;
class FSProviderTest extends \Aspect\TestCase { class FSProviderTest extends \Cytro\TestCase {
/** /**
* @var FSProvider * @var FSProvider
*/ */
@@ -12,7 +12,7 @@ class FSProviderTest extends \Aspect\TestCase {
parent::setUp(); parent::setUp();
$this->tpl("template1.tpl", 'Template 1 {$a}'); $this->tpl("template1.tpl", 'Template 1 {$a}');
$this->tpl("template2.tpl", 'Template 2 {$a}'); $this->tpl("template2.tpl", 'Template 2 {$a}');
$this->provider = new FSProvider(ASPECT_RESOURCES.'/template'); $this->provider = new FSProvider(CYTRO_RESOURCES.'/template');
} }
public function testIsTemplateExists() { public function testIsTemplateExists() {
@@ -23,8 +23,8 @@ class FSProviderTest extends \Aspect\TestCase {
public function testGetSource() { public function testGetSource() {
$src = $this->provider->getSource("template1.tpl", $time); $src = $this->provider->getSource("template1.tpl", $time);
clearstatcache(); clearstatcache();
$this->assertEquals(file_get_contents(ASPECT_RESOURCES.'/template/template1.tpl'), $src); $this->assertEquals(file_get_contents(CYTRO_RESOURCES.'/template/template1.tpl'), $src);
$this->assertEquals(filemtime(ASPECT_RESOURCES.'/template/template1.tpl'), $time); $this->assertEquals(filemtime(CYTRO_RESOURCES.'/template/template1.tpl'), $time);
} }
/** /**
@@ -37,7 +37,7 @@ class FSProviderTest extends \Aspect\TestCase {
public function testGetLastModified() { public function testGetLastModified() {
$time = $this->provider->getLastModified("template1.tpl"); $time = $this->provider->getLastModified("template1.tpl");
clearstatcache(); clearstatcache();
$this->assertEquals(filemtime(ASPECT_RESOURCES.'/template/template1.tpl'), $time); $this->assertEquals(filemtime(CYTRO_RESOURCES.'/template/template1.tpl'), $time);
} }
/** /**
@@ -52,7 +52,7 @@ class FSProviderTest extends \Aspect\TestCase {
$this->assertSame($tpls, array_keys($times)); $this->assertSame($tpls, array_keys($times));
clearstatcache(); clearstatcache();
foreach($times as $template => $time) { foreach($times as $template => $time) {
$this->assertEquals(filemtime(ASPECT_RESOURCES."/template/$template"), $time); $this->assertEquals(filemtime(CYTRO_RESOURCES."/template/$template"), $time);
} }
} }

View File

@@ -1,7 +1,7 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect, use Cytro,
Aspect\Render; Cytro\Render;
class RenderTest extends \PHPUnit_Framework_TestCase { class RenderTest extends \PHPUnit_Framework_TestCase {
@@ -11,7 +11,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase {
public static $render; public static $render;
public static function setUpBeforeClass() { public static function setUpBeforeClass() {
self::$render = new Render(Aspect::factory("."), function ($tpl) { self::$render = new Render(Cytro::factory("."), function ($tpl) {
echo "It is render's function ".$tpl["render"]; echo "It is render's function ".$tpl["render"];
}, array( }, array(
"name" => "render.tpl" "name" => "render.tpl"
@@ -19,7 +19,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase {
} }
public function testCreate() { public function testCreate() {
$r = new Render(Aspect::factory("."), function () { $r = new Render(Cytro::factory("."), function () {
echo "Test render"; echo "Test render";
}, array( }, array(
"name" => "test.render.tpl" "name" => "test.render.tpl"
@@ -43,7 +43,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase {
* @expectedExceptionMessage template error * @expectedExceptionMessage template error
*/ */
public function testFetchException() { public function testFetchException() {
$render = new Render(Aspect::factory("."), function () { $render = new Render(Cytro::factory("."), function () {
echo "error"; echo "error";
throw new \RuntimeException("template error"); throw new \RuntimeException("template error");
}, array( }, array(

View File

@@ -1,17 +1,17 @@
<?php <?php
namespace Aspect; namespace Cytro;
class ScopeTest extends TestCase { class ScopeTest extends TestCase {
public function openTag($tokenizer, $scope) { public function openTag($tokenizer, $scope) {
$this->assertInstanceOf('Aspect\Tokenizer', $tokenizer); $this->assertInstanceOf('Cytro\Tokenizer', $tokenizer);
$this->assertInstanceOf('Aspect\Scope', $scope); $this->assertInstanceOf('Cytro\Scope', $scope);
$scope["value"] = true; $scope["value"] = true;
return "open-tag"; return "open-tag";
} }
public function closeTag($tokenizer, $scope) { public function closeTag($tokenizer, $scope) {
$this->assertInstanceOf('Aspect\Tokenizer', $tokenizer); $this->assertInstanceOf('Cytro\Tokenizer', $tokenizer);
$this->assertInstanceOf('Aspect\Scope', $scope); $this->assertInstanceOf('Cytro\Scope', $scope);
$this->assertTrue($scope["value"]); $this->assertTrue($scope["value"]);
return "close-tag"; return "close-tag";
} }

View File

@@ -1,14 +1,14 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect\Template, use Cytro\Template,
Aspect, Cytro,
Aspect\Render; Cytro\Render;
class TemplateTest extends TestCase { class TemplateTest extends TestCase {
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
$this->aspect->addTemplate(new Render($this->aspect, function ($tpl) { $this->cytro->addTemplate(new Render($this->cytro, function ($tpl) {
echo "<b>Welcome, ".$tpl["username"]." (".$tpl["email"].")</b>"; echo "<b>Welcome, ".$tpl["username"]." (".$tpl["email"].")</b>";
}, array( }, array(
"name" => "welcome.tpl" "name" => "welcome.tpl"
@@ -111,14 +111,14 @@ class TemplateTest extends TestCase {
public static function providerVarsInvalid() { public static function providerVarsInvalid() {
return array( return array(
array('hello, {$a.}!', 'Aspect\CompileException', "Unexpected end of expression"), array('hello, {$a.}!', 'Cytro\CompileException', "Unexpected end of expression"),
array('hello, {$b[c}!', 'Aspect\CompileException', "Unexpected end of expression"), array('hello, {$b[c}!', 'Cytro\CompileException', "Unexpected end of expression"),
array('hello, {$b.c]}!', 'Aspect\CompileException', "Unexpected token ']'"), array('hello, {$b.c]}!', 'Cytro\CompileException', "Unexpected token ']'"),
array('hello, {$b[ ]}!', 'Aspect\CompileException', "Unexpected token ']'"), array('hello, {$b[ ]}!', 'Cytro\CompileException', "Unexpected token ']'"),
array('hello, {$b[9/].c}!', 'Aspect\CompileException', "Unexpected token ']'"), array('hello, {$b[9/].c}!', 'Cytro\CompileException', "Unexpected token ']'"),
array('hello, {$b[3]$c}!', 'Aspect\CompileException', "Unexpected token '\$c'"), array('hello, {$b[3]$c}!', 'Cytro\CompileException', "Unexpected token '\$c'"),
array('hello, {$b[3]c}!', 'Aspect\CompileException', "Unexpected token 'c'"), array('hello, {$b[3]c}!', 'Cytro\CompileException', "Unexpected token 'c'"),
array('hello, {$b.obj->valid()}!', 'Aspect\SecurityException', "Forbidden to call methods", Aspect::DENY_METHODS), array('hello, {$b.obj->valid()}!', 'Cytro\SecurityException', "Forbidden to call methods", Cytro::DENY_METHODS),
); );
} }
@@ -173,12 +173,12 @@ class TemplateTest extends TestCase {
public static function providerModifiersInvalid() { public static function providerModifiersInvalid() {
return array( return array(
array('Mod: {$lorem|}!', 'Aspect\CompileException', "Unexpected end of expression"), array('Mod: {$lorem|}!', 'Cytro\CompileException', "Unexpected end of expression"),
array('Mod: {$lorem|str_rot13}!', 'Aspect\CompileException', "Modifier str_rot13 not found", Aspect::DENY_INLINE_FUNCS), array('Mod: {$lorem|str_rot13}!', 'Cytro\CompileException', "Modifier str_rot13 not found", Cytro::DENY_INLINE_FUNCS),
array('Mod: {$lorem|my_encode}!', 'Aspect\CompileException', "Modifier my_encode not found"), array('Mod: {$lorem|my_encode}!', 'Cytro\CompileException', "Modifier my_encode not found"),
array('Mod: {$lorem|truncate:}!', 'Aspect\CompileException', "Unexpected end of expression"), array('Mod: {$lorem|truncate:}!', 'Cytro\CompileException', "Unexpected end of expression"),
array('Mod: {$lorem|truncate:abs}!', 'Aspect\CompileException', "Unexpected token 'abs'"), array('Mod: {$lorem|truncate:abs}!', 'Cytro\CompileException', "Unexpected token 'abs'"),
array('Mod: {$lorem|truncate:80|}!', 'Aspect\CompileException', "Unexpected end of expression"), array('Mod: {$lorem|truncate:80|}!', 'Cytro\CompileException', "Unexpected end of expression"),
); );
} }
@@ -220,15 +220,15 @@ class TemplateTest extends TestCase {
public static function providerExpressionsInvalid() { public static function providerExpressionsInvalid() {
return array( return array(
array('If: {-"hi"} end', 'Aspect\CompileException', "Unexpected token '-'"), array('If: {-"hi"} end', 'Cytro\CompileException', "Unexpected token '-'"),
array('If: {($a++)++} end', 'Aspect\CompileException', "Unexpected token '++'"), array('If: {($a++)++} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('If: {$a + * $c} end', 'Aspect\CompileException', "Unexpected token '*'"), array('If: {$a + * $c} end', 'Cytro\CompileException', "Unexpected token '*'"),
array('If: {/$a} end', 'Aspect\CompileException', "Unexpected token '\$a'"), array('If: {/$a} end', 'Cytro\CompileException', "Unexpected token '\$a'"),
array('If: {$a == 5 > 4} end', 'Aspect\CompileException', "Unexpected token '>'"), array('If: {$a == 5 > 4} end', 'Cytro\CompileException', "Unexpected token '>'"),
array('If: {$a != 5 <= 4} end', 'Aspect\CompileException', "Unexpected token '<='"), array('If: {$a != 5 <= 4} end', 'Cytro\CompileException', "Unexpected token '<='"),
array('If: {$a != 5 => 4} end', 'Aspect\CompileException', "Unexpected token '=>'"), array('If: {$a != 5 => 4} end', 'Cytro\CompileException', "Unexpected token '=>'"),
array('If: {$a + (*6)} end', 'Aspect\CompileException', "Unexpected token '*'"), array('If: {$a + (*6)} end', 'Cytro\CompileException', "Unexpected token '*'"),
array('If: {$a + ( 6} end', 'Aspect\CompileException', "Brackets don't match"), array('If: {$a + ( 6} end', 'Cytro\CompileException', "Brackets don't match"),
); );
} }
@@ -265,8 +265,8 @@ class TemplateTest extends TestCase {
public static function providerIncludeInvalid() { public static function providerIncludeInvalid() {
return array( return array(
array('Include {include} template', 'Aspect\CompileException', "Unexpected end of expression"), array('Include {include} template', 'Cytro\CompileException', "Unexpected end of expression"),
array('Include {include another="welcome.tpl"} template', 'Aspect\CompileException', "Unexpected token '='"), array('Include {include another="welcome.tpl"} template', 'Cytro\CompileException', "Unexpected token '='"),
); );
} }
@@ -306,10 +306,10 @@ class TemplateTest extends TestCase {
public static function providerIfInvalid() { public static function providerIfInvalid() {
return array( return array(
array('If: {if} block1 {/if} end', 'Aspect\CompileException', "Unexpected end of expression"), array('If: {if} block1 {/if} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('If: {if 1} block1 {elseif} block2 {/if} end', 'Aspect\CompileException', "Unexpected end of expression"), array('If: {if 1} block1 {elseif} block2 {/if} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('If: {if 1} block1 {else} block2 {elseif 0} block3 {/if} end', 'Aspect\CompileException', "Incorrect use of the tag {elseif}"), array('If: {if 1} block1 {else} block2 {elseif 0} block3 {/if} end', 'Cytro\CompileException', "Incorrect use of the tag {elseif}"),
array('If: {if 1} block1 {else} block2 {/if} block3 {elseif 0} end', 'Aspect\CompileException', "Unexpected tag 'elseif' (this tag can be used with 'if')"), array('If: {if 1} block1 {else} block2 {/if} block3 {elseif 0} end', 'Cytro\CompileException', "Unexpected tag 'elseif' (this tag can be used with 'if')"),
); );
} }
@@ -347,20 +347,20 @@ class TemplateTest extends TestCase {
public static function providerCreateVarInvalid() { public static function providerCreateVarInvalid() {
return array( return array(
array('Create: {var $v} Result: {$v} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Create: {var $v} Result: {$v} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Create: {var $v = } Result: {$v} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Create: {var $v = } Result: {$v} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Create: {var $v = 1++} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '++'"), array('Create: {var $v = 1++} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('Create: {var $v = c} Result: {$v} end', 'Aspect\CompileException', "Unexpected token 'c'"), array('Create: {var $v = c} Result: {$v} end', 'Cytro\CompileException', "Unexpected token 'c'"),
array('Create: {var $v = ($a)++} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '++'"), array('Create: {var $v = ($a)++} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('Create: {var $v = --$a++} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '++'"), array('Create: {var $v = --$a++} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('Create: {var $v = $a|upper++} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '++'"), array('Create: {var $v = $a|upper++} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('Create: {var $v = max($a,2)++} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '++'"), array('Create: {var $v = max($a,2)++} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '++'"),
array('Create: {var $v = max($a,2)} Result: {$v} end', 'Aspect\CompileException', "Modifier max not found", Aspect::DENY_INLINE_FUNCS), array('Create: {var $v = max($a,2)} Result: {$v} end', 'Cytro\CompileException', "Modifier max not found", Cytro::DENY_INLINE_FUNCS),
array('Create: {var $v = 4*} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '*'"), array('Create: {var $v = 4*} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '*'"),
array('Create: {var $v = ""$a} Result: {$v} end', 'Aspect\CompileException', "Unexpected token '\$a'"), array('Create: {var $v = ""$a} Result: {$v} end', 'Cytro\CompileException', "Unexpected token '\$a'"),
array('Create: {var $v = [1,2} Result: {$v} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Create: {var $v = [1,2} Result: {$v} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Create: {var $v = empty(2)} Result: {$v} end', 'Aspect\CompileException', "Unexpected token 2, isset() and empty() accept only variables"), array('Create: {var $v = empty(2)} Result: {$v} end', 'Cytro\CompileException', "Unexpected token 2, isset() and empty() accept only variables"),
array('Create: {var $v = isset(2)} Result: {$v} end', 'Aspect\CompileException', "Unexpected token 2, isset() and empty() accept only variables"), array('Create: {var $v = isset(2)} Result: {$v} end', 'Cytro\CompileException', "Unexpected token 2, isset() and empty() accept only variables"),
); );
} }
@@ -453,27 +453,27 @@ class TemplateTest extends TestCase {
public static function providerForeachInvalid() { public static function providerForeachInvalid() {
return array( return array(
array('Foreach: {foreach} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected end of tag {foreach}"), array('Foreach: {foreach} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected end of tag {foreach}"),
array('Foreach: {foreach $list} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Foreach: {foreach $list} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Foreach: {foreach $list+1 as $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list+1 as $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach array_random() as $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'array_random'"), array('Foreach: {foreach array_random() as $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'array_random'"),
array('Foreach: {foreach $list as $e+1} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list as $e+1} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach $list as $k+1 => $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list as $k+1 => $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach $list as max($i,1) => $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('Foreach: {foreach $list as max($i,1) => $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('Foreach: {foreach $list as max($e,1)} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('Foreach: {foreach $list as max($e,1)} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('Foreach: {foreach $list => $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '=>'"), array('Foreach: {foreach $list => $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '=>'"),
array('Foreach: {foreach $list $k => $e} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '\$k'"), array('Foreach: {foreach $list $k => $e} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '\$k'"),
array('Foreach: {foreach $list as $k =>} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Foreach: {foreach $list as $k =>} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Foreach: {foreach last=$l $list as $e } {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'last' in tag {foreach}"), array('Foreach: {foreach last=$l $list as $e } {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'last' in tag {foreach}"),
array('Foreach: {foreach $list as $e unknown=1} {$e}, {/foreach} end', 'Aspect\CompileException', "Unknown parameter 'unknown'"), array('Foreach: {foreach $list as $e unknown=1} {$e}, {/foreach} end', 'Cytro\CompileException', "Unknown parameter 'unknown'"),
array('Foreach: {foreach $list as $e index=$i+1} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list as $e index=$i+1} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach $list as $e first=$f+1} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list as $e first=$f+1} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach $list as $e last=$l+1} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token '+'"), array('Foreach: {foreach $list as $e last=$l+1} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('Foreach: {foreach $list as $e index=max($i,1)} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('Foreach: {foreach $list as $e index=max($i,1)} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('Foreach: {foreach $list as $e first=max($i,1)} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('Foreach: {foreach $list as $e first=max($i,1)} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('Foreach: {foreach $list as $e last=max($i,1)} {$e}, {/foreach} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('Foreach: {foreach $list as $e last=max($i,1)} {$e}, {/foreach} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('Foreach: {foreach $list as $e} {$e}, {foreachelse} {break} {/foreach} end', 'Aspect\CompileException', "Improper usage of the tag {break}"), array('Foreach: {foreach $list as $e} {$e}, {foreachelse} {break} {/foreach} end', 'Cytro\CompileException', "Improper usage of the tag {break}"),
array('Foreach: {foreach $list as $e} {$e}, {foreachelse} {continue} {/foreach} end', 'Aspect\CompileException', "Improper usage of the tag {continue}"), array('Foreach: {foreach $list as $e} {$e}, {foreachelse} {continue} {/foreach} end', 'Cytro\CompileException', "Improper usage of the tag {continue}"),
); );
} }
@@ -518,9 +518,9 @@ class TemplateTest extends TestCase {
public static function providerSwitchInvalid() { public static function providerSwitchInvalid() {
return array( return array(
array('Switch: {switch}{case 1} one {break}{/switch} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Switch: {switch}{case 1} one {break}{/switch} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Switch: {switch 1}{case} one {break}{/switch} end', 'Aspect\CompileException', "Unexpected end of expression"), array('Switch: {switch 1}{case} one {break}{/switch} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('Switch: {switch 1}{break}{case} one {/switch} end', 'Aspect\CompileException', "Improper usage of the tag {break}"), array('Switch: {switch 1}{break}{case} one {/switch} end', 'Cytro\CompileException', "Improper usage of the tag {break}"),
); );
} }
@@ -536,7 +536,7 @@ class TemplateTest extends TestCase {
public static function providerWhileInvalid() { public static function providerWhileInvalid() {
return array( return array(
array('While: {while} block {/while} end', 'Aspect\CompileException', "Unexpected end of expression"), array('While: {while} block {/while} end', 'Cytro\CompileException', "Unexpected end of expression"),
); );
} }
@@ -564,29 +564,29 @@ class TemplateTest extends TestCase {
public static function providerForInvalid() { public static function providerForInvalid() {
return array( return array(
array('For: {for} block1 {/for} end', 'Aspect\CompileException', "Unexpected end of expression"), array('For: {for} block1 {/for} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('For: {for $a=} block1 {/for} end', 'Aspect\CompileException', "Unexpected end of expression"), array('For: {for $a=} block1 {/for} end', 'Cytro\CompileException', "Unexpected end of expression"),
array('For: {for $a+1=3 to=6} block1 {/for} end', 'Aspect\CompileException', "Unexpected token '+'"), array('For: {for $a+1=3 to=6} block1 {/for} end', 'Cytro\CompileException', "Unexpected token '+'"),
array('For: {for max($a,$b)=3 to=6} block1 {/for} end', 'Aspect\CompileException', "Unexpected token 'max'"), array('For: {for max($a,$b)=3 to=6} block1 {/for} end', 'Cytro\CompileException', "Unexpected token 'max'"),
array('For: {for to=6 $a=3} block1 {/for} end', 'Aspect\CompileException', "Unexpected token 'to'"), array('For: {for to=6 $a=3} block1 {/for} end', 'Cytro\CompileException', "Unexpected token 'to'"),
array('For: {for index=$i $a=3 to=6} block1 {/for} end', 'Aspect\CompileException', "Unexpected token 'index'"), array('For: {for index=$i $a=3 to=6} block1 {/for} end', 'Cytro\CompileException', "Unexpected token 'index'"),
array('For: {for first=$i $a=3 to=6} block1 {/for} end', 'Aspect\CompileException', "Unexpected token 'first'"), array('For: {for first=$i $a=3 to=6} block1 {/for} end', 'Cytro\CompileException', "Unexpected token 'first'"),
array('For: {for last=$i $a=3 to=6} block1 {/for} end', 'Aspect\CompileException', "Unexpected token 'last'"), array('For: {for last=$i $a=3 to=6} block1 {/for} end', 'Cytro\CompileException', "Unexpected token 'last'"),
array('For: {for $a=4 to=6 unk=4} block1 {/for} end', 'Aspect\CompileException', "Unknown parameter 'unk'"), array('For: {for $a=4 to=6 unk=4} block1 {/for} end', 'Cytro\CompileException', "Unknown parameter 'unk'"),
array('For: {for $a=4 to=6} $a: {$a}, {forelse} {break} {/for} end', 'Aspect\CompileException', "Improper usage of the tag {break}"), array('For: {for $a=4 to=6} $a: {$a}, {forelse} {break} {/for} end', 'Cytro\CompileException', "Improper usage of the tag {break}"),
array('For: {for $a=4 to=6} $a: {$a}, {forelse} {continue} {/for} end', 'Aspect\CompileException', "Improper usage of the tag {continue}"), array('For: {for $a=4 to=6} $a: {$a}, {forelse} {continue} {/for} end', 'Cytro\CompileException', "Improper usage of the tag {continue}"),
); );
} }
public static function providerLayersInvalid() { public static function providerLayersInvalid() {
return array( return array(
array('Layers: {foreach $list as $e} block1 {if 1} {foreachelse} {/if} {/foreach} end', 'Aspect\CompileException', "Unexpected tag 'foreachelse' (this tag can be used with 'foreach')"), array('Layers: {foreach $list as $e} block1 {if 1} {foreachelse} {/if} {/foreach} end', 'Cytro\CompileException', "Unexpected tag 'foreachelse' (this tag can be used with 'foreach')"),
array('Layers: {foreach $list as $e} block1 {if 1} {/foreach} {/if} end', 'Aspect\CompileException', "Unexpected closing of the tag 'foreach'"), array('Layers: {foreach $list as $e} block1 {if 1} {/foreach} {/if} end', 'Cytro\CompileException', "Unexpected closing of the tag 'foreach'"),
array('Layers: {for $a=4 to=6} block1 {if 1} {forelse} {/if} {/for} end', 'Aspect\CompileException', "Unexpected tag 'forelse' (this tag can be used with 'for')"), array('Layers: {for $a=4 to=6} block1 {if 1} {forelse} {/if} {/for} end', 'Cytro\CompileException', "Unexpected tag 'forelse' (this tag can be used with 'for')"),
array('Layers: {for $a=4 to=6} block1 {if 1} {/for} {/if} end', 'Aspect\CompileException', "Unexpected closing of the tag 'for'"), array('Layers: {for $a=4 to=6} block1 {if 1} {/for} {/if} end', 'Cytro\CompileException', "Unexpected closing of the tag 'for'"),
array('Layers: {switch 1} {if 1} {case 1} {/if} {/switch} end', 'Aspect\CompileException', "Unexpected tag 'case' (this tag can be used with 'switch')"), array('Layers: {switch 1} {if 1} {case 1} {/if} {/switch} end', 'Cytro\CompileException', "Unexpected tag 'case' (this tag can be used with 'switch')"),
array('Layers: {/switch} end', 'Aspect\CompileException', "Unexpected closing of the tag 'switch'"), array('Layers: {/switch} end', 'Cytro\CompileException', "Unexpected closing of the tag 'switch'"),
array('Layers: {if 1} end', 'Aspect\CompileException', "Unclosed tag(s): {if}"), array('Layers: {if 1} end', 'Cytro\CompileException', "Unclosed tag(s): {if}"),
); );
} }

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Aspect; namespace Cytro;
use Aspect\Tokenizer; use Cytro\Tokenizer;
class TokenizerTest extends \PHPUnit_Framework_TestCase { class TokenizerTest extends \PHPUnit_Framework_TestCase {
@@ -54,7 +54,7 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase {
try { try {
$tokens->skip(T_STRING)->skip('(')->skip(':'); $tokens->skip(T_STRING)->skip('(')->skip(':');
} catch(\Exception $e) { } catch(\Exception $e) {
$this->assertInstanceOf('Aspect\UnexpectedTokenException', $e); $this->assertInstanceOf('Cytro\UnexpectedTokenException', $e);
$this->assertStringStartsWith("Unexpected token '3' in expression, expect ':'", $e->getMessage()); $this->assertStringStartsWith("Unexpected token '3' in expression, expect ':'", $e->getMessage());
} }
$this->assertTrue($tokens->valid()); $this->assertTrue($tokens->valid());

View File

@@ -1,22 +1,22 @@
<?php <?php
use Aspect\Render, use Cytro\Render,
Aspect\FSProvider as FS; Cytro\FSProvider as FS;
class AspectTest extends \Aspect\TestCase { class CytroTest extends \Cytro\TestCase {
public function testAddRender() { public function testAddRender() {
$test = $this; $test = $this;
$this->aspect->addTemplate(new Render($this->aspect, function($tpl) use ($test) { $this->cytro->addTemplate(new Render($this->cytro, function($tpl) use ($test) {
/** @var \PHPUnit_Framework_TestCase $test */ /** @var \PHPUnit_Framework_TestCase $test */
$test->assertInstanceOf('Aspect\Render', $tpl); $test->assertInstanceOf('Cytro\Render', $tpl);
echo "Inline render"; echo "Inline render";
}, array( }, array(
"name" => 'render.tpl', "name" => 'render.tpl',
"scm" => false "scm" => false
))); )));
$this->assertSame("Inline render", $this->aspect->fetch('render.tpl', array())); $this->assertSame("Inline render", $this->cytro->fetch('render.tpl', array()));
} }
public function testCompileFile() { public function testCompileFile() {
@@ -26,71 +26,71 @@ class AspectTest extends \Aspect\TestCase {
); );
$this->tpl('template1.tpl', 'Template 1 a'); $this->tpl('template1.tpl', 'Template 1 a');
$this->tpl('template2.tpl', 'Template 2 b'); $this->tpl('template2.tpl', 'Template 2 b');
$this->assertSame("Template 1 a", $this->aspect->fetch('template1.tpl', $a)); $this->assertSame("Template 1 a", $this->cytro->fetch('template1.tpl', $a));
$this->assertSame("Template 2 b", $this->aspect->fetch('template2.tpl', $a)); $this->assertSame("Template 2 b", $this->cytro->fetch('template2.tpl', $a));
$this->assertInstanceOf('Aspect\Render', $this->aspect->getTemplate('template1.tpl')); $this->assertInstanceOf('Cytro\Render', $this->cytro->getTemplate('template1.tpl'));
$this->assertInstanceOf('Aspect\Render', $this->aspect->getTemplate('template2.tpl')); $this->assertInstanceOf('Cytro\Render', $this->cytro->getTemplate('template2.tpl'));
$this->assertSame(3, iterator_count(new FilesystemIterator(ASPECT_RESOURCES.'/compile'))); $this->assertSame(3, iterator_count(new FilesystemIterator(CYTRO_RESOURCES.'/compile')));
} }
public function testStorage() { public function testStorage() {
$this->tpl('custom.tpl', 'Custom template'); $this->tpl('custom.tpl', 'Custom template');
$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template", $this->cytro->fetch('custom.tpl', array()));
//$this->aspect->clearCompiledTemplate('custom.tpl', false); //$this->aspect->clearCompiledTemplate('custom.tpl', false);
//$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array())); //$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array()));
$this->tpl('custom.tpl', 'Custom template 2'); $this->tpl('custom.tpl', 'Custom template 2');
$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template", $this->cytro->fetch('custom.tpl', array()));
} }
public function testCheckMTime() { public function testCheckMTime() {
$this->aspect->setOptions(Aspect::FORCE_COMPILE); $this->cytro->setOptions(Cytro::FORCE_COMPILE);
$this->tpl('custom.tpl', 'Custom template'); $this->tpl('custom.tpl', 'Custom template');
$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template", $this->cytro->fetch('custom.tpl', array()));
sleep(1); sleep(1);
$this->tpl('custom.tpl', 'Custom template (new)'); $this->tpl('custom.tpl', 'Custom template (new)');
$this->assertSame("Custom template (new)", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template (new)", $this->cytro->fetch('custom.tpl', array()));
} }
public function testForceCompile() { public function testForceCompile() {
$this->aspect->setOptions(Aspect::FORCE_COMPILE); $this->cytro->setOptions(Cytro::FORCE_COMPILE);
$this->tpl('custom.tpl', 'Custom template'); $this->tpl('custom.tpl', 'Custom template');
$this->assertSame("Custom template", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template", $this->cytro->fetch('custom.tpl', array()));
$this->tpl('custom.tpl', 'Custom template (new)'); $this->tpl('custom.tpl', 'Custom template (new)');
$this->assertSame("Custom template (new)", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom template (new)", $this->cytro->fetch('custom.tpl', array()));
} }
public function testSetModifier() { public function testSetModifier() {
$this->aspect->addModifier("mymod", "myMod"); $this->cytro->addModifier("mymod", "myMod");
$this->tpl('custom.tpl', 'Custom modifier {$a|mymod}'); $this->tpl('custom.tpl', 'Custom modifier {$a|mymod}');
$this->assertSame("Custom modifier (myMod)Custom(/myMod)", $this->aspect->fetch('custom.tpl', array("a" => "Custom"))); $this->assertSame("Custom modifier (myMod)Custom(/myMod)", $this->cytro->fetch('custom.tpl', array("a" => "Custom")));
} }
/** /**
* @group add_functions * @group add_functions
*/ */
public function testSetFunctions() { public function testSetFunctions() {
$this->aspect->setOptions(Aspect::FORCE_COMPILE); $this->cytro->setOptions(Cytro::FORCE_COMPILE);
$this->aspect->addFunction("myfunc", "myFunc"); $this->cytro->addFunction("myfunc", "myFunc");
$this->aspect->addBlockFunction("myblockfunc", "myBlockFunc"); $this->cytro->addBlockFunction("myblockfunc", "myBlockFunc");
$this->tpl('custom.tpl', 'Custom function {myfunc name="foo"}'); $this->tpl('custom.tpl', 'Custom function {myfunc name="foo"}');
$this->assertSame("Custom function MyFunc:foo", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom function MyFunc:foo", $this->cytro->fetch('custom.tpl', array()));
$this->tpl('custom.tpl', 'Custom function {myblockfunc name="foo"} this block1 {/myblockfunc}'); $this->tpl('custom.tpl', 'Custom function {myblockfunc name="foo"} this block1 {/myblockfunc}');
$this->assertSame("Custom function Block:foo:this block1:Block", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom function Block:foo:this block1:Block", $this->cytro->fetch('custom.tpl', array()));
} }
public function testSetCompilers() { public function testSetCompilers() {
$this->aspect->setOptions(Aspect::FORCE_COMPILE); $this->cytro->setOptions(Cytro::FORCE_COMPILE);
$this->aspect->addCompiler("mycompiler", 'myCompiler'); $this->cytro->addCompiler("mycompiler", 'myCompiler');
$this->aspect->addBlockCompiler("myblockcompiler", 'myBlockCompilerOpen', 'myBlockCompilerClose', array( $this->cytro->addBlockCompiler("myblockcompiler", 'myBlockCompilerOpen', 'myBlockCompilerClose', array(
'tag' => 'myBlockCompilerTag' 'tag' => 'myBlockCompilerTag'
)); ));
$this->tpl('custom.tpl', 'Custom compiler {mycompiler name="bar"}'); $this->tpl('custom.tpl', 'Custom compiler {mycompiler name="bar"}');
$this->assertSame("Custom compiler PHP_VERSION: ".PHP_VERSION." (for bar)", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom compiler PHP_VERSION: ".PHP_VERSION." (for bar)", $this->cytro->fetch('custom.tpl', array()));
$this->tpl('custom.tpl', 'Custom compiler {myblockcompiler name="bar"} block1 {tag name="baz"} block2 {/myblockcompiler}'); $this->tpl('custom.tpl', 'Custom compiler {myblockcompiler name="bar"} block1 {tag name="baz"} block2 {/myblockcompiler}');
$this->assertSame("Custom compiler PHP_VERSION: ".PHP_VERSION." (for bar) block1 Tag baz of compiler block2 End of compiler", $this->aspect->fetch('custom.tpl', array())); $this->assertSame("Custom compiler PHP_VERSION: ".PHP_VERSION." (for bar) block1 Tag baz of compiler block2 End of compiler", $this->cytro->fetch('custom.tpl', array()));
} }
} }

View File

@@ -12,20 +12,20 @@ function myBlockFunc($params, $content) {
return "Block:".$params["name"].':'.trim($content).':Block'; return "Block:".$params["name"].':'.trim($content).':Block';
} }
function myCompiler(Aspect\Tokenizer $tokenizer, Aspect\Template $tpl) { function myCompiler(Cytro\Tokenizer $tokenizer, Cytro\Template $tpl) {
$p = $tpl->parseParams($tokenizer); $p = $tpl->parseParams($tokenizer);
return 'echo "PHP_VERSION: ".PHP_VERSION." (for ".'.$p["name"].'.")";'; return 'echo "PHP_VERSION: ".PHP_VERSION." (for ".'.$p["name"].'.")";';
} }
function myBlockCompilerOpen(Aspect\Tokenizer $tokenizer, Aspect\Scope $scope) { function myBlockCompilerOpen(Cytro\Tokenizer $tokenizer, Cytro\Scope $scope) {
return myCompiler($tokenizer, $scope->tpl); return myCompiler($tokenizer, $scope->tpl);
} }
function myBlockCompilerClose(Aspect\Tokenizer $tokenizer, Aspect\Scope $scope) { function myBlockCompilerClose(Cytro\Tokenizer $tokenizer, Cytro\Scope $scope) {
return 'echo "End of compiler";'; return 'echo "End of compiler";';
} }
function myBlockCompilerTag(Aspect\Tokenizer $tokenizer, Aspect\Scope $scope) { function myBlockCompilerTag(Cytro\Tokenizer $tokenizer, Cytro\Scope $scope) {
$p = $scope->tpl->parseParams($tokenizer); $p = $scope->tpl->parseParams($tokenizer);
return 'echo "Tag ".'.$p["name"].'." of compiler";'; return 'echo "Tag ".'.$p["name"].'." of compiler";';
} }

View File

@@ -0,0 +1,7 @@
{block 'header'}
header block
{/block}
{block 'bottom'}
bottom block
{/block}

View File

@@ -0,0 +1,6 @@
{extends 'parent.tpl'}
up
{block 'header'}empty header{/block}
middle
{block 'bottom'}empty bottom{/block}
down

View File

@@ -0,0 +1 @@
include template

View File

@@ -0,0 +1,7 @@
{macro add(a, b)}
a + b = {$a + $b}
{/macro}
{macro rem(a, b)}
a - b = {$a - $b}
{/macro}

View File

@@ -0,0 +1,2 @@
{block 'header'}header body{/block}
{block 'bottom'}bottom body{/block}