Commit 5fc48230 by Seldaek

+ Syntax: Block plugins that you want to call without content can be

self-closed just like XML tags (e.g. {a "http://url.com" /} ) + Plugins: Added the {a} block plugin to generate <a> tags + API: Added Dwoo_Plugin::paramsToAttributes() utility function to help with the creation of compilable xml/html-related plugins * Syntax: Math expressions in strings are now only allowed when the entire expression is delimited, e.g. {"/$foo/$bar"} evaluates as just that while {"/`$foo/$bar`"} will result in "/".($foo/$bar), therefore processing the / as a division, this is better since URLs using / are far more common than math in strings => http://forum.dwoo.org/viewtopic.php?id=50 * Fixed a bug preventing if blocks containing a {elseif} followed by {else} git-svn-id: svn://dwoo.org/dwoo/trunk@121 0598d79b-80c4-4d41-97ba-ac86fbbd088b
parent 7869a71a
[2008--] 0.9.3
[2008-07-] 0.9.3
+ Syntax: Added the ";" token that allows to group multiple instructions in one
single template tag, for example: {if $foo; "> $foo";$bar;/} is equal to:
{if $foo}> {$foo}{$bar}{/} - It is not that useful with {/} as delimiters but
might come in handy to those using longer delimiters
* Compiler now allows the use of the right delimiter inside strings (i.e. {"}"})
single template tag, example: {if $foo; "> $foo";$bar;/} is equal to:
{if $foo}> {$foo}{$bar}{/} - This also allow block operations such as:
{a http://url.com; "Text" /} which equals to {a http://url.com}Text{/}
+ Syntax: Block plugins that you want to call without content can be
self-closed just like XML tags (e.g. {a "http://url.com" /} )
+ Plugins: Added the {a} block plugin to generate <a> tags
+ API: Added Dwoo_Plugin::paramsToAttributes() utility function to help
with the creation of compilable xml/html-related plugins
* Syntax: Math expressions in strings are now only allowed when the entire
expression is delimited, e.g. {"/$foo/$bar"} evaluates as just that while
{"/`$foo/$bar`"} will result in "/".($foo/$bar), therefore processing the /
as a division, this is better since URLs using / are far more common than
math in strings
=> http://forum.dwoo.org/viewtopic.php?id=50
* Compiler now allows the use of the right delimiter inside strings (e.g. {"}"})
* Fixed a bug preventing if blocks containing a {elseif} followed by {else}
[2008-06-28] 0.9.2
! BC Break: Renamed the {strip} modifier/function to {whitespace}, this does
......
......@@ -41,7 +41,7 @@ abstract class Dwoo_Block_Plugin extends Dwoo_Plugin
$this->buffer .= $input;
}
// initialization code, receives the parameters from {block param1, param2}
// initialization code, receives the parameters from {block param1 param2}
// public function init($arg, $arg, ...);
/**
......
......@@ -657,24 +657,26 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$ptr += strlen($this->ld);
$subptr = $ptr;
$subparse = '';
while (true) {
$parsed = $this->parse($tpl, $subptr, null, false, 'root', $subptr);
if ($parsed === false) {
break;
} else {
$subparse .= $parsed;
}
// reload loop if the compiler was reset
if ($ptr === 0) {
continue 2;
}
$len = $subptr - $ptr;
$this->push($parsed, substr_count(substr($tpl, $ptr, $len), "\n"));
$ptr += $len;
if ($parsed === false) {
break;
}
}
$len = $subptr - $ptr + strlen($this->rd);
$this->push($subparse, substr_count(substr($tpl, $ptr, $len), "\n"));
$ptr += $len;
$ptr += strlen($this->rd);
$this->setLine(substr_count($this->rd, "\n"), true);
// adds additional line breaks between php closing and opening tags because the php parser removes those if there is just a single line break
if (substr($this->curBlock['buffer'], -2) === '?>' && preg_match('{^(([\r\n])([\r\n]?))}', substr($tpl, $ptr, 3), $m)) {
......@@ -1248,6 +1250,9 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$ptr++;
if ($this->debug) echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT '.$ptr.'<br/>';
break 2;
} elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') {
if ($this->debug) echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT '.$ptr.'<br/>';
break 2;
} elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
if ($this->debug) echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT '.$ptr.'<br/>';
break 2;
......@@ -1585,7 +1590,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if (preg_match('#(\$?\.?[a-z0-9_:]*(?:(?:(?:\.|->)(?:[a-z0-9_:]+|(?R))|\[(?:[a-z0-9_:]+|(?R))\]))*)' . // var key
($curBlock==='root' || $curBlock==='function' || $curBlock==='namedparam' || $curBlock==='condition' || $curBlock==='variable' || $curBlock==='expression' ? '(\([^)]*?\)(?:->[a-z0-9_]+(?:\([^)]*?\))?)*)?' : '()') . // method call
($curBlock==='root' || $curBlock==='function' || $curBlock==='namedparam' || $curBlock==='condition' || $curBlock==='variable' || $curBlock==='string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)':'()') . // simple math expressions
($curBlock==='root' || $curBlock==='function' || $curBlock==='namedparam' || $curBlock==='condition' || $curBlock==='variable' || $curBlock==='delimited_string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)':'()') . // simple math expressions
($curBlock!=='modifier' ? '((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?':'(())') . // modifiers
'#i', $substr, $match)) {
$key = substr($match[1], 1);
......@@ -1784,7 +1789,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
return $parsingParams;
} elseif ($curBlock === 'namedparam') {
return array($output, $key);
} elseif ($curBlock === 'string') {
} elseif ($curBlock === 'string' || $curBlock === 'delimited_string') {
return array($matchedLength, $output);
} elseif ($curBlock === 'expression' || $curBlock === 'variable') {
return $output;
......@@ -1794,7 +1799,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
return $output;
}
} else {
if ($curBlock === 'string') {
if ($curBlock === 'string' || $curBlock === 'delimited_string') {
return array(0, '');
} else {
throw new Dwoo_Compilation_Exception($this, 'Invalid variable name <em>'.$substr.'</em>');
......@@ -2050,7 +2055,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if ($this->debug) echo 'BREAKCHAR ('.$substr.') PARSED<br />';
//$substr = '"'.$substr.'"';
} else {
$substr = $this->replaceStringVars('"'.str_replace('"', '\\"', $substr).'"', '"', $curBlock);
$substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock);
if ($this->debug) echo 'BLABBER ('.$substr.') CASTED AS STRING<br />';
}
......@@ -2075,27 +2080,26 @@ class Dwoo_Compiler implements Dwoo_ICompiler
*/
protected function replaceStringVars($string, $first, $curBlock='')
{
// replace vars
$cnt=substr_count($string, '$');
$pos = 0;
if ($this->debug) echo 'STRING VAR REPLACEMENT : '.$string.'<br>';
while (--$cnt >= 0) {
if (isset($last)) {
$last = strrpos($string, '$', - (strlen($string) - $last + 1));
} else {
$last = strrpos($string, '$');
}
if (array_search($string[$last-1], array('\\', '/', '*', '+', '-', '%')) !== false) {
// replace vars
while (($pos = strpos($string, '$', $pos)) !== false) {
$prev = substr($string, $pos-1, 1);
if ($prev === '\\') {
$pos++;
continue;
}
// get var length first
$var = $this->parse($string, $last, null, false, $curBlock === 'modifier' ? 'modifier' : 'string');
$var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string':'string')));
$len = $var[0];
// reparse after removing every \" in the parsed string
$var = $this->parse(str_replace('\\'.$first, $first, $string), $last, null, false, $curBlock === 'modifier' ? 'modifier' : 'string');
$var = $this->parse(str_replace('\\'.$first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string':'string')));
$string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $last, $len);
if ($prev === '`' && substr($string, $pos+$len, 1) === '`') {
$string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos-1, $len+2);
} else {
$string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos, $len);
}
$pos += strlen($var[1]) + 2;
if ($this->debug) echo 'STRING VAR REPLACEMENT DONE : '.$string.'<br>';
}
......@@ -2108,9 +2112,6 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$string = str_replace('\\$', '$', $string);
}
// remove backticks around strings if needed
$string = preg_replace('#`(("|\').+?\2)`#', '$1', $string);
return $string;
}
......
......@@ -42,13 +42,49 @@ abstract class Dwoo_Plugin
$this->dwoo = $dwoo;
}
// plugins that have arguments should always implement :
// plugins should always implement :
// public function process($arg, $arg, ...)
// or for block plugins :
// public function init($arg, $arg, ...)
// this could be enforced with :
// public function process(...)
// if my bug entry gets enough interest one day..
// abstract public function process(...);
// if my feature request gets enough interest one day
// see => http://bugs.php.net/bug.php?id=44043
/**
* utility function that converts an array of compiled parameters (or rest array) to a string of xml/html tag attributes
*
* this is to be used in preProcessing or postProcessing functions, example :
* $p = $compiler->getCompiledParams($params);
* // get only the rest array as attributes
* $attributes = Dwoo_Plugin::paramsToAttributes($p['*']);
* // get all the parameters as attributes (if there is a rest array, it will be included)
* $attributes = Dwoo_Plugin::paramsToAttributes($p);
*
* @param array $params an array of attributeName=>value items that will be compiled to be ready for inclusion in a php string
* @param string $delim the string delimiter you want to use (defaults to ')
* @return string
*/
public static function paramsToAttributes(array $params, $delim = '\'')
{
if (isset($params['*'])) {
$params = array_merge($params, $params['*']);
unset($params['*']);
}
$out = '';
foreach ($params as $attr=>$val) {
$out .= ' '.$attr.'=';
if (trim($val, '"\'')=='' || $val=='null') {
$out .= str_replace($delim, '\\'.$delim, '""');
} elseif (substr($val, 0, 1) === $delim && substr($val, -1) === $delim) {
$out .= str_replace($delim, '\\'.$delim, '"'.substr($val, 1, -1).'"');
} else {
$out .= str_replace($delim, '\\'.$delim, '"') . $delim . '.'.$val.'.' . $delim . str_replace($delim, '\\'.$delim, '"');
}
}
return ltrim($out);
}
}
......@@ -443,15 +443,8 @@ class Dwoo_Smarty__Adapter extends Dwoo
// abs path
if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId);
} elseif (is_string($this->template_dir)) {
self::$tplCache[$hash] = new Dwoo_Template_File($this->template_dir.DIRECTORY_SEPARATOR.$file, null, $cacheId, $compileId);
} elseif (is_array($this->template_dir)) {
foreach ($this->template_dir as $dir) {
if (file_exists($dir.DIRECTORY_SEPARATOR.$file)) {
self::$tplCache[$hash] = new Dwoo_Template_File($this->template_dir.DIRECTORY_SEPARATOR.$file, null, $cacheId, $compileId);
break;
}
}
} elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId, $this->template_dir);
} else {
throw new Exception('Unable to load "'.$file.'", check the template_dir');
}
......
......@@ -29,6 +29,22 @@ class Dwoo_Template_File extends Dwoo_Template_String
protected $file;
/**
* include path(s) to look into to find this template
*
* @var array
*/
protected $includePath = null;
/**
* resolved path cache when looking for a file in multiple include paths
*
* this is reset when the include path is changed
*
* @var string
*/
protected $resolvedPath = null;
/**
* creates a template from a file
*
* @param string $file the path to the template file, make sure it exists
......@@ -40,8 +56,9 @@ class Dwoo_Template_File extends Dwoo_Template_String
* to the current url
* @param string $compileId the unique compiled identifier, which is used to distinguish this
* template from others, if null it defaults to the filename+bits of the path
* @param mixed $includePath a string for a single path to look into for the given file, or an array of paths
*/
public function __construct($file, $cacheTime = null, $cacheId = null, $compileId = null)
public function __construct($file, $cacheTime = null, $cacheId = null, $compileId = null, $includePath = null)
{
$this->file = $file;
$this->name = basename($file);
......@@ -54,6 +71,37 @@ class Dwoo_Template_File extends Dwoo_Template_String
if ($cacheId !== null) {
$this->cacheId = strtr($cacheId, '\\%?=!:;'.PATH_SEPARATOR, '/-------');
}
if (is_string($includePath)) {
$this->includePath = array($includePath);
} elseif (is_array($includePath)) {
$this->includePath = $includePath;
}
}
/**
* sets the include path(s) to where the given template filename must be looked up
*
* @param mixed $paths the path to look into, can be string for a single path or an array of paths
*/
public function setIncludePath($paths)
{
if (is_array($paths) === false) {
$paths = array($paths);
}
$this->includePath = $paths;
$this->resolvedPath = null;
}
/**
* return the current include path(s)
*
* @return array
*/
public function getIncludePath()
{
return $this->includePath;
}
/**
......@@ -110,7 +158,7 @@ class Dwoo_Template_File extends Dwoo_Template_String
*/
public function getSource()
{
return file_get_contents($this->file);
return file_get_contents($this->getResourceIdentifier());
}
/**
......@@ -130,7 +178,20 @@ class Dwoo_Template_File extends Dwoo_Template_String
*/
public function getResourceIdentifier()
{
return $this->file;
if ($this->resolvedPath !== null) {
return $this->resolvedPath;
} elseif ($this->includePath === null) {
return $this->file;
} else {
foreach ($this->includePath as $path) {
if (file_exists($path.DIRECTORY_SEPARATOR.$this->file) === true) {
$this->resolvedPath = $path . DIRECTORY_SEPARATOR . $this->file;
return $this->resolvedPath;
}
}
throw new Dwoo_Exception('Template "'.$this->file.'" could not be found in any of your include path(s)');
}
}
/**
......@@ -141,7 +202,7 @@ class Dwoo_Template_File extends Dwoo_Template_String
*/
public function getUid()
{
return (string) filemtime($this->file);
return (string) filemtime($this->getResourceIdentifier());
}
/**
......@@ -197,7 +258,7 @@ class Dwoo_Template_File extends Dwoo_Template_String
{
// no compile id was provided, set default
if ($this->compileId===null) {
$this->compileId = implode('/', array_slice(explode('/', strtr($this->file, '\\', '/')), -3));
$this->compileId = implode('/', array_slice(explode('/', strtr($this->getResourceIdentifier(), '\\', '/')), -3));
}
return $dwoo->getCompileDir() . $this->compileId.'.d'.Dwoo::RELEASE_TAG.'.php';
}
......
......@@ -219,7 +219,6 @@ class Dwoo_Template_String implements Dwoo_ITemplate
*/
public function getCachedTemplate(Dwoo $dwoo)
{
$cachedFile = $this->getCacheFilename($dwoo);
if ($this->cacheTime !== null) {
$cacheLength = $this->cacheTime;
} else {
......@@ -231,6 +230,8 @@ class Dwoo_Template_String implements Dwoo_ITemplate
return false;
}
$cachedFile = $this->getCacheFilename($dwoo);
if (isset(self::$cache['cached'][$this->cacheId]) === true && file_exists($cachedFile)) {
// already checked, return cache file
return $cachedFile;
......@@ -394,8 +395,13 @@ class Dwoo_Template_String implements Dwoo_ITemplate
$cacheId = $_SERVER['REQUEST_URI'];
} elseif (isset($_SERVER['SCRIPT_FILENAME']) && isset($_SERVER['argv'])) {
$cacheId = $_SERVER['SCRIPT_FILENAME'].'-'.implode('-', $_SERVER['argv']);
} else {
$cacheId = '';
}
$this->cacheId = strtr($cacheId, '\\%?=!:;'.PATH_SEPARATOR, '/-------');
// force compiled id generation
$this->getCompiledFilename($dwoo);
$this->cacheId = $this->compileId . strtr($cacheId, '\\%?=!:;'.PATH_SEPARATOR, '/-------');
}
return $dwoo->getCacheDir() . $this->cacheId.'.html';
}
......
......@@ -4,7 +4,6 @@
* Outputs a html &lt;a&gt; tag
* <pre>
* * href : the target URI where the link must point
* * text : text to display, if not provided the href parameter will be used
* * rest : any other attributes you want to add to the tag can be added as named parameters
* </pre>
*
......@@ -13,11 +12,13 @@
* <code>
* {* Create a simple link out of an url variable and add a special class attribute: *}
*
* {$url|a:class="external"}
* {a $url class="external" /}
*
* {* Mark a link as active depending on some other variable : *}
*
* {a $link.url $link.title class=tif($link.active "active")} {* This is similar to: <a href="{$link.url}" class="{if $link.active}active{/if}">{$link.title}</a> *}
* {a $link.url class=tif($link.active "active"); $link.title /}
*
* {* This is similar to: <a href="{$link.url}" class="{if $link.active}active{/if}">{$link.title}</a> *}
* </code>
*
* This software is provided 'as-is', without any express or implied warranty.
......@@ -36,17 +37,36 @@
* @date 2008-05-30
* @package Dwoo
*/
function Dwoo_Plugin_a_compile(Dwoo_Compiler $compiler, $href, $text=null, array $rest=array())
class Dwoo_Plugin_a extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
{
if ($text=='null') {
$text = $href;
}
$out = '\'<a href="\'.'.$href.'.\'"';
foreach ($rest as $attr=>$val) {
if (trim($val, '"\'')=='' || $val=='null') {
continue;
}
$out .= ' '.$attr.'="\'.'.$val.'.\'"';
}
return $out . '>\'.'.$text.'.\'</a>\'';
public function init($href, array $rest=array())
{
}
public static function preProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $type)
{
$p = $compiler->getCompiledParams($params);
$out = Dwoo_Compiler::PHP_OPEN . 'echo \'<a '.self::paramsToAttributes($p);
return $out.'>\';' . Dwoo_Compiler::PHP_CLOSE;
}
public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content)
{
$p = $compiler->getCompiledParams($params);
// no content was provided so use the url as display text
if ($content == "") {
// merge </a> into the href if href is a string
if (substr($p['href'], -1) === '"' || substr($p['href'], -1) === '\'') {
return Dwoo_Compiler::PHP_OPEN . 'echo '.substr($p['href'], 0, -1).'</a>'.substr($p['href'], -1).';'.Dwoo_Compiler::PHP_CLOSE;
}
// otherwise append
return Dwoo_Compiler::PHP_OPEN . 'echo '.$p['href'].'.\'</a>\';'.Dwoo_Compiler::PHP_CLOSE;
}
// return content
return $content . '</a>';
}
}
......@@ -2,12 +2,12 @@
/**
* Generic else block, it supports all builtin optional-display blocks which are if/for/foreach/loop/with
*
* If any of those block contains an else statement, the content between {else} and {/block} (you do not
*
* If any of those block contains an else statement, the content between {else} and {/block} (you do not
* need to close the else block) will be shown if the block's condition has no been met
*
*
* Example :
*
*
* <code>
* {foreach $array val}
* $array is not empty so we display it's values : {$val}
......@@ -34,6 +34,12 @@
*/
class Dwoo_Plugin_else extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
{
public static $types = array
(
'if' => true, 'elseif' => true, 'for' => true,
'foreach' => true, 'loop' => true, 'with' => true
);
public function init()
{
}
......@@ -42,7 +48,7 @@ class Dwoo_Plugin_else extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Blo
{
$block =& $compiler->getCurrentBlock();
$out = '';
while ($block['type'] !== 'if' && $block['type'] !== 'foreach' && $block['type'] !== 'for' && $block['type'] !== 'with' && $block['type'] !== 'loop') {
while (!isset(self::$types[$block['type']])) {
$out .= $compiler->removeTopBlock();
$block =& $compiler->getCurrentBlock();
}
......@@ -54,7 +60,7 @@ class Dwoo_Plugin_else extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Blo
$currentBlock =& $compiler->getCurrentBlock();
$currentBlock['params']['postOutput'] = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
return $out . "else {\n".Dwoo_Compiler::PHP_CLOSE;
return $out . " else {\n".Dwoo_Compiler::PHP_CLOSE;
}
public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content)
......
......@@ -22,17 +22,35 @@
*/
class Dwoo_Plugin_elseif extends Dwoo_Plugin_if implements Dwoo_ICompilable_Block
{
public static $types = array
(
'if' => true, 'elseif' => true
);
public function init(array $rest)
{
}
public static function preProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $type)
{
$if =& $compiler->findBlock('if', true);
$out = $if['params']['postOutput'];
$if['params']['postOutput'] = '';
// delete this block
$compiler->removeTopBlock();
// fetch the top of the stack
$parent =& $compiler->getCurrentBlock();
// loop until we get an elseif or if block
$out = '';
while (!isset(self::$types[$parent['type']])) {
$out .= $compiler->removeTopBlock();
$parent =& $compiler->getCurrentBlock();
}
//
$out .= $parent['params']['postOutput'];
$parent['params']['postOutput'] = '';
// reinsert this block
$compiler->injectBlock($type, $params, 1);
// generate post-output
$currentBlock =& $compiler->getCurrentBlock();
$currentBlock['params']['postOutput'] = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
......
......@@ -44,60 +44,66 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
reset($params);
while (list($k,$v) = each($params)) {
switch((string) $v) {
$v = (string) $v;
switch(substr($v, 0, 1) === '"' || substr($v, 0, 1) === '\'' ? substr($v, 1, -1) : $v) {
case '"and"':
case 'and':
$p[] = '&&';
break;
case '"or"':
case 'or':
$p[] = '||';
break;
case '"=="':
case '"eq"':
case '==':
case 'eq':
$p[] = '==';
break;
case '"<>"':
case '"!="':
case '"ne"':
case '"neq"':
case '<>':
case '!=':
case 'ne':
case 'neq':
$p[] = '!=';
break;
case '">="':
case '"gte"':
case '"ge"':
case '>=':
case 'gte':
case 'ge':
$p[] = '>=';
break;
case '"<="':
case '"lte"':
case '"le"':
case '<=':
case 'lte':
case 'le':
$p[] = '<=';
break;
case '">"':
case '"gt"':
case '>':
case 'gt':
$p[] = '>';
break;
case '"<"':
case '"lt"':
case '<':
case 'lt':
$p[] = '<';
break;
case '"==="':
case '===':
$p[] = '===';
break;
case '"!=="':
case '!==':
$p[] = '!==';
break;
case '"is"':
if ($params[$k+1] === '"not"') {
case 'is':
if (isset($params[$k+1]) && trim($params[$k+1], '"\'') === 'not') {
$negate = true;
next($params);
} else {
$negate = false;
}
$ptr = 1+(int)$negate;
if (!isset($params[$k+$ptr])) {
$params[$k+$ptr] = '';
} else {
$params[$k+$ptr] = trim($params[$k+$ptr], '"\'');
}
switch($params[$k+$ptr]) {
case '"div"':
if (isset($params[$k+$ptr+1]) && $params[$k+$ptr+1] === '"by"') {
case 'div':
if (isset($params[$k+$ptr+1]) && trim($params[$k+$ptr+1], '"\'') === 'by') {
$p[] = ' % '.$params[$k+$ptr+2].' '.($negate?'!':'=').'== 0';
next($params);
next($params);
......@@ -106,9 +112,9 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
throw new Dwoo_Compilation_Exception($compiler, 'If : Syntax error : syntax should be "if $a is [not] div by $b", found '.$params[$k-1].' is '.($negate?'not ':'').'div '.$params[$k+$ptr+1].' '.$params[$k+$ptr+2]);
}
break;
case '"even"':
case 'even':
$a = array_pop($p);
if (isset($params[$k+$ptr+1]) && $params[$k+$ptr+1] === '"by"') {
if (isset($params[$k+$ptr+1]) && trim($params[$k+$ptr+1], '"\'') === 'by') {
$b = $params[$k+$ptr+2];
$p[] = '('.$a .' / '.$b.') % 2 '.($negate?'!':'=').'== 0';
next($params);
......@@ -118,9 +124,9 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
}
next($params);
break;
case '"odd"':
case 'odd':
$a = array_pop($p);
if (isset($params[$k+$ptr+1]) && $params[$k+$ptr+1] === '"by"') {
if (isset($params[$k+$ptr+1]) && trim($params[$k+$ptr+1], '"\'') === 'by') {
$b = $params[$k+$ptr+2];
$p[] = '('.$a .' / '.$b.') % 2 '.($negate?'=':'!').'== 0';
next($params);
......@@ -135,12 +141,12 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
}
break;
case '"%"':
case '"mod"':
case '%':
case 'mod':
$p[] = '%';
break;
case '"!"':
case '"not"':
case '!':
case 'not':
$p[] = '!';
break;
default:
......
......@@ -41,7 +41,7 @@ class Dwoo_Plugin_extends extends Dwoo_Plugin implements Dwoo_ICompilable
$inheritanceTree = array(array('source'=>$compiler->getTemplateSource()));
while (!empty($file)) {
if ($file === '""' || $file === "''" || (substr($file, 0, 1) !== '"' && substr($file, 0, 1) !== '"')) {
if ($file === '""' || $file === "''" || (substr($file, 0, 1) !== '"' && substr($file, 0, 1) !== '\'')) {
throw new Dwoo_Compilation_Exception($compiler, 'Extends : The file name must be a non-empty string');
return;
}
......
......@@ -14,6 +14,30 @@ class BlockTests extends PHPUnit_Framework_TestCase
$this->dwoo = new Dwoo(DWOO_COMPILE_DIR, DWOO_CACHE_DIR);
}
public function testA()
{
$tpl = new Dwoo_Template_String('{a "http://foo/" test="foo" bar="bar"; "Foo!" /}');
$tpl->forceCompilation();
$this->assertEquals('<a href="http://foo/" test="foo" bar="bar">Foo!</a>', $this->dwoo->get($tpl, array(), $this->compiler));
$tpl = new Dwoo_Template_String('{a $url test="foo" bar="bar"}');
$tpl->forceCompilation();
$this->assertEquals('<a href="http://foo/" test="foo" bar="bar">http://foo/</a>', $this->dwoo->get($tpl, array('url'=>'http://foo/'), $this->compiler));
$tpl = new Dwoo_Template_String('{a $url foo="bar"; "text" /}
{a $url; "" /}
{a $url; /}
{a $url}{/}');
$tpl->forceCompilation();
$this->assertEquals('<a href="http://foo/" foo="bar">text</a>
<a href="http://foo/"></a>
<a href="http://foo/">http://foo/</a>
<a href="http://foo/">http://foo/</a>', $this->dwoo->get($tpl, array('url'=>'http://foo/'), $this->compiler));
}
public function testAutoEscape()
{
$cmp = new Dwoo_Compiler();
......@@ -135,7 +159,7 @@ baz"));
$fixCall = new Dwoo_Plugin_if ($this->dwoo);
$fixCall->init(array());
}
public function testIfVariation2 ()
{
$tpl = new Dwoo_Template_String('{if 4/2==2 && 2!=1 && 3>0 && 4<5 && 5<=5 && 6>=3 && 3===3 && "3"!==3}true{/if}');
......@@ -143,7 +167,7 @@ baz"));
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfVariation3 ()
{
$tpl = new Dwoo_Template_String('{if 5%2==1 && !isset($foo)}true{/if}');
......@@ -151,7 +175,7 @@ baz"));
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfVariation4 ()
{
$tpl = new Dwoo_Template_String('{if 5 is not div by 2 && 4 is div by 2 && 6 is even && 6 is not even by 5 && (3 is odd && 9 is odd by 3)}true{/if}');
......@@ -159,7 +183,7 @@ baz"));
$this->assertEquals('true', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfVariation5 ()
{
$tpl = new Dwoo_Template_String('{if (3==4 && 5==5) || 3==3}true{/if}');
......@@ -192,6 +216,38 @@ baz"));
$fixCall->init();
}
public function testIfElseifElse()
{
$tpl = new Dwoo_Template_String('{if "BAR" == "bar"}true{elseif 3==5}true{else}false{/if}');
$tpl->forceCompilation();
$this->assertEquals('false', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfElseifElseifElse()
{
$tpl = new Dwoo_Template_String('{if "BAR" == "bar"}true{elseif 3==5}true{elseif 5==3}true{else}false{/if}');
$tpl->forceCompilation();
$this->assertEquals('false', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfElseifElseif()
{
$tpl = new Dwoo_Template_String('{if "BAR" == "bar"}true{elseif 3==5}true{elseif 5==5}moo{/if}');
$tpl->forceCompilation();
$this->assertEquals('moo', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfElseifElseifVariation2()
{
$tpl = new Dwoo_Template_String('{if "BAR" == "bar"}true{elseif 5==5}moo{elseif 3==5}true{/if}');
$tpl->forceCompilation();
$this->assertEquals('moo', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testIfElseImplicitUnset()
{
$tpl = new Dwoo_Template_String('{if $moo}true{else}false{/if}');
......
......@@ -223,16 +223,19 @@ replace="BAR"
$tpl->forceCompilation();
$this->assertEquals("10 10 40 145 5 3.3 3.3 win win", $this->dwoo->get($tpl, array('foo'=>5, 'arr'=>array(8=>'win')), $this->compiler));
}
$tpl = new Dwoo_Template_String('{"$foo/$foo"}');
public function testDelimitedExpressionsInString()
{
$tpl = new Dwoo_Template_String('{"`$foo/$foo`"}');
$tpl->forceCompilation();
$this->assertEquals("1", $this->dwoo->get($tpl, array('foo'=>5), $this->compiler));
}
public function testNonExpressions()
public function testNonDelimitedExpressionsInString()
{
$tpl = new Dwoo_Template_String('{"`$foo`/`$foo`"}');
$tpl = new Dwoo_Template_String('{"$foo/$foo"}');
$tpl->forceCompilation();
$this->assertEquals("5/5", $this->dwoo->get($tpl, array('foo'=>5), $this->compiler));
......
......@@ -28,21 +28,22 @@ class DwooTests extends PHPUnit_Framework_TestSuite {
return $suite;
}
protected function tearDown() {
$this->clearDir(TEST_DIRECTORY.'/temp/compiled', true);
protected function tearDown() {
$this->clearDir(TEST_DIRECTORY.'/temp/compiled', true);
}
protected function clearDir($path, $emptyOnly=false)
{
if (is_dir($path)) {
foreach (glob($path.'/*') as $f)
$this->clearDir($f);
if (!$emptyOnly) {
rmdir($path);
}
} else {
unlink($path);
}
if (is_dir($path)) {
foreach (glob($path.'/*') as $f) {
$this->clearDir($f);
}
if (!$emptyOnly) {
rmdir($path);
}
} else {
unlink($path);
}
}
}
......@@ -67,3 +68,24 @@ class DwooConstraintStringEquals extends PHPUnit_Framework_Constraint
return 'equals expected value.'.PHP_EOL.'Expected:'.PHP_EOL.$this->target.PHP_EOL.'Received:'.PHP_EOL.$this->other.PHP_EOL;
}
}
class DwooConstraintPathEquals extends PHPUnit_Framework_Constraint
{
protected $target;
public function __construct($target)
{
$this->target = preg_replace('#([\\\\/]{1,2})#', '/', $target);
}
public function evaluate($other)
{
$this->other = preg_replace('#([\\\\/]{1,2})#', '/', $other);
return $this->target == $this->other;
}
public function toString()
{
return 'equals expected value.'.PHP_EOL.'Expected:'.PHP_EOL.$this->target.PHP_EOL.'Received:'.PHP_EOL.$this->other.PHP_EOL;
}
}
\ No newline at end of file
......@@ -14,19 +14,6 @@ class FuncTests extends PHPUnit_Framework_TestCase
$this->dwoo = new Dwoo(DWOO_COMPILE_DIR, DWOO_CACHE_DIR);
}
public function testA()
{
$tpl = new Dwoo_Template_String('{a "http://foo/" "Foo!" test="foo" bar="bar"}');
$tpl->forceCompilation();
$this->assertEquals('<a href="http://foo/" test="foo" bar="bar">Foo!</a>', $this->dwoo->get($tpl, array(), $this->compiler));
$tpl = new Dwoo_Template_String('{a $url test="foo" bar="bar"}');
$tpl->forceCompilation();
$this->assertEquals('<a href="http://foo/" test="foo" bar="bar">http://foo/</a>', $this->dwoo->get($tpl, array('url'=>'http://foo/'), $this->compiler));
}
public function testAssign()
{
// test simple assign
......
<?php
require_once 'Dwoo/Compiler.php';
class TemplateTests extends PHPUnit_Framework_TestCase
{
protected $compiler;
protected $dwoo;
public function __construct()
{
$this->compiler = new Dwoo_Compiler();
$this->dwoo = new Dwoo(DWOO_COMPILE_DIR, DWOO_CACHE_DIR);
}
public function testIncludePath()
{
// no include path
$tpl = new Dwoo_Template_File('test.html');
$this->assertEquals('test.html', $tpl->getResourceIdentifier());
// include path in constructor
$tpl = new Dwoo_Template_File('test.html', null, null, null, TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources');
$this->assertEquals(TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'test.html', $tpl->getResourceIdentifier());
// set include path as string
$tpl->setIncludePath(TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'subfolder'.DIRECTORY_SEPARATOR);
$this->assertThat($tpl->getResourceIdentifier(), new DwooConstraintPathEquals(TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'subfolder'.DIRECTORY_SEPARATOR.'test.html'));
// set include path as array
$tpl->setIncludePath(array(TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'subfolder2', TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'subfolder'.DIRECTORY_SEPARATOR));
$this->assertThat($tpl->getResourceIdentifier(), new DwooConstraintPathEquals(TEST_DIRECTORY.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'subfolder2'.DIRECTORY_SEPARATOR.'test.html'));
}
}
{$bar}{$foo}
\ No newline at end of file
{$bar}{$foo}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment