原文发表于:Phalcon入门教程之Volt模板引擎
volt
是Phalcon中集成的模板引擎,我们也可以更换为其他模板引擎或同时使用多个模板引擎。本文只介绍 Phalcon
自带的 volt
模板引擎。
启用Volt
和其他模板引擎一样,我们需要将 volt
模板注册到 views
组件中,并设置模板文件通用后缀名,或者直接使用标准化的后缀名 .phtml
才能正常使用:
//文件路径:Marser\App\Frontend\FrontendModule.php
$di->setShared('view', function () use ($config, $di) {
$view = new \Phalcon\Mvc\View();
//设置模板根目录
$view->setViewsDir(ROOT_PATH . '/app/frontend/views/');
//注册模板引擎
$view->registerEngines(array(
//设置模板后缀名
'.phtml' => function ($view, $di) use ($config) {
$volt = new \Phalcon\Mvc\View\Engine\Volt($view, $di);
$volt->setOptions(array(
//模板是否实时编译
'compileAlways' => false,
//模板编译目录
'compiledPath' => ROOT_PATH . '/app/cache/compiled/frontend'
));
return $volt;
},
));
return $view;
});
用法
volt
模板中 基本用法 、 变量 、表达式 、 流程控制等部分的具体用法,文档中已有详细说明,请直接翻阅Phalcon文档
这里分享一下大家咨询比较多的几处用法以及踩过的坑。
控制器指定模板
public function testAction(){
$this->view->pick('view/test');
}
变量传值
//控制器中变量
public function test2Action(){
//setVar:单独进行变量传值
$this->view->setVar('test', 'hello world');
//setVars:关联数组进行变量传值
//$this->view->setVars([
// 'test' => 'hellow world',
//]);
$this->view->pick('view/test2');
}
数值循环(For)
Phalcon文档 中有提到 volt
模板中 对象
和 关联数组
的循环方式,但没有明确例子来说明数值循环的用法。具体用法请看如下示例代码:
{% for i in 0..100 %}
<div>{{i}}</div>
{% endfor %}
连接符
在 volt
模板中的连接符不是 .
,也不是 +
,而是 ~
,代码示例如下:
{{ url('user/detail?uid='~user['uid']) }}
模板继承
Phalcon文档 中有非常详细的 模板的继承
的用法。这里和大家分享我在使用模板继承过程中踩过的一个坑:
<html>
<head>
{% block head %}
<link rel="stylesheet" href="style.css" />
{% endblock %}
</head>
<body>
<div id="content">
{% block content %}
<div>
{% block subContent %}{% endblock %}
</div>
{% endblock %}
</div>
</body>
</html>
在模板编译过程中,会报如下错误信息:
#模板继承中的block块不能嵌套
Embedding blocks into other blocks is not supported
目前官方暂未计划支持此功能,所以大家在使用模板继承时,需要特别注意规避block块嵌套的问题。
扩展模板函数
volt
模板中提供了一些常用的基本函数,若想在其中使用自定义函数或PHP自带的其他函数,则需要将函数注册到 volt
模板中。
首先,我们定义一个 volt
模板基类,并通过 模板编译器
添加函数:
//文件路径:Marser\App\Core\PhalBaseVolt.php
use \Phalcon\Mvc\View\Engine\Volt;
class PhalBaseVolt extends Volt{
/**
* 添加扩展函数
*/
public function initFunction(){
$compiler = $this->getCompiler();
// 添加PHP自带的explode函数
$compiler -> addFunction('explode', 'explode');
// 添加自定义的get_userinfo函数
//$resolvedArgs即为任意参数,可接收多个参数
//这里需要注意的是,匿名函数中的return返回值必须是string类型,且不需要实例化类,直接通过范围解析操作符(::)调用成员方法
$compiler -> addFunction('get_userinfo', function($resolvedArgs, $exprArgs) use ($compiler){
return '\Marser\App\Libs\Test::get_userinfo(' . $resolvedArgs . ')';
});
}
}
其中自定义函数 get_userinfo()
的代码如下:
//文件路径:Marser\App\Libs\Test.php
class Test {
public function get_userinfo($username, $age, $mobile){
return "用户名:{$username}, 年龄:{$age}, 联系方式:{$mobile}";
}
}
通过上述代码,就已经向模板编译器中添加了PHP自带的 explode()
函数和程序中自定义的 get_userinfo()
函数。
然后,我们修改 DI
中注册的 views
对象:
//文件路径:Marser\App\Frontend\FrontendModule.php
$di -> setShared('view', function() use($config) {
$view = new \Phalcon\Mvc\View();
#设置模板根目录
$view -> setViewsDir(ROOT_PATH . '/app/frontend/views/');
#注册模板引擎
$view -> registerEngines(array(
#设置模板后缀名
'.phtml' => function($view, $di) use($config) {
#实例化volt模板对象
$volt = new \Marser\App\Core\PhalBaseVolt($view, $di);
#设置模板配置项
$volt -> setOptions(array(
#模板是否实时编译
'compileAlways' => false,
#模板编译目录
'compiledPath' => ROOT_PATH . '/app/cache/compiled/frontend'
));
# 注意!区别在此行---添加模板扩展函数
$volt -> initFunction();
return $volt;
},
));
return $view;
});
至此, explode()
和 get_userinfo()
两个函数就已经注册在模板中了。那么,如何调用呢?explode()
在模板中调用的示例代码:
{% set introArray = explode('-', intro) %}
{% for value in introArray %}
<div>{{value}}</div>
{% endfor %}
自定义函数 get_userinfo()
在模板中调用的示例代码:
{{get_userinfo('admin', '20', '中国上海')}}
不论是PHP自带函数,还是程序中自定义的函数,只需按照函数定义时的参数顺序传参即可。
以上代码已托管在github:https://github.com/KevinJay/marser-phalcon-demo
最后,欢迎大家加入QQ群交流讨论:
- 广州PHP高端交流群:158587573
- Phalcon玩家群:150237524