Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Vitaliy Filippov | 7f7a2f2dc6 | |
Vitaliy Filippov | 2e50829f8c |
10
compile.sh
10
compile.sh
|
@ -1,14 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ "$LIME_DIR" = "" ]; then
|
||||
LIME_DIR=./lime/
|
||||
LIME_DIR=~/gits/lime/
|
||||
fi
|
||||
|
||||
php -d xdebug.max_nesting_level=200 $LIME_DIR/lime.php template.lime | tail -n +2 > template.class
|
||||
LINES=`grep -n -h " \*\*\* DON'T EDIT THIS FILE! \*\*\*" VMXTemplateCompiler.php | perl -pe 's/(\d+):.*/$1-2/e'`
|
||||
LINES=`grep -n -h " \*\*\* DON'T EDIT THIS FILE! \*\*\*" template.parser.php | perl -pe 's/(\d+):.*/$1-2/e'`
|
||||
if [ "$LINES" != "" ]; then
|
||||
head -n $LINES VMXTemplateCompiler.php | cat - template.class > VMXTemplateCompiler.php.new
|
||||
head -n $LINES template.parser.php | cat - template.class > template.parser.php.new
|
||||
else
|
||||
cat VMXTemplateCompiler.php template.class > VMXTemplateCompiler.php.new
|
||||
cat template.parser.php template.class > template.parser.php.new
|
||||
fi
|
||||
mv VMXTemplateCompiler.php.new VMXTemplateCompiler.php
|
||||
mv template.parser.php.new template.parser.php
|
||||
|
|
183
template.lime
183
template.lime
|
@ -50,8 +50,6 @@
|
|||
%token ">" "greater than operator '>'"
|
||||
%token "<=" "less or equal operator '<='"
|
||||
%token ">=" "greater or equal operator '>='"
|
||||
%token "?" "ternary operator '? :'"
|
||||
%token ":" "ternary operator '? :'"
|
||||
%token "+" "plus operator '+'"
|
||||
%token "-" "minus operator '-'"
|
||||
%token "*" "multiply operator '*'"
|
||||
|
@ -73,7 +71,6 @@
|
|||
%token "}}" "substitution end"
|
||||
|
||||
%left ".."
|
||||
%nonassoc "?" ":"
|
||||
%left "||" "OR" "XOR"
|
||||
%left "&&" "AND"
|
||||
%nonassoc "==" "!=" "<" ">" "<=" ">="
|
||||
|
@ -84,95 +81,80 @@
|
|||
# Директивы
|
||||
|
||||
template = chunks {
|
||||
$this->template->st->functions['main']['body'] = "function fn_main() {\$stack = array();\n\$t = '';\n".$1."\nreturn \$t;\n}\n";
|
||||
$this->template->st->AST = $1;
|
||||
$$ = '';
|
||||
}
|
||||
.
|
||||
chunks = {
|
||||
$$ = '';
|
||||
$$ = [];
|
||||
}
|
||||
| chunks chunk {
|
||||
$$ = $1 . "# line ".$this->template->lexer->lineno."\n" . $2;
|
||||
$$ = $1;
|
||||
if ($2) {
|
||||
$$[] = $2;
|
||||
}
|
||||
}
|
||||
.
|
||||
chunk = literal {
|
||||
$$ = ($1 != "''" && $1 != '""' ? '$t .= ' . $1 . ";\n" : '');
|
||||
$$ = [ 'literal', $1 ];
|
||||
}
|
||||
| "<!--" code_chunk/c "-->" {
|
||||
$$ = $c;
|
||||
}
|
||||
| "{{" exp/e "}}" {
|
||||
$$ = '$t .= ' . ($e[1] || !$this->template->options->auto_escape ? $e[0] : $this->template->compile_function($this->template->options->auto_escape, [ $e ])[0]) . ";\n";
|
||||
$$ = [ 'subst', $e ];
|
||||
}
|
||||
| error/e {
|
||||
$$ = '';
|
||||
$$ = false;
|
||||
}
|
||||
.
|
||||
code_chunk = c_if/$ | c_set/$ | c_fn/$ | c_for/$ | exp/e {
|
||||
$$ = '$t .= ' . ($e[1] || !$this->template->options->auto_escape ? $e[0] : $this->template->compile_function($this->template->options->auto_escape, [ $e ])[0]) . ";\n";
|
||||
$$ = [ 'subst', $e ];
|
||||
}
|
||||
.
|
||||
c_if = "IF" exp/e "-->" chunks/if "<!--" "END" {
|
||||
$$ = "if (" . $e[0] . ") {\n" . $if . "}\n";
|
||||
$$ = [ 'if', [ $e, $if ] ];
|
||||
}
|
||||
| "IF" exp/e "-->" chunks/if "<!--" "ELSE" "-->" chunks/else "<!--" "END" {
|
||||
$$ = "if (" . $e[0] . ") {\n" . $if . "} else {\n" . $else . "}\n";
|
||||
$$ = [ 'if', [ $e, $if ], [ false, $else ] ];
|
||||
}
|
||||
| "IF" exp/e "-->" chunks/if c_elseifs/ei chunks/ec "<!--" "END" {
|
||||
$$ = "if (" . $e[0] . ") {\n" . $if . $ei . $ec . "}\n";
|
||||
$$ = $ei;
|
||||
$$[count($$)-1] = $ec;
|
||||
$$ = array_merge([ 'if', [ $e, $if ] ], $ei);
|
||||
}
|
||||
| "IF" exp/e "-->" chunks/if c_elseifs/ei chunks/ec "<!--" "ELSE" "-->" chunks/else "<!--" "END" {
|
||||
$$ = "if (" . $e[0] . ") {\n" . $if . $ei . $ec . "} else {\n" . $else . "}\n";
|
||||
$$ = $ei;
|
||||
$$[count($$)-1] = $ec;
|
||||
$$[] = [ false, $else ];
|
||||
$$ = array_merge([ 'if', [ $e, $if ] ], $$);
|
||||
}
|
||||
.
|
||||
c_elseifs = "<!--" elseif exp/e "-->" {
|
||||
$$ = "} elseif (" . $e[0] . ") {\n";
|
||||
$$ = [ [ $e ] ];
|
||||
}
|
||||
| c_elseifs/p chunks/cs "<!--" elseif exp/e "-->" {
|
||||
$$ = $p . $cs . "} elseif (" . $e[0] . ") {\n";
|
||||
$$ = $p;
|
||||
$$[count($$)-1][] = $cs;
|
||||
$$[] = [ $e ];
|
||||
}
|
||||
.
|
||||
c_set = "SET" varref/v "=" exp/e {
|
||||
$$ = $v[0] . ' = ' . $e[0] . ";\n";
|
||||
$$ = [ 'set', $v, [ 'subst', $e ] ];
|
||||
}
|
||||
| "SET" varref/v "-->" chunks/cs "<!--" "END" {
|
||||
$$ = "\$stack[] = \$t;\n\$t = '';\n" . $cs . $v[0] . " = \$t;\n\$t = array_pop(\$stack);\n";
|
||||
$$ = [ 'set', $v, $cs ];
|
||||
}
|
||||
.
|
||||
c_fn = fn name/name "(" arglist/args ")" "=" exp/exp {
|
||||
$this->template->st->functions[$name] = array(
|
||||
'name' => $name,
|
||||
'args' => $args,
|
||||
'body' => 'function fn_'.$name." () {\nreturn ".$exp[0].";\n}\n",
|
||||
//'line' => $line, Ой, я чо - аргументы не юзаю?
|
||||
//'pos' => $pos,
|
||||
);
|
||||
$$ = '';
|
||||
$$ = [ 'function', $name, $args, [ 'subst', $exp ] ];
|
||||
}
|
||||
| fn name/name "(" arglist/args ")" "-->" chunks/cs "<!--" "END" {
|
||||
$this->template->st->functions[$name] = array(
|
||||
'name' => $name,
|
||||
'args' => $args,
|
||||
'body' => 'function fn_'.$name." () {\$stack = array();\n\$t = '';\n".$cs."\nreturn \$t;\n}\n",
|
||||
//'line' => $line,
|
||||
//'pos' => $pos,
|
||||
);
|
||||
$$ = '';
|
||||
$$ = [ 'function', $name, $args, $cs ];
|
||||
}
|
||||
.
|
||||
c_for = for varref/varref "=" exp/exp "-->" chunks/cs "<!--" "END" {
|
||||
$varref_index = substr($varref[0], 0, -1) . ".'_index']";
|
||||
$$ = "\$stack[] = ".$varref[0].";
|
||||
\$stack[] = ".$varref_index.";
|
||||
\$stack[] = 0;
|
||||
foreach ((array)($exp[0]) as \$item) {
|
||||
".$varref[0]." = \$item;
|
||||
".$varref_index." = \$stack[count(\$stack)-1]++;
|
||||
".$cs."}
|
||||
array_pop(\$stack);
|
||||
".$varref_index." = array_pop(\$stack);
|
||||
".$varref[0]." = array_pop(\$stack);
|
||||
";
|
||||
$$ = [ 'for', $varref, $exp, $cs ];
|
||||
}
|
||||
.
|
||||
fn = "FUNCTION" | "BLOCK" | "MACRO" .
|
||||
|
@ -182,98 +164,91 @@ elseif = "ELSE" "IF" | "ELSIF" | "ELSEIF" .
|
|||
# Выражения
|
||||
|
||||
exp: exp/a ".." exp/b {
|
||||
$$ = [ '(' . $a[0] . ' . ' . $b[0] . ')', $a[1] && $b[1] ];
|
||||
$$ = [ 'op', '.', $a, $b ];
|
||||
}
|
||||
| exp/a "||" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' ?: ' . $b[0] . ')', $a[1] && $b[1] ];
|
||||
$$ = [ 'op', '||', $a, $b ];
|
||||
}
|
||||
| exp/a "OR" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' ?: ' . $b[0] . ')', $a[1] && $b[1] ];
|
||||
}
|
||||
$$ = [ 'op', '||', $a, $b ];
|
||||
}
|
||||
| exp/a "XOR" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' XOR ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', 'XOR', $a, $b ];
|
||||
}
|
||||
| exp/a "&&" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' && ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '&&', $a, $b ];
|
||||
}
|
||||
| exp/a "AND" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' && ' . $b[0] . ')', true ];
|
||||
}
|
||||
| exp/a "?" exp/b ":" exp/c {
|
||||
$$ = [ '(' . $a[0] . ' ? ' . $b[0] . ' : ' . $c[0] . ')', $b[1] && $c[1] ];
|
||||
$$ = [ 'op', '&&', $a, $b ];
|
||||
}
|
||||
| exp/a "==" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' == ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '==', $a, $b ];
|
||||
}
|
||||
| exp/a "!=" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' != ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '!=', $a, $b ];
|
||||
}
|
||||
| exp/a "<" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' < ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '<', $a, $b ];
|
||||
}
|
||||
| exp/a ">" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' > ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '>', $a, $b ];
|
||||
}
|
||||
| exp/a "<=" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' <= ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '<=', $a, $b ];
|
||||
}
|
||||
| exp/a ">=" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' >= ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '>=', $a, $b ];
|
||||
}
|
||||
| exp/a "+" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' + ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '+', $a, $b ];
|
||||
}
|
||||
| exp/a "-" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' - ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '-', $a, $b ];
|
||||
}
|
||||
| exp/a "&" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' & ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '&', $a, $b ];
|
||||
}
|
||||
| exp/a "*" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' * ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '*', $a, $b ];
|
||||
}
|
||||
| exp/a "/" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' / ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '/', $a, $b ];
|
||||
}
|
||||
| exp/a "%" exp/b {
|
||||
$$ = [ '(' . $a[0] . ' % ' . $b[0] . ')', true ];
|
||||
$$ = [ 'op', '%', $a, $b ];
|
||||
}
|
||||
| p10/$
|
||||
.
|
||||
p10: p11/$
|
||||
| '-' p11/a {
|
||||
$$ = [ '(-'.$a[0].')', true ];
|
||||
$$ = [ 'op', '-', $a ];
|
||||
}
|
||||
.
|
||||
p11: nonbrace
|
||||
p11: nonbrace/$
|
||||
| '(' exp/e ')' varpath/p {
|
||||
$$ = [ ($p !== '' ? 'self::noop('.$e[0].')'.$p : '('.$e[0].')'), false ];
|
||||
$$ = [ 'varpath', $e, $p ];
|
||||
}
|
||||
| '!' p11/a {
|
||||
$$ = [ '(!'.$a[0].')', true ];
|
||||
$$ = [ 'op', '!', $a ];
|
||||
}
|
||||
| "NOT" p11/a {
|
||||
$$ = [ '(!'.$a[0].')', true ];
|
||||
$$ = [ 'op', '!', $a ];
|
||||
}
|
||||
.
|
||||
nonbrace: '{' hash/h '}' {
|
||||
$$ = [ 'array(' . $h . ')', true ];
|
||||
}
|
||||
| literal {
|
||||
$$ = [ $1, true ];
|
||||
}
|
||||
nonbrace: '{' hash/$ '}'
|
||||
| literal/$
|
||||
| varref/$
|
||||
| name/f '(' ')' {
|
||||
$$ = $this->template->compile_function($f, []);
|
||||
$$ = [ 'call', $f, [] ];
|
||||
}
|
||||
| name/f '(' list/args ')' {
|
||||
$$ = $this->template->compile_function($f, $args);
|
||||
$$ = [ 'call', $f, $args ];
|
||||
}
|
||||
| name/f '(' gthash/args ')' {
|
||||
$$ = [ "\$this->parent->call_block('".addcslashes($f, "'\\")."', array(".$args."), '".addcslashes($this->template->lexer->errorinfo(), "'\\")."')", true ];
|
||||
$$ = [ 'call_block', $f, $args, $this->template->lexer->errorpos() ];
|
||||
}
|
||||
| name/f nonbrace/arg {
|
||||
$$ = $this->template->compile_function($f, [ $arg ]);
|
||||
$$ = [ 'call', $f, [ $arg ] ];
|
||||
}
|
||||
.
|
||||
list: exp/e {
|
||||
|
@ -295,57 +270,61 @@ arglist: name/n {
|
|||
$$ = [];
|
||||
}
|
||||
.
|
||||
hash: pair/$
|
||||
hash: pair/p {
|
||||
$$ = [ 'hash', $p ];
|
||||
}
|
||||
| pair/p ',' hash/h {
|
||||
$$ = $p . ', ' . $h;
|
||||
array_splice($h, 1, 0, [ $p ]);
|
||||
$$ = $h;
|
||||
}
|
||||
| {
|
||||
$$ = '';
|
||||
$$ = [ 'hash' ];
|
||||
}
|
||||
.
|
||||
gthash: gtpair/$
|
||||
gthash: gtpair/p {
|
||||
$$ = [ 'hash', $p ];
|
||||
}
|
||||
| gtpair/p ',' gthash/h {
|
||||
$$ = $p . ', ' . $h;
|
||||
array_splice($h, 1, 0, [ $p ]);
|
||||
$$ = $h;
|
||||
}
|
||||
.
|
||||
pair: exp/k ',' exp/v {
|
||||
$$ = $k[0] . ' => ' . $v[0];
|
||||
$$ = [ $k, $v ];
|
||||
}
|
||||
| gtpair/$
|
||||
.
|
||||
gtpair: exp/k "=>" exp/v {
|
||||
$$ = $k[0] . ' => ' . $v[0];
|
||||
$$ = [ $k, $v ];
|
||||
}
|
||||
.
|
||||
varref: name/n {
|
||||
$$ = [ "\$this->tpldata['".addcslashes($n, "\\\'")."']", false ];
|
||||
$$ = [ 'varref', $n ];
|
||||
}
|
||||
| varref/v varpart/p {
|
||||
$$ = [ $v[0] . $p, false ];
|
||||
$v[] = $p;
|
||||
$$ = $v;
|
||||
}
|
||||
.
|
||||
varpart: '.' namekw/n {
|
||||
$$ = "['".addcslashes($n, "\\\'")."']";
|
||||
$$ = [ 'index', $n ];
|
||||
}
|
||||
| '[' exp/e ']' {
|
||||
$$ = '['.$e[0].']';
|
||||
$$ = [ 'index', $e ];
|
||||
}
|
||||
| '.' namekw/n '(' ')' {
|
||||
$$ = '->'.$n.'()';
|
||||
$$ = [ 'method', $n, [] ];
|
||||
}
|
||||
| '.' namekw/n '(' list/l ')' {
|
||||
$argv = [];
|
||||
foreach ($l as $a) {
|
||||
$argv[] = $a[0];
|
||||
}
|
||||
$$ = '->'.$n.'('.implode(', ', $argv).')';
|
||||
$$ = [ 'method', $n, $l ];
|
||||
}
|
||||
.
|
||||
varpath: {
|
||||
$$ = '';
|
||||
$$ = [];
|
||||
}
|
||||
| varpath/a varpart/p {
|
||||
$$ = $a . $p;
|
||||
$a[] = $p;
|
||||
$$ = $a;
|
||||
}
|
||||
.
|
||||
namekw: name
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,12 +7,12 @@
|
|||
*
|
||||
* Homepage: http://yourcmc.ru/wiki/VMX::Template
|
||||
* License: GNU GPLv3 or later
|
||||
* Author: Vitaliy Filippov, 2006-2020
|
||||
* Version: V3 (LALR), 2020-01-01
|
||||
* Author: Vitaliy Filippov, 2006-2015
|
||||
* Version: V3 (LALR), 2015-04-12
|
||||
*
|
||||
* The template engine is split into two parts:
|
||||
* (1) This file - always used when running templates
|
||||
* (2) VMXTemplateCompiler.php - used only when compiling new templates
|
||||
* (2) template.parser.php - used only when compiling new templates
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -49,9 +49,6 @@ if (!defined('TS_UNIX'))
|
|||
|
||||
class VMXTemplate
|
||||
{
|
||||
// Loaded template class names
|
||||
public static $loadedClasses = [];
|
||||
|
||||
static $Mon, $mon, $Wday;
|
||||
static $cache_type = NULL;
|
||||
static $cache = array();
|
||||
|
@ -233,17 +230,16 @@ class VMXTemplate
|
|||
|
||||
/**
|
||||
* parse_real variant that does not require $vars to be an lvalue
|
||||
* and does not run filters on output
|
||||
*/
|
||||
protected function parse_discard($fn, $inline, $func, $vars = NULL)
|
||||
{
|
||||
return $this->parse_real($fn, $inline, $func, $vars, false);
|
||||
return $this->parse_real($fn, $inline, $func, $vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Real" parse function, handles all parse_*()
|
||||
*/
|
||||
protected function parse_real($fn, $inline, $func, &$vars = NULL, $run_filters = true)
|
||||
protected function parse_real($fn, $inline, $func, &$vars = NULL)
|
||||
{
|
||||
if (!$fn)
|
||||
{
|
||||
|
@ -329,7 +325,7 @@ class VMXTemplate
|
|||
{
|
||||
error_reporting($old);
|
||||
}
|
||||
if ($run_filters && $this->options->filters)
|
||||
if ($this->options->filters)
|
||||
{
|
||||
$filters = $this->options->filters;
|
||||
if (is_callable($filters) || is_string($filters) && is_callable(array(__CLASS__, "filter_$filters")))
|
||||
|
@ -352,40 +348,6 @@ class VMXTemplate
|
|||
return $t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate template file line number from stack frame $frame (taken from debug_backtrace())
|
||||
*/
|
||||
public function translateLine(&$frame)
|
||||
{
|
||||
if (isset(VMXTemplate::$loadedClasses[$frame['file']]))
|
||||
{
|
||||
$class = VMXTemplate::$loadedClasses[$frame['file']];
|
||||
if (isset($class::$smap))
|
||||
{
|
||||
$l = $frame['line'];
|
||||
$s = 0;
|
||||
$e = count($class::$smap);
|
||||
while ($e > $s+1)
|
||||
{
|
||||
if ($l < $class::$smap[($e+$s)>>1][0])
|
||||
$e = ($e+$s)>>1;
|
||||
else
|
||||
$s = ($e+$s)>>1;
|
||||
}
|
||||
$frame['file'] = $class::$template_filename;
|
||||
$frame['line'] = $class::$smap[$s][1];
|
||||
}
|
||||
}
|
||||
if (!empty($frame['class']) && substr($frame['class'], 0, 9) == 'Template_')
|
||||
{
|
||||
$class = $frame['class'];
|
||||
$frame['class'] = $class::$template_filename;
|
||||
$frame['type'] = '->';
|
||||
if (substr($frame['function'], 0, 3) == 'fn_')
|
||||
$frame['function'] = substr($frame['function'], 3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load file (with caching)
|
||||
*
|
||||
|
@ -462,15 +424,12 @@ class VMXTemplate
|
|||
$func_ns = md5($fn);
|
||||
}
|
||||
|
||||
if ($this->options->strip_space)
|
||||
self::filter_strip_space($code);
|
||||
if (!$this->compiler)
|
||||
{
|
||||
require_once(dirname(__FILE__).'/VMXTemplateCompiler.php');
|
||||
require_once(dirname(__FILE__).'/template.parser.php');
|
||||
$this->compiler = new VMXTemplateCompiler($this->options);
|
||||
}
|
||||
$compiled = $this->compiler->parse_all($code, $fn, $func_ns);
|
||||
$compiled .= "VMXTemplate::\$loadedClasses['".addcslashes(realpath(dirname($file)).'/'.basename($file), '\\\'')."'] = 'Template_$func_ns';\n";
|
||||
if (!file_put_contents($file, $compiled))
|
||||
{
|
||||
throw new VMXTemplateException("Failed writing $file");
|
||||
|
@ -501,7 +460,7 @@ class VMXTemplate
|
|||
{
|
||||
// FIXME maybe do it better!
|
||||
$fn = $this->function_search_path[$block][0][0];
|
||||
return $this->parse_real($fn, NULL, $block, $args, false);
|
||||
return $this->parse_real($fn, NULL, $block, $args);
|
||||
}
|
||||
throw new VMXTemplateException("Unknown block '$block'$errorinfo");
|
||||
}
|
||||
|
@ -512,7 +471,7 @@ class VMXTemplate
|
|||
{
|
||||
$fun = $this->function_search_path[$block][0];
|
||||
$args = array_combine($fun[1], array_pad(array_slice($args, 0, count($fun[1])), count($fun[1]), NULL));
|
||||
return $this->parse_real($fun[0], NULL, $block, $args, false);
|
||||
return $this->parse_real($fun[0], NULL, $block, $args);
|
||||
}
|
||||
throw new VMXTemplateException("Unknown block or function '$block'$errorinfo");
|
||||
}
|
||||
|
@ -597,14 +556,7 @@ class VMXTemplate
|
|||
static function exec_subst($str)
|
||||
{
|
||||
$args = func_get_args();
|
||||
$str = preg_replace_callback(
|
||||
'/(?<!\\\\)((?:\\\\\\\\)*)\$(?:([1-9]\d*)|\{([1-9]\d*)\})/is',
|
||||
function($m) use($args)
|
||||
{
|
||||
return $args[$m[2] ? $m[2] : $m[3]];
|
||||
},
|
||||
$str
|
||||
);
|
||||
$str = preg_replace_callback('/(?<!\\\\)((?:\\\\\\\\)*)\$(?:([1-9]\d*)|\{([1-9]\d*)\})/is', create_function('$m', 'return $args[$m[2]?$m[2]:$m[3]];'), $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
@ -632,11 +584,11 @@ class VMXTemplate
|
|||
}
|
||||
|
||||
// For a hash, returns an array with pairs { key => 'key', value => 'value' }
|
||||
static function exec_pairs($array, $kf = 'key', $vf = 'value')
|
||||
static function exec_pairs($array)
|
||||
{
|
||||
$r = array();
|
||||
foreach ($array as $k => $v)
|
||||
$r[] = array($kf => $k, $vf => $v);
|
||||
$r[] = array('key' => $k, 'value' => $v);
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
@ -832,18 +784,22 @@ class VMXTemplateOptions
|
|||
$this->$k = $v;
|
||||
}
|
||||
}
|
||||
if ($this->strip_space && array_search('strip_space', $this->filters) === false)
|
||||
{
|
||||
$this->filters[] = 'strip_space';
|
||||
}
|
||||
if (!$this->begin_subst || !$this->end_subst)
|
||||
{
|
||||
$this->begin_subst = false;
|
||||
$this->end_subst = false;
|
||||
$this->no_code_subst = false;
|
||||
}
|
||||
$this->cache_dir = preg_replace('!([^/])/*$!s', '\1/', $this->cache_dir);
|
||||
$this->cache_dir = preg_replace('!/*$!s', '/', $this->cache_dir);
|
||||
if (!is_writable($this->cache_dir))
|
||||
{
|
||||
throw new VMXTemplateException('VMXTemplate: cache_dir='.$this->cache_dir.' is not writable');
|
||||
}
|
||||
$this->root = preg_replace('!([^/])/*$!s', '\1/', $this->root);
|
||||
$this->root = preg_replace('!/*$!s', '/', $this->root);
|
||||
}
|
||||
|
||||
function __destruct()
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
require 'template.php';
|
||||
|
||||
system('mkdir -p ./cache');
|
||||
system('rm ./cache/tpl*.php');
|
||||
|
||||
$template = new VMXTemplate([
|
||||
'cache_dir' => './cache',
|
||||
'root' => '.',
|
||||
'auto_escape' => 's',
|
||||
]);
|
||||
|
||||
$template->parse('test.tpl');
|
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div>x{intro}y</div>
|
||||
<select>
|
||||
<!-- FOR o = options -->
|
||||
<option value="{o.url}"<!-- IF o.selected --> selected="selected"<!-- END -->>{o.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<span>{v.end('x', 'y')['z'].begin()}</span>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue