页面模版
文章分页:
页面模版 - 1

框架模版系统采用二次编译模式,严格实现模板与程序的分离,通过通俗的标签模式调用各类数据。基本模板格式简单易学,方便制作,只要对HTML有一定了解就可以很快上手,模板修改后即时生效。同时具备高度可扩展性,可根据实际需要任意扩充模版标签。 

实例声明

模版类的实例创建代码如下:

$tpl = new myTemplate($tpl_setting, $tpl_cache, $allow_script, $delimiter);

参数一 $tpl_setting 为调用设置,为一个字符串下标的数组,包括以下参数:

  • name - 必选项,所调用的模版文件名;
  • path - 必选项,模版文件存放的路径;
  • style - 可选项,模版样式名,即模版目录下的子目录名,默认为空;
  • path_compile - 可选项,编译文件存放的路径,默认为模版目录下的 comipled 子目录;
  • ext - 可选项,模版文件的扩展名,默认为 tpl;

参数二 $tpl_cache 为缓存设置,也就是将生成的页面作为缓存保存至文件,如为 false 则表示不使用缓存,否则为一个字符串下标的数组,包括以下参数:

  • name - 缓存文件名,默认为模版文件名,在同一模版生成不同页面时(如文章内容页)设置;
  • path - 缓存路径,默认为模版目录下的 cache 子目录;
  • ext - 缓存文件的扩展名,默认为 html;
  • expire - 缓存过期时间,单位为秒,默认为 300。

参数三 $allow_script 为布尔值,表示是否允许在模版代码中加带 PHP 代码。

参数四 $delimiter 为间隔符,用于划分模版变量的标识符,框架默认的标识符设置为:左标识符 <!-- 和右标识符 --> ,即 ['<!--', '-->']。

 

模版语法

赋值语法

1、单变量赋值

模版语法:<!--name-->

赋值方式:$tpl->assign('name', 'value');

结果:对应的模版标签将被替换为 value

2、多变量赋值

模版语法:<!--name_1--><!--name_2--><!--name_3-->(相关标签可以在模版的任意位置)

赋值方式:

$tpl->assign([  
    'name_1'=>'value_1',      
    'name_2'=>'value_2',      
    'name_3'=>'value_3',   
]);

结果:将依次将对应数组下标的标签替换为对应的值。

3、多变量带前缀赋值

模版语法:<!--pre_name_1--><!--pre_name_2--><!--pre_name_3-->(相关标签可以在模版的任意位置)

赋值方式:

$tpl->assign('pre', [  
    'name_1'=>'value_1',      
    'name_2'=>'value_2',      
    'name_3'=>'value_3',   
]);

结果:将依次将数组下标添加前缀,并将前缀标签替换为对应的值。

4、多变量文件赋值

模版语法:同以上三种模式

赋值方式:$tpl->loadSet($file, $prefix, $mode)

    • $file - 变量文件,格式可以为 ini,php(返回字符串下标的数组) 或 json ,支持多级递归;
    • $prefix - 对应 assign 方法中,对变量前缀赋值模式中的前缀;
    • $mode - 递归数组标签命名方式,设定为 false 的话,则只取当前下标作为标签名,否则按照变量深度,依次将各级数组下标用“_”连接作为标签名。

结果:参考多变量赋值

循环语法

模版语法:

<ul>  
<!--loop:start key="info" time="5"-->  
    <li><a href="<!--info_url-->" title="<!--info_comment-->" target="_blank"><!--info_name--></a></li>  
<!--loop:end-->  
</ul>

模版循环标签通过 loop:startloop:end 标签将循环部分包起,标签内含有两个属性,key属性为必选项,相当于赋值前缀,目的是为了区分循环变量和普通变量;time属性为可选项,表示最低循环次数,也就是在赋值数量不足这个数字时,将再加上几个空的项目以达到规定数额(保证页面布局整齐)。

赋值方式:$tpl->setLoop($key, $data, $fullset)

    • $key 为索引值,对应模版中的 key 属性;
    • $data 为数据项,用于依次将数据循环赋值给模版;
    • $fullset 注明数据项是否为全套数据,默认为false。

一次性将所有数据提交:

$record = array(  
    ['url'=>'###', 'comment'=>'text1', 'name'=>'name1'],  
    ['url'=>'###', 'comment'=>'text2', 'name'=>'name2'],  
    ['url'=>'###', 'comment'=>'text3', 'name'=>'name3'],  
    ['url'=>'###', 'comment'=>'text4', 'name'=>'name4'],  
);  
$tpl->setLoop('info', $record, true);

通过循环按组提交:

$record = array(  
    ['url'=>'###', 'comment'=>'text', 'name'=>'name'],  
    ['url'=>'###', 'comment'=>'text', 'name'=>'name'],  
    ['url'=>'###', 'comment'=>'text', 'name'=>'name'],  
    ['url'=>'###', 'comment'=>'text', 'name'=>'name'],  
);  
while($data=next($record)) {  
    $tpl->setLoop('info', $data);  
}

上例通过循环依次将每一组变量赋值到循环标签中,本方法多用于数据结果集的依次读取并赋值。

判断语法

模版语法:(其中 else 部分不是必须的)

<!--if:start key='error'-->  
<p style="color:red;">No!!!!</p>  
<!--else-->  
<p style="color:green;">Yes</p>  
<!--if:end-->

赋值方式:$tpl->setIf($key, $value)

    • $key 为索引值,对应模版中的 key 属性;
    • $value 为布尔值,用于对标签做判断。
$tpl->setIf('error', $flag)

上例中,如果 flag 为 true ,则显示标签上半部分;否则显示下半部分,如无下半部分则不显示内容。

结构选择

模版语法:

<!--switch:start key='in_the_box'-->  
<!--(1)-->  
<p>It's an apple.</p>  
<!--(2)-->  
<p>It's a dog.</p>  
<!--(3)-->  
<p>Nothing here!</p>  
<!--switch:end-->

赋值方式:$tpl->setSwitch($key, $value)

    • $key 为索引值,对应模版中的 key 属性;
    • $value 为判断值,对比各子部分的索引值,如相同则显示其下面的内容。
$tpl->->setSwitch('in_the_box', rand(1, 3));
随机选择

模版语法:

<!--random:start-->  
<p>aaa</p>  
<!--(s)-->  
<p>bbb</p>  
<!--(s)-->  
<p>ccc</p>  
<!--random:end-->

本标签随机显示被  <!--(s)--> 间隔的项目之一,无属性,无赋值。

 

扩展标签

本模版系统可以通过扩展标签实现更多自如、复杂的组合。扩展标签也可称为块模版一般为单一功能(如循环、判断、选择或纯静态)但是会在页面反复用到的页面功能块,依照传入参数的不同,依照相同的机理显示不同的内容。例如不同栏目的新闻列表(循环),登陆模块(静态),用户信息显示(判断),页面功能(选择)等。

模版语法

格式:<!--tag name1='value1' name2='value2'-->

    • tag 为自定义的标签名称
    • name1、name2 为属性名称,可根据标签需要设定无限多个;
    • value1、value2 为属性值,既可以为具体的数字或字符串,也可以为变量名称,但需要注意的是此变量必须为全局变量,如 name1='$_GET["c"]' 或 name2="$var"。
    • 需要注意的是如果属性值为变量,则该变量需要在对应的解析脚本中做全局化声明,如上例中的name2的值为 $var,需要在解析脚本头部加上 global $var
解析方法

代码:$tpl->regTag($tag_name, $tag_func)

    • $tag_name 为标签名称,对应上文中的 tag;
    • $tag_func 为解析函数,可为任意有效的函数调用名称,或者闭包函数,此函数会被传入两个参数,参数一为当前模版实例,参数二为解析好的标签属性数组,如模版语法示例的标签对应属性的参数为:array('name1'=>'value1', 'name2'=>'value2'),此参数为址传递,可在解析函数中扩种内容,以供模版解析调用。
模版语法

与主模版语法类似,标签模版可通过标签属性传递相关参数,省去了主模版语法中的属性设置,且只包含 loop、if、switch 三种结构。

解析函数

由于涉及到了模版解析,需要用到模版类内部的两个方法:

    • $tpl->getTemplate($file) ,本方法将返回自定义标签所对应的块模版文件内容;
    • $tpl->getBlock($tpl_content, $tag, $idx),本方法将从自定义块模版文件中解析出所需的功能结构,各函数意义如下:
      • $tpl_content - 块模版文件内容;
      • $tag - 需要解析的功能结构名,即 loop、if、switch;
      • $idx - 仅作用于 loop 结构,相当于循环数据标识的前缀。
      本方法只支持一次解析一个功能结构,鉴于扩展标签的特性,块模版文件内建议只包含单一的逻辑结构,并且只出现一次,以便于功能更为纯粹,结构更为简洁。
      本方法将返回一个包含三个项目的数组,如下:
      • 0 - 整体功能结构的代码
      • 1 - 单元代码,loop结构返回需要循环的代码;if结构返回判断为 true ,即 else 前面的代码;switch结构返回以符合值为下标,值为对应代码的数组
      • 2 - 附加代码,loop结构返回不含模版标签的空行代码(即去掉单元代码所有模版变量标签后的部分);if结构返回判断为 false ,即 else 后面的代码;switch结构返回空字符串

下面将以一个实例来演示扩展标签的使用方法,首先我们先设置一个自定义标签:

<!--test name='$_get["n"]' author="myStep" time='Y-m-d' loop='5'-->

需要注意的是,有两个属性名称是不可使用的,分别是 unitunit_blank ,分别对应块模版功能结构中的结构内代码(即被定界符包起来的部分)和loop结构中的空行代码(即去掉unit代码中所有模版变量标签后的部分)。

对应的块模版文件:

<ul>  
    <li><!--name--> - <!--author--></li>  
<!--loop:start-->  
    <li style="<!--news_style-->">  
        <em><!--news_catalog--></em>  
        <a href="<!--news_link-->" title="<!--news_subject-->" target="_blank"><!--news_subject--></a> &nbsp;  
        <i><!--news_add_date--></i>  
    </li>  
<!--loop:end-->  
</ul>

解析代码如下:

$tpl->regTag('test', 'parseTest');  
function parseTest(myTemplate &$tpl, &$att_list = array()){  
    $tpl_content = $tpl->getTemplate('path/template/block_loop.tpl');  
    list($block, $att_list['unit'], $att_list['unit_blank'])= $tpl->getBlock($tpl_content, 'loop', 'news');  
    $result = <<<'mytpl'  
<?PHP  
$result = array(  
            ['style'=>'style', 'catalog'=>'catalog', 'link'=>'###', 'subject'=>'subject', 'add_date'=>'0'],  
            ['style'=>'style', 'catalog'=>'catalog', 'link'=>'###', 'subject'=>'subject', 'add_date'=>'0'],  
            ['style'=>'style', 'catalog'=>'catalog', 'link'=>'###', 'subject'=>'subject', 'add_date'=>'0'],  
        );  
$n = 0;  
foreach($result as $news) {  
    $news['add_date'] = date('{myTemplate::time}', $news['add_date']);  
    echo <<<content  
{myTemplate::unit}  
content;  
    if(++$n >= {myTemplate::loop}) break;  
}  
for(; $n<{myTemplate::loop}; $n++) {  
    echo <<<content  
{myTemplate::unit_blank}  
content;  
}  
?>  
mytpl;  
    return str_replace($block, $result, $tpl_content);  
}

首先,通过 regTag 的方法注册 parseTest 方法用于解析 test 标签,再通过解析方法,将对应的标签转换为php脚本,大致流程为:

    1. 通过 getTemplate 方法获取对应模块模版文件代码;
    2. 通过 getBlock 方法获取指定功能结构的相关代码,具体内容见上
    3. 获取数据,并转换模版代码为php代码,其中如果解析出的代码需要用到属性代码,由于此代码可能是变量,可以通过 {myTemplate::属性名称} 的方式插入到代码里,框架系统将在最后编译时替换为对应的变量或固定值,此外对于子模版中的单变量赋值标签,框架系统将会自动寻找同名属性值替换,如上例中的 name 被替换为 $_GET['n'],author 被替换为 myStep。
    4. 在将相关代码转换为对应的PHP代码后,将原有标签结构部分替换为所解析的PHP代码,并返回结果。当然,返回内容视标签具体情况而定,可灵活掌握。

 

页面生成

页面生成

生成页面的方法为:$tpl->render($global_vars, $tpl_show, $minify)

    • $global_vars 对于编译后的模版,由于属于黑盒执行的php脚本,相关全局变量需要通过此变量进行声明,内容为以逗号间隔的变量名;
    • $tpl_show 是否直接用于显示,默认为true,如果为false的话将直接返回编译后的页面内容;
    • $minify 是否对生成的页面内容做压缩处理,默认为false

本方法为模版类最后的实现方法,在解析之前框架系统会自动判断是否存在编译缓存,如存在且未过期,同时模版文件更改日期早于编译文件生成日期,则直接调用已编译好的缓存文件。

子模版引入

本模版系统未设置子模版的引入机制,但是可以通过声明子模版实例,再将解析后的页面代码(子模版实例的 $tpl_show 设定为 false)直接赋值给主模版的单一变量标签即可实现相同的结果,相关内容也更为可控。

 

上一篇:应用接口
下一篇:控制核心