视图模板
<h3>模板只是为了方便阅读,能够清晰的看懂模版的结构, 以及方便各个模板的组合和复用。使用另外的语法规则会引入额外的复杂度,增加使用者的学习成本,违背了此框架的初衷。有人认为需要为那些编写html的人员单独定制一套语法,我觉得与其额外增加一些稀奇古怪的语法规则,还不如使用原生的语法来的清晰,毕竟常用的就是 判断、循环、和几个格式化函数</h3>
<h3>模板语法其实很简单,只需要:</h3>
<p><strong>1: 记住模板定界符实际上只是将定界符内的内容 替换成了 <?php echo 定界符内的内容;?> </strong>
<strong>2: 理解 使用html标签的属性-值来声明需要执行的php方法和参数,其它和php代码都一样 </strong></p>
<p><strong><font color=red>注意:</font>需要在入口文件中加载 view 依赖库</strong>
<strong><font color=red>注意:</font>DEBUG['level'] > 1 的情况下才会<font color=red>自动更新</font>模板的缓存文件,否则如果修改了模板文件,需要<font color=red>手动删除</font>对应的模板缓存文件(/tmp/run/应用目录)</strong></p>
<h1>控制器中使用视图模板</h1>
<pre><code>&lt;?php
namespace app\ctrl;
use nec\z\view; // 使用view视图类
class index {
function index ()
{
$user = [
'username'=&gt;'user',
'userid'=&gt;123,
];
$data = [
'head'=&gt;'this is head',
'body'=&gt;'this is body',
];
$login = false;
view::Assign('user', $user); // 分配user变量
view::Assign('data', $data); // 分配data变量
view::Assign('login', $login); // 分配login变量
view::Display(); // 渲染默认路径下的模板
// view::Display('default/user/index'); // 渲染default样式目录下/user/index.html的模板
}
}</code></pre>
<h1>模板路径</h1>
<p><strong>默认路径:当前风格目录/控制器名/操作名.html</strong></p>
<p><strong>view::Display('index') 路径:当前风格目录/控制器名/index.html</strong></p>
<p><strong>view::Display('user/index') 路径:当前风格目录/user/index.html</strong></p>
<p><strong>view::Display('user/<font color=red>new_dir</font>/header') 路径:当前风格目录/user/<font color=red>new_dir</font>/header.html</strong></p>
<p><strong>也可以使用绝对路径,可以配合常量使用</strong></p>
<pre><code>$tpl = P_VIEW_MODULE . 'theme/user/index.html'
// 当前模块模板目录/theme风格目录/user/index.html
view::Display($tpl)</code></pre>
<p><strong>其它模块目录</strong></p>
<pre><code>$tpl = P_APP . 'test/view/' . THEME . '/user/index.html'
// 当前应用目录/test模块/模板目录/当前风格目录/user/index.html
view::Display($tpl)</code></pre>
<h1>模板引用:</h1>
<ul>
<li><strong>模板内使用 import 标签来引入其它模板文件,file属性指定要引入的模板文件路径,name属性指定要引入文件中的哪个 template 的内容;不指定 name 的情况下将导入整个文件内容</strong></li>
<li><strong>import 中可以使用<font color=red>路径常量</font>,<font color=red>不需要</font>添加变量解析标签</strong></li>
<li><strong>支持 ../ 相对路径</strong></li>
<li><strong>支持模板文件的嵌套引用</strong></li>
</ul>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;head&gt;
&lt;import file=&quot;block/common.html&quot; name=&quot;head&quot;/&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;import file=&quot;block/common.html&quot; name=&quot;nav&quot;/&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;h1&gt;&lt;{ $title }&gt;&lt;/h1&gt;
&lt;import file=&quot;index/block/content.html&quot; name=&quot;content&quot;/&gt;
&lt;/div&gt;
&lt;import file=&quot;block/common.html&quot; name=&quot;footer&quot;/&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><strong>要引用的模板文件:common.html</strong></p>
<pre><code>&lt;!-- head --&gt;
&lt;template name=&quot;head&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;&lt;{U_RES}&gt;/css/main.css&quot;&gt;
&lt;/template&gt;
&lt;!-- 导航 --&gt;
&lt;template name=&quot;nav&quot;&gt;
&lt;nav class=&quot;navbar&quot;&gt;
&lt;/nav&gt;
&lt;/template&gt;
&lt;!-- 页脚 --&gt;
&lt;template name=&quot;footer&quot;&gt;
&lt;footer class=&quot;footer&quot;&gt;&lt;/footer&gt;
&lt;/template&gt;</code></pre>
<h1>模板语法:</h1>
<p><strong><font color=red>注意:</font>模板内的标签<font color=red>必须配对或者闭合</font>,不能前一个 template 写 div 标签, 下一个 template 才写 /div 闭合,否则可能会解析错误!</font></strong></p>
<h2>显示变量:<{ $param }></h2>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;charset=UTF-8&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;$param变量值是:&lt;{ $param }&gt;&lt;/div&gt;
&lt;div&gt;可以使用三元表达式:&lt;{ $istrue ? $param : 'false' }&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h2>模板标签</h2>
<p><strong>框架采用模板标签的方式,兼顾简洁灵活</strong>
<strong>规则同样很简单:将判断,循环等语句写在标签的属性中即可</strong>
<strong>理解规则之后就可以很方便地使用了</strong></p>
<p><strong><font color=red>自定义标签名</font>:默认使用<php></php>标签,如有需要,可以修改配置文件的 VIEW['php_tag'] 字段</strong></p>
<ul>
<li>
<p><strong>条件判断</strong></p>
<pre><code>&lt;php if=&quot;$param1&quot;&gt;
&lt;p&gt;变量$param1是真&lt;/p&gt;
&lt;/php&gt;
&lt;php elseif=&quot;$param2&quot;&gt;
&lt;p&gt;变量$param2是真&lt;/p&gt;
&lt;/php&gt;
&lt;php else&gt;
&lt;p&gt;变量$param1和$param2都是假&lt;/p&gt;
&lt;/php&gt;</code></pre>
</li>
<li>
<p><strong>foreach 循环</strong>
<strong>此处直接写原生语句给<font color=red>$class</font>变量赋值</strong></p>
<pre><code>&lt;php foreach=&quot;$navs as $key=&gt;$value&quot;&gt;
&lt;?php $class = $key === $active ? 'active' : 'nav-item'; ?&gt;
&lt;a class=&quot;&lt;{ $class }&gt;&quot; href=&quot;&lt;{ $key }&gt;&quot;&gt;&lt;{ $key }&gt;&lt;/a&gt;
&lt;/php&gt;</code></pre>
</li>
<li>
<p><strong>for 循环</strong></p>
<pre><code>&lt;php for=&quot;$i=0; $i !== count($param); ++$i&quot;&gt;
&lt;h2 style=&quot;color:red;&quot;&gt;&lt;{ $param[$i] }&gt;&lt;/h2&gt;
&lt;/php&gt;</code></pre>
</li>
<li>
<p><strong>while 循环</strong></p>
<pre><code>&lt;php while=&quot;--$i&quot;&gt;
&lt;h3 style=&quot;color:cyan;&quot;&gt;&lt;{ $i }&gt;&lt;/h3&gt;
&lt;/php&gt;</code></pre>
</li>
<li><strong>switch 语句</strong>
<pre><code>&lt;php switch=&quot;$param&quot;&gt;
&lt;php case=&quot;0&quot; break&gt;&lt;p&gt;000000000&lt;/p&gt;&lt;/php&gt;
&lt;php case=&quot;1&quot;&gt;&lt;p&gt;11111111&lt;/p&gt;&lt;/php&gt;
&lt;php case=&quot;2&quot; break&gt;&lt;p&gt;2222222222&lt;/p&gt;&lt;/php&gt;
&lt;php default&gt;&lt;h1&gt;default&lt;/h1&gt;&lt;/php&gt;
&lt;/php&gt;</code></pre></li>
</ul>
<h1>模板的复用</h1>
<ul>
<li><strong>定义一个模板 hello:</strong>
<strong>其中<font color=red> 模板中使用的变量 </font>可以通过<font color=red> import </font>标签绑定变量</strong>
<strong>变量名必须<font color=red> 小写 </font>,由于变量的<font color=red> 作用域 </font>在整个视图中有效,建议添加前缀区别</strong>
<strong>为方便阅读和引用, 需在<font color=red>被调用的模板中声明需要传入的参数名</font> params="$var1,$var2"</strong>
<pre><code>&lt;template name=&quot;hello&quot; params=&quot;$tpl_cfg,$tpl_arr&quot;&gt;
&lt;p&gt;a: &lt;{$tpl_cfg['a']}&gt;&lt;/p&gt;
&lt;p&gt;b: &lt;{$tpl_cfg['b']}&gt;&lt;/p&gt;
&lt;php foreach=&quot;$tpl_arr['arr'] as $k=&gt;$v&quot;&gt;
&lt;p&gt;&lt;span&gt;&lt;{$k}&gt;&lt;/span&gt;:&lt;span&gt;&lt;{$v}&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/php&gt;
&lt;/template&gt;</code></pre></li>
<li><strong>引用多个模板 hello:</strong>
<strong>通过<font color=red> :tpl_cfg</font> 和 <font color=red>:tpl_arr </font> 属性绑定到模板内的<font color=red> $tpl_cfg </font>和<font color=red> $tpl_arr </font>变量</strong>
<strong><font color=red> :tpl_cfg</font> 和 <font color=red>:tpl_arr </font>属性的值可以是变量名 <font color=red>:tpl_cfg="$cfg" :tpl_arr="$arr"</font>
也可以直接赋值 <font color=red>:tpl_arr="['a'=>'111', 'b'=>'222']"</font></strong>
<pre><code>&lt;div&gt;
&lt;import file=&quot;common.html&quot; name=&quot;hello&quot; :tpl_cfg=&quot;['a'=&gt;'111', 'b'=&gt;'222']&quot; :tpl_arr=&quot;$arr&quot; /&gt;
&lt;hr&gt;
&lt;import file=&quot;common.html&quot; name=&quot;hello&quot; :tpl_cfg=&quot;$cfg1&quot; :tpl_arr=&quot;$arr1&quot; /&gt;
&lt;hr&gt;
&lt;import file=&quot;common.html&quot; name=&quot;hello&quot; :tpl_cfg=&quot;$cfg2&quot; :tpl_arr=&quot;$arr2&quot; /&gt;
&lt;/div&gt;</code></pre></li>
<li><strong>控制器内分配变量:</strong>
<pre><code>$arr = [1,2,3];
$arr1 = [11,22,33];
$arr2 = [111,222,333];
$cfg1 = ['a'=&gt;'a', 'b'=&gt;'b'];
$cfg2 = ['a'=&gt;'aa', 'b'=&gt;'bb'];
view::Assign('arr', $arr);
view::Assign('arr1', $arr1);
view::Assign('arr2', $arr2);
view::Assign('cfg1', $cfg1);
view::Assign('cfg2', $cfg2);
view::display();</code></pre></li>
</ul>
<h1>自定义标签</h1>
<ul>
<li><strong>配置文件增加 custom_tags 字段:</strong>
<pre><code>'VIEW' =&gt; [
'custom_tags'=&gt;[
'set'=&gt;['model\testc', 'testb', '$var'], // [类, 方法(默认为fn), 接收变量名(无此参数将重写此标签(将返回值当作php代码写入模板)]
'loop'=&gt;['model\viewTag', 'loop'],
'if' =&gt; ['model\viewTag', 'if'],
'data'=&gt;['', 'testb', '$var'], // 参数1留空则表示调用全局函数
],
]</code></pre></li>
<li><strong>模板中使用自定义标签</strong>
$var 是上面配置文件中定义的接收数据的变量名
标签各属性都被作为参数传入函数 <code>a=&quot;1&quot; src=&quot;abcd&quot;</code>
<strong>示例:该标签实际执行的是 $var = model\testc::testb($attrs); 使用 $var 接收返回值</strong>
<strong>标签属性 :var <font color=red>重新指定了接收变量为 $asd</font></strong>
<pre><code>&lt;set :var=&quot;$asd&quot; :num=&quot;5&quot; /&gt;
&lt;p style=&quot;color: red;&quot;&gt;&lt;{ json_encode($asd) }&gt;&lt;/p&gt;</code></pre>
<p><strong>示例:当方法返回值是数组的时候可以指定多个接收变量名 (用 , 分隔) 注意顺序要和返回值一致</strong></p>
<pre><code>&lt;set :num=&quot;5&quot;/&gt;
&lt;p style=&quot;color: red;&quot;&gt;&lt;{ $var1 }&gt;&lt;/p&gt;
&lt;p style=&quot;color: red;&quot;&gt;&lt;{ $var2 }&gt;&lt;/p&gt;
&lt;p style=&quot;color: red;&quot;&gt;&lt;{ $var3 }&gt;&lt;/p&gt;</code></pre></li>
</ul>
<h2>重写标签的返回代码</h2>
<p><strong><font color=red>详见示例: /model/viewTag.php</font></strong></p>
<h1>缓存页面 GetCache()</h1>
<p><strong><font color=red>只适合不需要登录的公共页面</font>,需要登录的页面,因为每个用户的页面是有区别的,所以不适合缓存页面</strong></p>
<table>
<thead>
<tr>
<th>参数</th>
<th>默认值</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>无</td>
<td>无 缓存时间</td>
</tr>
<tr>
<td>2</td>
<td>同 Display()</td>
<td>模板文件</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
<td>限制url参数,可以是:<br><font color=red>假:</font>无视url参数,只生成同一个页面。<br><font color=red>真:</font>url参数不同生成不同的缓存页面。<font color=red>数组:</font>过滤不在数组中的url参数。</td>
</tr>
</tbody>
</table>
<p><strong>参数3 通常用来做列表页的缓存,根据分页参数不同生成相应的缓存页面</strong>
<strong><font color=red>最好</font>限制一下有效参数,<font color=red>并且</font>事先判断一下取值范围</strong>
<strong>因为搜索引擎,蜘蛛,爬虫 == 可能会尝试不同的url参数抓取页面,会造成无故生成大量的相同内容的缓存页面</strong>
<strong><font color=red>只要</font>调用了GetCache()方法,后面的Display()就会生成缓存页面,<font color=red>而且</font>Display()中指定的模板文件参数<font color=red>无效</font>,使用的是GetCache()中的模板文件</strong></p>
<pre><code>public static function index()
{
$html = view::GetCache(60, 'index.html'); // 无视url参数
$html = view::GetCache(60, 'index.html', ['p']); // p 参数不同生成不同的缓存页面
$html = view::GetCache(60, 'index.html', ['p'=&gt;1]); // 指定p参数
$html = view::GetCache(60, 'index.html', true); // url参数不同生成不同的缓存页面
if($html){
echo $html;
} else {
// ... 代码
view::Display();
}
}</code></pre>
<h1>压缩编译生成的模板页</h1>
<p><strong>配置文件 VIEW 的 compress 字段</strong>
<strong>可选值:</strong></p>
<ul>
<li>1:只删除注释</li>
<li>2:删除注释并压缩</li>
</ul>
<p><strong><font color=red>注意:</font>上面的配置对 javascript 和 css 同样生效</strong>
<strong><font color=red>如果有不同策略:</font>请配置为数组格式:</strong>
<strong>[0]:html 的参数值,[1]:style标签内css的参数值,[2]:javascript 的参数值</strong>
<strong>例如:[2, 1, 1] 表示 html:删除注释并压缩,css:只删除注释,javascript:只删除注释</strong></p>