redcatphp / templix
Templix - 基于HTML5的模板引擎,具有递归扩展和CSS3选择器,可在DOM上像使用Jquery一样工作
Requires
- php: >=5.4.0
README
不再积极维护。我现在使用NodeJS,并建议您查看 ReactJS、Next.JS 和 EJS
Templix
Templix 是一个基于标记语法的强大模板引擎。
特性
- 递归扩展
- CSS3 选择器 (jQuery/sizzle 风格) 用于编译时在DOM上工作
- 兼容PHP
- onCompile 绑定器
- 支持PHP短开放标签语法,即使php.ini中未启用
- 将PHP语法元素移植到HTML5
- HTML5/XML语法
- 扩展的Templix语法
- 编译时与简单的include一样快
- 可以构建自己的基于标记的逻辑语言
- 标记对象方法- closest
- searchNode
- match
- find
- children
- merge
- premerge
- submerge
- isSameNode
- getAttributes
- hasAttribute
- getElementsByTagName
- write
- append
- prepend
- each
- replaceWith
- remove
- applyFile
- before
- after
- getIndex
- getInnerMarkups
- getInner
- __toString
- clear
- clearInner
- head
- foot
- innerHead
- innerFoot
- attr
- tmpAttr
- removeAttr
- remapAttr
- data
- css
- removeClass
- addClass
- wrap
- unwrap
- createChild
- recursive
- arecursive
- getIterator 魔法
- offsetGet 魔法
- offsetSet 魔法
- offsetUnset 魔法
- offsetExists 魔法
- __get 魔法
- __set 魔法
- __isset 魔法
- __unset 魔法
- __invoke 魔法
- 属性插件- vars
- cacheSync
- cacheStatic
- 标记插件- after
- append
- apply
- attr
- attrappend
- attrprepend
- before
- case
- code
- css
- else
- elseif
- end
- eval
- extend
- for
- foreach
- if
- img
- include
- incorpore
- js
- link
- merge
- premerge
- submerge
- noparse
- pre
- prepend
- remove
- replace
- return
- script
- switch
- t
- var
- vars
- write
Templix 语法
Templix 语法基于双引号符号 < > 和 < >,因此如果您想将其用于打开或关闭标记声明以外的其他目的,您必须使用它们的 HTML 实体等效符号,即 > 和 <。
Templix 语法基于 PHP 和 HTML5/XML,但与 HTML5 类似,Templix 在 XML 中添加了快捷属性,在 HTML5 中添加了快捷值。
<markup "my shortcut value" />
注释之间的标记将不会解析,除了 PHP。
onCompile 绑定器
您可以将一些回调绑定到 Templix,以便在文档几乎编译完成且其所有 DOM 都可访问时触发。
$templix->onCompile(function($templix){ $templix->find('footer a')->addClass('footer-link'); });
选项
开发
// re-compile each time // add indentation and line feed for code readability $templix->setDevTemplate(true); //default true // add time suffix parameter to local css links to avoid browser caching $templix->setDevCss(true); //default true // add time suffix parameter to local js scripts avoid browser caching $templix->setDevJs(true); //default true // add time suffix parameter to local images to avoid browser caching $templix->setDevImg(true); //default false // add clean callback when switch from prod to dev $templix->setCleanCallback(function(){ });
路径
//set compile directory $templix->setDirCompile('.tmp/templix/compile/'); //by default //set cache directory $templix->setDirCache('.tmp/templix/cache/'); //by default //add mtime directory registry to use when you use "cacheSync" attribute $templix->setDirSync('.tmp/sync/'); //by default //set current working directories in order you want templix look for $templix->setDirCwd(['template/','redcat/template/']); //by default //add directories to stack of current working directories $templix->addDirCwd(['template/','redcat/template/',]); //the template file to display on call of $templix->display(); $templix->setPath($file);
插件路径
插件路径基于类命名空间,最终,自动加载。每个类插件名称以标记的第一个字符的大写字母结尾,并以前缀开头,前缀可以是命名空间(以 \\ 结尾)或简单前缀。
$prefixDefault = Templix::getPluginPrefixDefault(); // Templix\\MarkupX\\ , Templix\\MarkupHtml5\\ , Templix\\ $templix->setPluginPrefix($prefixDefault); //by default $templix->addPluginPrefix($prefix,$prepend=true); //equivalent to prependPluginPrefix $templix->appendPluginPrefix($prefix); $templix->prependPluginPrefix($prefix);
路径相对性
以下规则在您直接使用 PHP API display 或 setPath 时有效,就像您使用标记 include、extend、incorpore 或属性 applyFile 一样。
无前缀 - 在每个模板的工作目录以及每个父模板中查找
<include "my-template.tml">
"./" 前缀 - 在当前模板的同一目录中优先查找
<include "./my-template.tml">
"/" 前缀 - 在定义的工作目录根目录中优先查找
<include "/my-template.tml">
"//" 前缀 - 在绝对路径中优先查找
<include "//var/www/my-project.dev/templates/my-template.tml">
HTML5 插件
XHTML
HTML5 与 XML/XHTML 语法的主要区别在于,在 XML 语法中我们必须关闭每个元素,它支持自闭合,但与 HTML5 不同,没有隐式自闭合。在 XML 中没有对快捷属性的支持,所有属性都必须由键和值组成。在 XML 中,我们还需要将所有 HTML 命名实体转换为它们的数字实体等效。文档类型也不同,但除了这些少数差异外,我们可以非常简单地从一个切换到另一个。
在 Templix 中,如果您将 html5 doctype 声明 "" 更改为 "",输出语法将自动更改为 XHTML,而无需对您的模板进行任何更改!
解析器支持的语法比 HTML5 更灵活,具有一些 Templix 插件特定性,例如快捷值,但通过将 DOM 转换为 PHP 对象,输出可以很容易地更改为 XML。根据 W3C 规范,以下元素是隐式自闭合的
- area
- base
- br
- col
- command
- embed
- hr
- img
- input
- keygen
- link
- meta
- param
- script
- source
- style
- track
- wbr
您可以通过查看 "RedCat\Templix\MarkupHtml5" 命名空间在 "redcat/php/RedCat/Templix/MarkupHtml5" 目录中了解自闭合实现的方式。
标记对象方法
在以下文档中,标记对象将被称为节点。
closest
使用最近的方法通过节点的祖先节点找到第一个匹配的元素,这些元素与当前节点最近。
$node->closest('form'); //will find the enclosing form if there is one
searchNode
searchNode 方法用于在节点的子节点中找到节点的索引(如果存在)。第二个参数可用于从索引开始搜索。
$index = $node->searchNode($searchingNode); $index = $node->searchNode($searchingNode,2);
match
match 方法用于确定节点是否对应于选择器。
$node->match('#node-id'); $node->match('a.my-class'); $node->match('a[href="templix"]');
find
find 方法用于在所有封装的节点中找到匹配的选择器。第二个参数可用于指定结果的索引。
如果您指定索引为 "true",则结果将不是节点数组,而是一个节点迭代器对象,您可以用作数组进行遍历和 foreach,但也可以像常规节点一样调用子方法。
foreach($node->find('img') as $img){ if(!$img->alt) $img->alt = basename($img->src); } $node->find('a',0); //will get the first node of results $node->find('a',1); //will get the second node of results $allA = $node->find('ul>li',true)->find('a'); $node->find('ul>li',true)->remove();
children
children 方法用于在节点的第一子级中找到匹配的选择器。与 find 方法类似,第二个参数可用于指定结果的索引。
如果您指定索引为 "true",则结果将不是节点数组,而是一个节点迭代器对象,您可以用作数组进行遍历和 foreach,但也可以像常规节点一样调用子方法。
foreach($node->children('img') as $img){ if(!$img->alt) $img->alt = basename($img->src); } $node->children('a',0); //will get the first node of 'a' children $node->children('a',1); //will get the second node of 'a' children $childrenA = $node->children('ul>li',true)->children('a'); $node->children('ul>li',true)->remove();
merge
merge 方法将方法传递的节点参数与节点的子节点合并。
如果已存在等效节点,则不会添加节点以避免重复。如果参数是标量值,则将其转换为节点树。
如果元素尚未存在,则将其添加到现有元素之后。
$node->merge($otherNode); $node->merge('</li>unique element</li>');
premerge
premerge 方法将方法传递的节点参数与节点的子节点合并。
如果已存在等效节点,则不会添加节点以避免重复。如果参数是标量值,则将其转换为节点树。
与 merge 不同的是,如果元素尚未存在,它将被添加到现有元素之前而不是之后。
$node->premerge($otherNode); $node->premerge('</li>unique element</li>');
submerge
submerge 方法将参数节点的子节点与节点的子节点合并。
与 merge 类似,如果已存在等效节点,则不会添加节点以避免重复。如果参数是标量值,则将其转换为节点树。
$node->submerge($otherNode); $node->submerge('<ul></li>unique element</li></ul>');
isSameNode
isSameNode 方法将节点与基于子节点、属性和类名的节点参数进行比较,并返回布尔值。它是一个等价比较,而不是基于对象内存引用的严格比较。
var\_dump( $node===$node ); //true var\_dump( $node->isSameNode($node) ); //true var\_dump( $node===$otherNode ); //false var\_dump( $node->isSameNode($otherNode) ); //true
getAttributes
getAttributes 方法允许您以关联数组的形式获取属性。
$attributes = $node->getAttributes();
hasAttribute
hasAttribute 方法允许您知道是否定义了属性。
if($node->hasAttribute('title')){ }
getElementsByTagName
getElementsByTagName 方法类似于常规的 JavaScript 方法,它从调用节点本身开始递归地根据标签名获取元素。
$divs = $node->getElementsByTagName('div');
write
写入方法将在附加参数之前清除内部头部、内部尾部和子节点。头部和尾部将被保留。如果参数是标量值,它将被转换为节点树。
$node->write($nodes); $node->write('<span>New inner content</span>'); $node->write('New inner content');
append
append方法将参数添加到现有子节点之后。如果参数是标量值,它将被转换为节点树。
$node->append($nodes); $node->append('<span>New appending content</span>'); $node->append('New appending content');
prepend
prepend方法将参数添加到现有子节点之前。如果参数是标量值,它将被转换为节点树。
$node->prepend($nodes); $node->prepend('<span>New prepending content</span>'); $node->prepend('New prepending content');
each
each方法接收一个回调函数作为参数。它将对节点或迭代器节点进行操作,并对每个节点应用该回调。
$node->find('a',true)->each(function($a){ echo $a->href."<br>"; });
replaceWith
replaceWith方法允许您用另一个节点替换父节点中的节点。如果参数是标量值,它将被转换为节点树。
$node->replaceWith($otherNode); $node->replaceWith('<div>replaced</div>');
remove
remove方法将从父节点的子节点中删除节点。
$node->remove();
applyFile
applyFile方法将读取文件名,通常是一个".tpl"文件,其中包含修改节点的标记符,类似于extend中的第一级标记符。
$node->applyFile($filename);
before
before方法将在父节点的子节点中在节点之前添加参数。如果参数是标量值,它将被转换为节点树。
$node->before($nodes); $node->before('<span>Before content</span>'); $node->before('Before content');
after
after方法将在父节点的子节点中在节点之后添加参数。如果参数是标量值,它将被转换为节点树。
$node->after($nodes); $node->after('<span>After content</span>'); $node->after('After content');
getIndex
getIndex方法返回节点在父节点子节点中的索引。
$index = $node->getIndex();
getInnerMarkups
getInnerMarkups方法返回内部子节点的字符串版本。
$string = $node->getInnerMarkups();
getInner
getInner方法返回内部头部、内部子节点和内部尾部的字符串版本。
$string = $node->getInner();
__toString
__toString方法返回整个节点及其所有封装节点的字符串。当尝试将节点转换为字符串时,将返回此魔术方法。
$string = $node->\_\_toString(); $string = (string)$node; $string = $node.'';
clear
clear方法删除头部、内部头部、子节点、内部尾部、尾部、前一个兄弟、后一个兄弟,将其从下一个和前一个流中分离,并将hiddenWrap设置为隐藏标记开闭输出。
$node->clear();
clearInner
clearInner方法删除内部头部、子节点和内部尾部。
$node->clearInner();
head
head方法将原始内容或源代码添加到节点的头部,在打开标记之前。可以使用第二个参数指定一个插入索引。如果插入索引为true,则将原始内容推入而不是移至开头。
$node->head('<?php echo time();?>'); $node->head($raw,2); $node->head($raw,true);
foot
脚方法将原始内容或源代码推送到节点底部,在关闭标记之后。可以使用第二个参数来指定插入索引。如果插入索引为真,则原始内容将使用 unshift 而不是 push。
$node->head('<?php echo time();?>'); $node->head($raw,2); $node->head($raw,true);
innerHead
innerHead 方法在节点内部头部插入原始内容或源代码,在打开标记之后。可以使用第二个参数来指定插入索引。如果插入索引为真,则原始内容将使用 push 而不是 unshift。
$node->innerHead('<?php echo time();?>'); $node->innerHead($raw,2); $node->innerHead($raw,true);
innerFoot
innerFoot 方法将原始内容或源代码推送到节点内部底部,在关闭标记之前。可以使用第二个参数来指定插入索引。如果插入索引为真,则原始内容将使用 unshift 而不是 push。
$node->innerFoot('<?php echo time();?>'); $node->innerFoot($raw,2); $node->innerFoot($raw,true);
attr
attr 方法是用于访问属性的 getter 或 setter。它将是一个带有单个参数的 getter 和带有两个参数的 setter。
$node->attr('src','images/logo.png'); $src = $node->attr('src');
tmpAttr
attr 方法是用于访问临时属性的 getter 或 setter。
由于扩展或应用,DOM 可以重新编译为字符串并重新解析。在这个过程中,你可以添加到对象中的所有不可见元数据,比如使用 data 方法,都将被清除。因此,有一种约定,使用带有 "tmp-attr" 属性的 urlencoded 键值对来传递节点中的元数据。这个属性是一个可见属性,它与不是 "hiddenWrap" 节点(可见的打开和关闭标记)一起工作,但它们将在全局编译结束前自动删除。
它将是一个带有单个参数的 getter 和带有两个参数的 setter。
$node->tmpAttr('meta-data',$data); $meta = $node->tmpAttr('meta-data');
removeAttr
removeAttr 方法从节点打开标记中移除属性。
$node->removeAttr('class');
remapAttr
remapAttr 方法用于根据属性中的顺序添加键到快捷属性或快捷值。第一个参数指定要添加的键,第二个参数指定快捷的索引,从零开始。默认索引为零。
class Mynode extend \\RedCat\\Templix\\Markup{ function load(){ $this->remapAttr('src'); $this->remapAttr('async',1); $src = $this->src; $async = $this->async; ) }
data
data 方法是用于访问不可见属性的元数据的 getter 或 setter。
由于扩展或应用,DOM 可以重新编译为字符串并重新解析。在这个过程中,你可以添加到对象中的所有不可见元数据,比如使用 data 方法,都将被清除。为了解决这个问题,请使用 tmpAttr 而不是 data。
它将是一个带有单个参数的 getter 和带有两个参数的 setter。
$node->data('meta-data',$data); $meta = $node->data('meta-data');
css
css 方法是用于访问样式属性 CSS 属性的 getter 或 setter。它将是一个带有单个参数的 getter 和带有两个参数的 setter。
$height = $node->css('height'); if(substr($height,-2)=='px') $height = substr($height,0,-2); $node->css('height',($height+120).'px');
removeClass
removeClass 方法允许你通过以常规方式移除类来在类属性上工作,而无需直接在类字符串属性上工作。
$node->removeClass('my-class');
addClass
addClass 方法允许你通过以常规方式添加类来在类属性上工作,而无需直接在类字符串属性上工作,并避免重复。
$node->addClass('my-class');
wrap
包装方法允许您将节点或节点树包装在一个节点中。如果您传递给它一个节点树,它将使用第一个顶级封装节点作为包装器。如果参数是标量值,它将被转换为节点树。
$node->wrap($wrapperNode); $node->wrap('<div class="my-wrapper" />');
unwrap
unwrap方法允许您移除包装器。您还可以使用选择器指定要从祖先中移除的最接近的匹配包装器。默认情况下,它将是最近的封装器(选择器"*")。
$node->unwrap(); $node->unwrap('div.my-wrapper');
createChild
createChild方法将从标量内容创建一个节点在子节点中。
$div = $node->createChild('<div />');
recursive
recursive方法允许您递归地对每个节点执行回调,并从回调上下文中断递归。回调将从深层元素执行到顶层。
$node->recurse(function($subnode,&$break){ if($subnode->attr('data-find')){ $break = true; //break the recursion } });
arecursive
recursive方法允许您递归地对每个节点执行回调,并从回调上下文中断递归。与recursive相反,回调将从顶层元素执行到底层。
$node->arecurse(function($subnode,&$break){ if($subnode->attr('data-find')){ $break = true; //break the recursion } });
getIterator魔法
getIterator魔法方法允许您像处理节点数组一样处理子节点,并用foreach循环遍历它们。
foreach($node as $childNode){ }
offsetSet魔法
offsetSet魔法方法允许您像处理节点数组一样处理子节点,并像偏移量一样设置子节点。如果参数是标量值,它将被转换为节点树。
$node[] = $appendNode; $node[] = '<a href="http://redcatphp.com">RedCat Framework</a>'; $node[5] = $indexedNode;
这相当于
$node->append($appendNode); $node->append('<a href="http://redcatphp.com">RedCat Framework</a>'); $node->append($indexedNode,5);
offsetGet魔法
offsetGet魔法方法允许您像处理节点数组一样处理子节点,并像偏移量一样获取子节点。
$childNode4 = $node[4];
这相当于
$childNode4 = $node->children('\*',4);
offsetExists魔法
offsetGet魔法方法允许您检查子节点是否存在。
if(isset($node[0])){ }
这相当于
if(!is\_null($node->children('\*',0))){ }
offsetUnset魔法
offsetGet魔法方法允许您移除子节点。
unset($node[1]);
这相当于
$node[1]->remove();
__get魔法
__get魔法方法允许您直接获取属性。
$src = $node->src;
这相当于
$src = $node->attr('src');
set魔法
__set魔法方法允许您直接设置属性。
$node->src = $src;
这相当于
$node->attr('src',$src);
__isset魔法
__isset魔法方法允许您直接检查节点是否有属性。
if(isset($node->src)){ }
这相当于
if($node->hasAttribute('src')){ }
__unset魔法
__unset魔法方法允许您直接删除属性。
unset($node->src);
这相当于
$node->removeAttr('src');
__invoke魔法
__invoke魔法方法允许您直接与集合迭代器一起工作。
$node('ul>li>a')->addClass('my-class');
这相当于
$node->find('ul>li>a',true)->addClass('my-class');
原生插件
属性插件
某些属性会触发特殊行为,注入后变为不可见。将属性触发函数实现到标记的方法是将一个方法命名为带有load前缀,后跟属性名的首字母大写。属性名中的破折号"-"在方法名中将被下划线"_"替换。如果您想捕获所有以名称后跟破折号"-"开头的属性,例如"data-",则可以实现以下划线"_"结尾的"loadAttr"方法。以下是一些示例
<mymarkup src="path.ext" data-meta="Some metadata" data-other="Other metadata" />
class Mymarkup{ function loadSrc($v){ var\_dump( $v ); //will output 'path.ext' } function loadData\_meta($v){ var\_dump( $v ); //will output 'Some metadata' } function loadData\_($v,$k){ var\_dump( $v ); //will output 'Some metadata' and 'Other metadata' var\_dump( $k ); //will output 'meta' and 'other' } }
通用属性插件
vars
vars属性用于使用sprintf插值函数包装内部内容。
<?$name = 'Jo';?> <?$lastname = 'Surikat';?> <span vars="'Jo','Surikat'">Hi %s !</span> <span vars="$name,$lastname">Hi %s %s !</span>
cacheSync
cacheSync属性与同步路径一起使用。如果其修改时间早于同步路径的修改时间,则将缓存并重新生成标记内容。
<ul cacheSync="tracks"> <foreach "$model->getTracks() as $k=>$v"> <li><?=$k?>:<?=$v?></li> </foreach> </ul>
更新缓存
touch('.tmp/sync/tracks.sync');
配置同步文件的路径
$templix->setDirSync('.tmp/sync/'); //by default
cacheStatic
cacheStatic属性用作缓存标记内容的快捷属性,使其无限期缓存。
<ul cacheStatic> <foreach "$model->getTracks() as $k=>$v"> <li><?=$k?>:<?=$v?></li> </foreach> </ul>
标记插件
after
after方法的标记用法。after标记必须在".tpl"内或其内部的第一层使用,并使用apply。它将在其目标节点之后添加其内容。
<extend> <after main> <img src="img/signature.png"> </after> <after "main>article:nth-child(2)"> <article>Bla bla bla ...</article> </after> </extend>
append
append方法的标记用法。append标记必须在".tpl"内或其内部的第一层使用,并使用apply。它将在其目标节点的末尾添加其内容。
<extend> <append main> <img src="img/signature.png"> </append> <append "body>main"> <article>Bla bla bla ...</article> </append> </extend>
apply
applyFile方法的标记用法。这是:的逆过程,.tpl文件将能够使用选择器标记来对.的内容进行操作。.tpl文件就像一种应用程序修补程序函数。
<apply "form-validation.tpl"> <form> <!-- ... --> </form> </apply>
apply的特殊语法{{this:property}}允许您以更灵活和动态的方式访问当前目标节点的属性来构建apply。Tpl文件
<write selector="textarea[name]"> <?=isset($\_POST['{{this:name}}'])?$\_POST['{{this:name}}']:'{{this:value}}'?> </write>
apply的特殊语法{{compile:callback()}}允许您使用当前目标节点的属性预先编译一些代码片段,以构建更快速、更一致的编译模板。Tpl文件
<after selector="input[name][type!=checkbox][type!=hidden], select[name], textarea[name]"> <? if(isset($formErrors)&&isset($formErrors["{{compile: rtrim(str\_replace(array('[',']'),array('.',''),'{{this:name}}'),'.') }}"])){ ?><small class="help-block"><?=$formErrors["{{compile: rtrim(str\_replace(array('[',']'),array('.',''),'{{this:name}}'),'.') }}"]?></small><? } ?> </after>
attr
attr方法的标记用法。attr标记必须在".tpl"内或其内部的第一层使用,并使用apply。它将设置其目标节点(s)的属性为其属性,并可以使用一些以add或remove开头(例如addClass或removeClass)的特殊行为。
<extend> <attr selector="main > article:eq(0) > img:eq(2)" alt="Name for my image"> <attr "img.my-logo" alt="My Logo" src="img/logo.png"> <attr main addClass="about"> </extend>
attrappend
attrappend标记必须在".tpl"内或其内部的第一层使用,并使用apply。它将向其目标节点(s)的属性追加其属性。
<extend> <attrappend "img.my-logo" alt=" - Me"> </extend>
attrprepend
attrprepend 标记必须用于 ".tpl" 文件内部或第一层,并使用 apply。它将把属性预加到目标节点上。
<extend> <attrprepend "img.my-logo" alt="Me -"> </extend>
before
before 方法的标记必须用于 ".tpl" 文件内部或第一层,并使用 apply。它将在目标节点之前添加内容。
<extend> <before main> <img src="img/signature.png"> </before> <before "main>article:nth-child(2)"> <article>Bla bla bla ...</article> </before> </extend>
case
case 是一个基本的 PHP 语法结构元素。
<switch "$switcher"> <case hello> Hello </case> <case "bye" /> Bye <break> </switch>
code
code 标记允许您放入未解析的代码,如 <script> 、 <style> 或 . 它的内容将被转换为 HTML 实体。以下内容将按此方式显示,而不会被解释。
<code class="lang-xml"> <switch "$switcher"> <case hello> Hello </case> <case "bye" /> Bye <break> </switch> </code>
css
css 标记可以在文档的任何位置使用,甚至在第一层,用于向文档的 head 添加样式表链接。如果已经存在具有相同 href 的链接元素,则不会重复。如果 href 是绝对路径或以斜杠 "/" 开头,则默认不会添加前缀路径 "css/"。如果 URL 不是绝对路径且不以 ".css" 扩展名结尾,则将自动添加扩展名。
<css style> <css "/path/to/my/stylesheet.css">
else
elseif 是一个基本的 PHP 语法结构元素。
<if "$cond"> <else> </if> <if "$cond" /> <else> <end>
elseif
elseif 是一个基本的 PHP 语法结构元素。
<if "$cond"> <elseif "$cond"> </if> <if "$cond" /> <elseif "$cond"> <end>
end
end 是一个基本的 PHP 语法结构元素,对应于 "}"。
<if "$cond" /> <end> <switch "$switcher" /> <end> <foreach "$var as $v" /> <end>
eval
eval 标记可用于独立于文档其余部分执行 PHP,以便 Temlix 在之后解析输出。
$templix['outsideVar'] = true;
<?$insideVar = true;?> <eval> <? //$outsideVar is defined here //$insideVar is not defined here echo '<img src="img/logo.png">'; ?> </eval>
如果找到图像,解析器将添加高度和宽度(请参阅 img 标记)。
extend
extend 标记将引用包装模板,通常在第一层是布局。
同一个模板中可以有多个 extend,并且您可以递归地扩展已扩展的模板文件。
默认情况下,它将文件名后缀为 ".xtml",如果为空,则默认包装文件为 ".xtml"。它将包含其他特定元素,这些元素将在 DOM 上工作:如 write、append、prepend、after、before、remove、replace、merge、premerge、submerge、attr、attrprepend、attrappend、css、js。
<extend> <main> <h1>Hi</h1> </main> </extend>
<extend "header.xtml"> <append "title"> - RedCat</append> </extend> <extend "footer.xtml"> <prepend "footer">RedCat -</prepend> </extend>
第一级标记将按顺序应用。以下示例中,
内容 "Hi" 将被 "Hello" 覆盖
<extend> <main> <h1>Hi</h1> </main> <write "main>h1:eq(0)"> Hello </write> </extend>
如果第一级的标记不是计划在DOM上工作的预期标记,它将被转换为标记,并且其名称和属性将转换为选择器。让我们举一个例子,这个
<extend> <article id="something" class="interesting"> <h2>Something interesting</h2> </article> </extend>
等同于这个
<extend> <write "article[class='interesting'][id='something']"> <h2>Something interesting</h2> </write> </extend>
for
for 是一个基本的 PHP 语法结构元素。
<for "$i=0;$i<10;$++"> </for> <for i="10"> </for> <for from="0" to="10"> </for>
foreach
foreach 是一个基本的 PHP 语法结构元素。
<foreach "$var as $k=>$v"> <?php echo $k;?>:<?php echo $v;?></foreach> <foreach "$var" key="k" val="v"> <?php echo $k;?>:<?php echo $v;?></foreach>
if
if 是一个基本的 PHP 语法结构元素。
<if "$cond"> </if> <if "$cond" /> <end>
img
如果 src 是本地资源,height 或 width 未定义且文件可找到,则会自动提取 height 和 width 属性以提高浏览器渲染性能。
如果 devImg 选项设置为 true,它将为文件名添加时间后缀以避免浏览器缓存机制。
include
include 标记将以一种方式编译子模板,使其可以通过调用者编译的模板中的常规 include 包含。无法从调用者 DOM 修改包含的模板 DOM,但包含的模板可以访问调用者 DOM 并对其进行操作。
<incude "path/to/my/included-template.tml">
incorpore
incorpore 标记将完全将子模板合并到当前模板工作流程中。可以从调用者 DOM 修改合并的模板 DOM,并且合并的模板也可以访问并修改调用者 DOM。
<incude "path/to/my/incorpored-template.tml">
js
js 标记可以在文档的任何地方使用,甚至在第一级中,以将 $js 脚本调用添加到 body 的最后一个脚本。如果 $js 调用已经存在,并且具有相同的 src URL,则不会重复。
<js script> <js "/path/to/my/script.js">
link
常规 HTML5 标记。如果 Templix devCss 选项设置为 true,它将为 href 添加时间后缀以避免浏览器缓存机制
merge
merge 标记的使用与 merge 方法。merge 标记必须在第一级或 ".tpl" 中的 apply 内部使用。它将合并其节点与其选择器目标节点(的)子节点。如果已经存在等效节点,则不会添加节点以避免重复。
<extend> <merge "body>main"> <article>Bla bla bla ...</article> </merge> </extend>
noparse
解析器不会解析其内部除了纯PHP代码之外的标记。解析器将一直关闭,直到遇到结束标记 <script>。样式和脚本标记也有相同的实现。
class Noparse extends \\RedCat\\Templix\\Markup{
protected $hiddenWrap = true;
protected $noParseContent = true;
}
pre
pre 标记允许您放置未解析的代码,就像在 <script>、<style> 或 . 中一样。其内容将被转换为HTML实体。
premerge
premerge 方法的标记使用。必须在 ".tpl" 中的一级内部或使用 apply 的 ".tpl" 中使用 premerge 标记。它将与其选择器目标节点(s)的子节点合并其节点。如果已存在等效节点,则不会添加节点以避免重复。与合并相反,如果元素尚未存在,则会在现有元素之前添加,而不是之后。
<extend> <premerge "body>main"> <article>Bla bla bla ...</article> </premerge> </extend> </p> <h4 id="plugin-prepend">prepend</h4> <p> Markup usage of <a href="templix#method-prepend">prepend method</a>. The prepend markup have to be used at first level inside <extend> or in "*.tpl*" with apply. It will add its content at top inside its selector targeted node(s). <code class="lang-xml"> <extend> <prepend main> <img src="img/signature.png"> </prepend> <prepend "body>main"> <article>Bla bla bla ...</article> </prepend> </extend>
remove
remove 方法的标记使用。必须在 ".tpl" 中的一级内部或使用 apply 的 ".tpl" 中使用 remove 标记。它将删除其选择器目标节点(s)。
<extend> <remove "span.some-widget"> </extend>
replace
replace 标记将替换其选择器目标节点(s)的内容。
<extend> <replace "body>main>article:eq(0)"> <article>Bla bla bla ...</article> </replace> </extend>
return
return 是一个基本的 PHP 语法结构元素。
<return "$result">
script
常规HTML5 <script> 标记,如果没有定义,则具有隐式 type="text/javascript"。如果它有 src 属性并且 Templix devJs 选项设置为 true,则会在其 src 上添加时间后缀以避免浏览器缓存机制。
submerge
submerge 方法的标记使用。必须在 ".tpl" 中的一级内部或使用 apply 的 ".tpl" 中使用 submerge 标记。它将与其选择器目标节点(s)的子节点合并其子节点。与合并一样,如果已存在等效节点,则不会添加节点以避免重复。
<extend> <submerge "body>main"> <article>Bla bla bla ...</article> <article>And Bla bla bla ...</article> </submerge> </extend>
switch
switch 是一个基本的 PHP 语法结构元素。
<switch "$switcher"> <case hello> Hello </case> <case "bye" /> Bye <break> </switch> <switch "$switcher" /> <end>
t
t 标记可以像 vars 属性一样使用,是透明的,可以用于与 gettext 翻译和 sprintf 一起工作。
<?$name = 'Jo';?> <?$lastname = 'Surikat';?> <t "'Jo','Surikat'">Hi %s %s !</t> <t "$name,$lastname">Hi %s %s !</t>
var
var 标记可以用于将原始内容分配给变量。变量可以每次重新生成,也可以使用静态属性作为快捷属性进行缓存。
<var compilation static> <span>Timestamp at compilation: <?=time()?>.</span> </var> <var execution> <span>Timestamp execution: <?=time()?>.</span> </var> <?=$compilation?> <?=$execution?>
vars
vars 标记将在模板包含路径(s)中查找 "vars.$name.php" 文件。该文件将作为动态内容包含,但它的变量也可以通过添加快捷属性 "static" 作为静态内容包含。
<vars basic /> <vars "my-static-vars" static />
write
标记使用方法 write 方法。write 标记必须在 ".tpl" 文件的第一级内部或外部使用,并应用它。它将内容写入目标节点内部,并覆盖其内部内容。
<extend> <write main> <article>Bla bla bla ...</article> </write> </extend>
自定义插件
构建您自己的插件
要构建您自己的插件,您必须设置插件前缀类路径,然后创建相应的带前缀的类。
您必须从 "\RedCat\Templix\Markup" 类扩展此类。以下是一个示例
$templix->addPluginPrefix('RedCat\\Plugin\\Templix\\Markup\\');
<markdown> # [See Away, Be Lite, Run Fast](http://redcatphp.com)  [REDCAT](http://redcatphp.com) [The essential framework for web developers](http://redcatphp.com) </markdown>
从 RedCat\Plugin\Templix\Markup\Markdown.php
namespace RedCat\\Plugin\\Templix\\Markup; class Markdown extends \\RedCat\\Templix\\Markup { protected $hiddenWrap = true; protected $noParseContent = true; function load(){ $this->remapAttr('file'); if($this->file) $text = file\_get\_contents($this->file); else{ $text = $this->getInnerMarkups(); $x = explode("\\n",$text); foreach($x as &$v) $v = ltrim($v); $text = implode("\\n",$x); } $this->clearInner(); $md = new Parsedown(); $this->innerHead[] = $md->text($text); } }
插件类名
类名对应于前缀加上标记名称首字母大写。如果标记名称包含特殊字符,则将它们替换为下划线 "_" 以供类查找。
<my-markup></my-markup>
namespace RedCat\\Plugin\\Templix\\Markup; //here is the namespace prefix class My\_markup extends \\RedCat\\Templix\\Markup {}
插件方法
类的 load 方法在您的标记关闭时触发,通过关闭标记、自闭合或隐式自闭合。所有在加载之前加载的 DOM 都可访问。
您还可以实现加载方法,该方法在整个文档加载时触发,并可以从该方法中访问。
从该类中,您可以使用 标记对象方法 访问标记的属性和所有 DOM。
class Mymarkup extends \\RedCat\\Templix\\Markup { function load(){ var\_dump( $this->getAttributes() ); } function loaded(){ var\_dump( $this->closest('div')->getAttributes() ); } }
插件的特殊属性
有一些标记类的特殊属性可以重载以添加特殊行为。
hiddenWrap 属性,当设置为 true 时,告诉 templix 此标记的开头标签、结尾标签及其属性都没有输出。只有其头部、尾部和内部内容将被显示。此实现的示例有 t、noparse、vars 以及所有基本的 php 语法结构元素 或标记,这些标记在加载时将重写其内容。
noParseContent 告诉解析器不要解析其内部的标记(除了纯 PHP 代码)。解析器将关闭,直到遇到与已打开的 noParseContent 标记对应的结束标记,例如 . 此实现的示例有 noparse、script、style、code 和 pre。
class Mymarkup extends \\RedCat\\Templix\\Markup { protected $hiddenWrap = true; protected $noParseContent = true; }