Add comments and license block

This commit is contained in:
bzick 2013-04-28 11:33:36 +04:00
parent 5d4d218942
commit 614428e88d
11 changed files with 136 additions and 39 deletions

View File

@ -4,7 +4,7 @@
"description": "Cytro - fast template engine for PHP",
"homepage": "http://bzick.github.io/cytro/",
"keywords": ["cytro", "template", "templating"],
"license": "MIT",
"license": "BSD-3",
"authors": [
{
"name": "Ivan Shalganov",

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Cytro\Template,
Cytro\ProviderInterface;

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cytro;
use Cytro\Tokenizer;
use Cytro\Template;
@ -6,6 +14,7 @@ use Cytro\Scope;
/**
* Compilers collection
* @package Cytro
*/
class Compiler {
/**
@ -18,7 +27,7 @@ class Compiler {
* @return string
*/
public static function tagInclude(Tokenizer $tokens, Template $tpl) {
$cname = $tpl->parseFirstArg($tokens, $name);
$cname = $tpl->parsePlainArg($tokens, $name);
$p = $tpl->parseParams($tokens);
if($p) { // if we have additionally variables
if($name && ($tpl->getStorage()->getOptions() & \Cytro::FORCE_INCLUDE)) { // if FORCE_INCLUDE enabled and template name known
@ -371,7 +380,7 @@ class Compiler {
if(!empty($tpl->_extends)) {
throw new ImproperUseException("Only one {extends} allowed");
}
$tpl_name = $tpl->parseFirstArg($tokens, $name);
$tpl_name = $tpl->parsePlainArg($tokens, $name);
if(empty($tpl->_extended)) {
$tpl->addPostCompile(__CLASS__."::extendBody");
}
@ -423,13 +432,14 @@ class Compiler {
}
/**
* Tag {use ...}
* @param Tokenizer $tokens
* @param Template $tpl
* @throws ImproperUseException
* @return string
*/
public static function tagUse(Tokenizer $tokens, Template $tpl) {
$tpl->parseFirstArg($tokens, $name);
$tpl->parsePlainArg($tokens, $name);
if($name) {
$donor = $tpl->getStorage()->getRawTemplate()->load($name, false);
$donor->_extended = true;
@ -457,7 +467,7 @@ class Compiler {
* @throws ImproperUseException
*/
public static function tagBlockOpen(Tokenizer $tokens, Scope $scope) {
$p = $scope->tpl->parseFirstArg($tokens, $name);
$p = $scope->tpl->parsePlainArg($tokens, $name);
$scope["name"] = $name;
$scope["cname"] = $p;
}
@ -750,7 +760,7 @@ class Compiler {
$tokens->next();
}
$tpl->parseFirstArg($tokens, $name);
$tpl->parsePlainArg($tokens, $name);
if(!$name) {
throw new ImproperUseException("Invalid usage tag {import}");
}

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cytro;
use Cytro\ProviderInterface;
@ -46,6 +54,10 @@ class FSProvider implements ProviderInterface {
}
}
/**
* @param string $template_dir directory of templates
* @throws \LogicException if directory doesn't exists
*/
public function __construct($template_dir) {
if($_dir = realpath($template_dir)) {
$this->_path = $_dir;
@ -107,9 +119,9 @@ class FSProvider implements ProviderInterface {
}
/**
* Verify templates by change time
* Verify templates (check change time)
*
* @param array $templates [template_name => modified, ...] By conversation you may trust the template's name
* @param array $templates [template_name => modified, ...] By conversation, you may trust the template's name
* @return bool
*/
public function verify(array $templates) {

View File

@ -12,8 +12,6 @@ namespace Cytro;
/**
* Collection of modifiers
*
* @package aspect
* @author Ivan Shalganov <owner@bzick.net>
*/
class Modifier {
@ -84,9 +82,9 @@ class Modifier {
/**
* Crop string by length
* UTF8 support
* @param string $string
* @param int $length
* @param string $etc
* @param string $string text witch will be truncate
* @param int $length maximum symbols of result string
* @param string $etc place holder truncated symbols
* @param bool $by_words
* @param bool $middle
* @return string
@ -116,7 +114,7 @@ class Modifier {
/**
* Strip spaces symbols on edge of string end multiple spaces in string
* @static
*
* @param string $str
* @param bool $to_line strip line ends
* @return string

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cytro;
interface ProviderInterface {

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cytro;
use Cytro;
@ -22,20 +30,34 @@ class Render extends \ArrayObject {
* @var string
*/
protected $_name = 'runtime';
/**
* Provider's schema
* @var bool
*/
protected $_scm = false;
/**
* Basic template name
* @var string
*/
protected $_base_name = 'runtime';
/**
* @var Cytro
*/
protected $_aspect;
protected $_cytro;
/**
* Timestamp of compilation
* @var float
*/
protected $_time = 0.0;
/**
* @var array depends list
*/
protected $_depends = array();
/**
* @var int tempalte options (see Cytro options)
*/
protected $_options = 0;
/**
@ -45,15 +67,15 @@ class Render extends \ArrayObject {
protected $_provider;
/**
* @param Cytro $aspect
* @param Cytro $cytro
* @param callable $code template body
* @param array $props
*/
public function __construct(Cytro $aspect, \Closure $code, $props = array()) {
$this->_aspect = $aspect;
public function __construct(Cytro $cytro, \Closure $code, $props = array()) {
$this->_cytro = $cytro;
$props += self::$_props;
$this->_name = $props["name"];
$this->_provider = $this->_aspect->getProvider($props["scm"]);
$this->_provider = $this->_cytro->getProvider($props["scm"]);
$this->_scm = $props["scm"];
$this->_time = $props["time"];
$this->_depends = $props["depends"];
@ -65,7 +87,7 @@ class Render extends \ArrayObject {
* @return Cytro
*/
public function getStorage() {
return $this->_aspect;
return $this->_cytro;
}
public function getDepends() {
@ -113,12 +135,12 @@ class Render extends \ArrayObject {
* @return bool
*/
public function isValid() {
$provider = $this->_aspect->getProvider(strstr($this->_name, ":"), true);
$provider = $this->_cytro->getProvider(strstr($this->_name, ":"), true);
if($provider->getLastModified($this->_name) >= $this->_time) {
return false;
}
foreach($this->_depends as $tpl => $time) {
if($this->_aspect->getTemplate($tpl)->getTime() !== $time) {
if($this->_cytro->getTemplate($tpl)->getTime() !== $time) {
return false;
}
}

View File

@ -1,4 +1,12 @@
<?php
/*
* This file is part of Cytro.
*
* (c) 2013 Ivan Shalganov
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Cytro;
/**

View File

@ -68,6 +68,7 @@ class Template extends Render {
* Just factory
*
* @param \Cytro $aspect
* @param $options
* @return Template
*/
public static function factory(Cytro $aspect, $options) {
@ -75,11 +76,12 @@ class Template extends Render {
}
/**
* @param Cytro $aspect Template storage
* @param Cytro $cytro Template storage
* @param $options
*/
public function __construct(Cytro $aspect, $options) {
$this->_aspect = $aspect;
$this->_options = $this->_aspect->getOptions();
public function __construct(Cytro $cytro, $options) {
$this->_cytro = $cytro;
$this->_options = $this->_cytro->getOptions();
}
/**
@ -96,7 +98,7 @@ class Template extends Render {
} else {
$this->_base_name = $name;
}
$this->_provider = $this->_aspect->getProvider($provider);
$this->_provider = $this->_cytro->getProvider($provider);
$this->_src = $this->_provider->getSource($name, $this->_time);
if($compile) {
$this->compile();
@ -143,12 +145,12 @@ class Template extends Render {
$pos = $end + 1; // trying finding tags after the comment block
continue 2;
}
$end = strpos($this->_src, '}', $start); // search close-char of the tag
$end = strpos($this->_src, '}', $start); // search close-symbol of the tag
if(!$end) { // if unexpected end of template
throw new CompileException("Unclosed tag in line {$this->_line}", 0, 1, $this->_name, $this->_line);
}
$frag .= substr($this->_src, $this->_pos, $start - $this->_pos); // variable $frag contains chars after last '}' and next '{'
$tag = substr($this->_src, $start, $end - $start + 1); // variable $tag contains aspect tag '{...}'
$frag .= substr($this->_src, $this->_pos, $start - $this->_pos); // variable $frag contains chars after previous '}' and current '{'
$tag = substr($this->_src, $start, $end - $start + 1); // variable $tag contains cytro tag '{...}'
$this->_line += substr_count($this->_src, "\n", $this->_pos, $end - $start + 1); // count lines in $frag and $tag (using original text $code)
$pos = $this->_pos = $end + 1; // move search-pointer to end of the tag
@ -215,6 +217,11 @@ class Template extends Render {
$this->_body .= str_replace("<?", '<?php echo "<?"; ?>'.PHP_EOL, $text);
}
/**
* Append PHP_EOL after each '?>'
* @param int $code
* @return string
*/
private function _escapeCode($code) {
$c = "";
foreach(token_get_all($code) as $token) {
@ -414,7 +421,7 @@ class Template extends Render {
return $this->parseMacro($tokens, $name);
}
if($act = $this->_aspect->getFunction($action)) { // call some function
if($act = $this->_cytro->getFunction($action)) { // call some function
switch($act["type"]) {
case Cytro::BLOCK_COMPILER:
$scope = new Scope($action, $this, $this->_line, $act, count($this->_stack), $this->_body);
@ -442,7 +449,7 @@ class Template extends Render {
return $this->_stack[$i]->tag($action, $tokens);
}
}
if($tags = $this->_aspect->getTagOwners($action)) { // unknown template tag
if($tags = $this->_cytro->getTagOwners($action)) { // unknown template tag
throw new TokenizeException("Unexpected tag '$action' (this tag can be used with '".implode("', '", $tags)."')");
} else {
throw new TokenizeException("Unexpected tag $action");
@ -496,7 +503,7 @@ class Template extends Render {
if($tokens->isSpecialVal()) {
$_exp .= $tokens->getAndNext();
} elseif($tokens->isNext("(")) {
$func = $this->_aspect->getModifier($tokens->current());
$func = $this->_cytro->getModifier($tokens->current());
$tokens->next();
$_exp .= $func.$this->parseArgs($tokens);
} else {
@ -828,7 +835,7 @@ class Template extends Render {
*/
public function parseModifier(Tokenizer $tokens, $value) {
while($tokens->is("|")) {
$mods = $this->_aspect->getModifier( $tokens->getNext(Tokenizer::MACRO_STRING) );
$mods = $this->_cytro->getModifier( $tokens->getNext(Tokenizer::MACRO_STRING) );
$tokens->next();
$args = array();
@ -1008,7 +1015,7 @@ class Template extends Render {
* @param string $static
* @return mixed|string
*/
public function parseFirstArg(Tokenizer $tokens, &$static) {
public function parsePlainArg(Tokenizer $tokens, &$static) {
if($tokens->is(T_CONSTANT_ENCAPSED_STRING)) {
if($tokens->isNext('|')) {
return $this->parseExp($tokens, true);

View File

@ -9,9 +9,16 @@
*/
namespace Cytro;
/**
* for <PHP 5.4 compatible
*/
defined('T_INSTEADOF') || define('T_INSTEADOF', 341);
defined('T_TRAIT') || define('T_TRAIT', 355);
defined('T_TRAIT_C') || define('T_TRAIT_C', 365);
/**
* for PHP <5.5
*/
defined('T_YIELD') || define('T_YIELD', 370);
/**
* Each token have structure

View File

@ -11,11 +11,11 @@ class ExtendsTemplateTest extends TestCase {
"name" => "level.0.tpl",
"level" => 0,
"blocks" => array(
"b1" => "",
"b1" => "default 5",
"b2" => "empty 0"
),
"result" => array(
"b1" => "",
"b1" => "default 5",
"b2" => "empty 0"
),
),
@ -79,10 +79,27 @@ class ExtendsTemplateTest extends TestCase {
* @group static-extend
*/
public function testTemplateExtends() {
foreach(self::generate('{block "%s"}%s{/block}', '{extends "level.%d.tpl"}') as $name => $tpl) {
$vars = array(
"b1" => "b1",
"b2" => "b2",
"b3" => "b3",
"b4" => "b4",
"level" => "level",
"default" => 5
);
$tpls = self::generate('{block "%s"}%s{/block}', '{extends "level.%d.tpl"}');
foreach($tpls as $name => $tpl) {
$this->tpl($name, $tpl["src"]);
//var_dump($src, "----\n\n----", $dst);ob_flush();fgetc(STDIN);
$this->assertSame($this->cytro->fetch($name, array()), $tpl["dst"]);
$this->assertSame($this->cytro->fetch($name, $vars), $tpl["dst"]);
}
$tpls = self::generate('{block "{$%s}"}%s{/block}', '{extends "level.%d.tpl"}');
arsort($tpls);
foreach($tpls as $name => $tpl) {
$this->tpl("d.".$name, $tpl["src"]);
//var_dump($src, "----\n\n----", $dst);ob_flush();fgetc(STDIN);
$this->assertSame($this->cytro->fetch("d.".$name, $vars), $tpl["dst"]);
//var_dump($name);ob_flush();fgets(STDIN);
}
}