在Yii框架中使用PHP模板引擎Twig的例子

Twig是一款快速、安全、灵活的PHP模板引擎,它内置了许多filter和tags,并且支持模板继承,能让你用最简洁的代码来描述你的模板。他的语法和Python下的模板引擎Jinjia以及Django的模板语法都非常像。 比如我们在PHP中需要输出变量并且将其进行转义时,语法比较累赘:


代码如下:

<?php echo $var ?>
<?php echo htmlspecialchars(\$var, ENT_QUOTES, 'UTF-8') ?>

但是在Twig中可以这样写:


代码如下:

{{ var }}
{{ var|escape }}
{{ var|e }}         {# shortcut to escape a variable #}

遍历数组:


代码如下:

{% for user in users %}
  * {{ user.name }}
{% else %}
  No user has been found.
{% endfor %}

但是要在Yii Framework集成Twig就会遇到点麻烦了,官方网站中已经有能够集成Twig的方案,所以这里我也不再赘述。但是由于Twig中是不支持PHP语法的,所以在有些表达上会遇到困难,比如我们在写Form的视图时,经常会这么写:


代码如下:

<?php $form=$this->beginWidget('CActiveForm'); ?>
    <span>Login</span>
    <ul>
  <li>
    <?php echo $form->label($model,'username'); ?>
                <?php echo $form->textField($model,'username'); ?>

</li>

<li>
    <?php echo $form->label($model,'password'); ?>
                <?php echo $form->passwordField($model,'password'); ?>

</li>

<li class="last">
    <button type="submit">Login</button>

</li>

</ul>
    <?php echo $form->error($model,'password'); ?>
<?php $this->endWidget(); ?>

但是这样的语法是没法在twig中表达的,所以想去扩展下Twig的功能,让他能够支持我们自定义的widget标签,然后自动解析成我们需要的代码。 总共需要两个类:TokenParser和Node,下面直接上代码:


代码如下:

<?php
/*
 * This file is an extension of Twig.
 *
 * (c) 2010 lfyzjck
 */

/**
 * parser widget tag in Yii framework
 *
 * {% beginwidget 'CActiveForm' as form %}
 *    content of form
 * {% endwidget %}
 *
 */
class Yii_WidgetBlock_TokenParser extends Twig_TokenParser
{
    /**
     * Parses a token and returns a node.
     *
     * @param Twig_Token $token A Twig_Token instance
     *
     * @return Twig_NodeInterface A Twig_NodeInterface instance
     */
    public function parse(Twig_Token $token)
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();

$name = $stream->expect(Twig_Token::STRING_TYPE);
        if($stream->test(Twig_Token::PUNCTUATION_TYPE)){
            $args = $this->parser->getExpressionParser()->parseHashExpression();
        }
        else{
            $args = new Twig_Node_Expression_Array(array(), $lineno);
        }

$stream->expect(Twig_Token::NAME_TYPE);
        $assign = $stream->expect(Twig_Token::NAME_TYPE);
        $stream->expect(Twig_Token::BLOCK_END_TYPE);

$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
        $stream->expect(Twig_Token::BLOCK_END_TYPE);

return new Yii_Node_WidgetBlock(array(
            'alias' => $name->getValue(),
            'assign' => $assign,
        ), $body, $args, $lineno, $this->getTag());
    }

/**
     * Gets the tag name associated with this token parser.
     *
     * @param string The tag name
     */
    public function getTag()
    {
        return 'beginwidget';
    }

public function decideBlockEnd(Twig_Token $token)
    {
        return $token->test('endwidget');
    }
}

class Yii_Node_WidgetBlock extends Twig_Node
{
    public function __construct($attrs, Twig_NodeInterface $body, Twig_Node_Expression_Array $args = NULL, $lineno, $tag)
    {
        $attrs = array_merge(array('value' => false),$attrs);
        $nodes = array('args' => $args, 'body' => $body);
        parent::__construct($nodes, $attrs, $lineno,$tag);
    }

public function compile(Twig_Compiler $compiler)
    {
        $compiler->addDebugInfo($this);
        $compiler->write('$context["'.$this->getAttribute('assign')->getValue().'"] = $context["this"]->beginWidget("'.$this->getAttribute('alias').'",');
        $argNode = $this->getNode('args');
        $compiler->subcompile($argNode)
                 ->raw(');')
                 ->raw("\n");

$compiler->indent()->subcompile($this->getNode('body'));

$compiler->raw('$context["this"]->endWidget();');
    }
}
?>

然后在Twig初始化的地方增加我们的语法解析类:


代码如下:

$twig->addTokenParser(new Yii_WidgetBlock_TokenParser);

然后我们就可以在twig的模板里这么写了:


代码如下:

{% beginwidget 'CActiveForm' as form %}
<ul>
  <li>
    {{ form.label(model, 'username') }}
    {{ form.textField(model, 'username') }}
  </li>
  <li>
    {{ form.label(model, 'password') }}
    {{ form.passwordField(model, 'password') }}
  </li>
</ul>
{% endwidget %}

(0)

相关推荐

  • PHP YII框架开发小技巧之模型(models)中rules自定义验证规则

    YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规则后才能被提交,可以很有效地保证表单安全和信息的有效性.还是给大家具体说明一下: 以下是视图(views)部分的简单代码: <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'tag-form', 'enableAjaxVa

  • yiic命令时提示“php.exe”不是内部或外部命令的解决方法

    本文实例讲述了yiic命令时提示"php.exe"不是内部或外部命令的解决方法,分享给大家供大家参考.具体方法如下: 在CMD中运行 yiic webapp work 如果报"php.exe"不是内部命令,是这样的:原因是Yii自带的yiic.bat找不到php.exe. 解决方法: 因为没有加入环境变量,所以无法直接执行php.exe. 右击"我的电脑->属性->高级->环境变量->系统变量->PATH->编辑&quo

  • 详细解读PHP的Yii框架中登陆功能的实现

    Yii的登陆机制 Yii 生成应用时已经提供了最基础的用户登陆机制.我们用 Yii 生成一个新的应用,进入 protected/components 目录,我们可以看到 UserIdentity.php 文件,里面的 UserIdentity 类里面只有一个 public 函数如下: public function authenticate() { $users=array( // username => password 'demo'=>'demo', 'admin'=>'admin'

  • PHP的Yii框架中Model模型的学习教程

    模型是 MVC 模式中的一部分, 是代表业务数据.规则和逻辑的对象. 模型是 CModel 或其子类的实例.模型用于保持数据以及与其相关的业务逻辑. 模型是单独的数据对象.它可以是数据表中的一行,或者一个用户输入的表单. 数据对象的每个字段对应模型中的一个属性.每个属性有一个标签(label), 并且可以通过一系列规则进行验证. Yii 实现了两种类型的模型:表单模型和 Active Record.二者均继承于相同的基类 CModel. 表单模型是 CFormModel 的实例.表单模型用于保持

  • PHP yii实现model添加默认值的方法(两种方法)

    yii实现model添加默认值的方法(2种方法) 这篇文章主要介绍了yii实现model添加默认值的方法,结合实例分析了在rules()方法及在beforeSave()方法中设定两种实现技巧,对大家也许有帮助, 本文实例讲述了yii实现model添加默认值的方法.分享给大家供大家参考,具体如下: yii model 继承自CActiveRecord 有些字段可能不会出现在表单中,而需要在程序中加入.如订单编号,时间戳,操作的user_id等等. 以下二种方法: 1.在rules()方法中设定:

  • Yii中使用PHPExcel导出Excel的方法

    本文实例讲述了Yii中使用PHPExcel导出Excel的方法.分享给大家供大家参考.具体分析如下: 最近在研究PHP的Yii框架,很喜欢,碰到导出Excel的问题,研究了一下,就有了下面的方法. 1.首先在cofig/main.php中添加对PHPExcel的引用,我的方法是这样,代码如下: 复制代码 代码如下: // autoloading model and component classes     'import'=>array(         /*'application.modu

  • Yii PHP Framework实用入门教程(详细介绍)

    说明:因为最近工作工作关系,需要开发一个在Linux下运行的Web Application,需要对现在比较流行的一些PHP框架做一个了解和评估,下面的这篇文章是笔者最近学习一个比较新的PHP Framework的一点经历和操作步骤,因为官方的手册写得比较晦涩(特别是中文的),曾经尝试遍读它那个手册再动手,读了一大半发现仍无法理解,于是干脆先下手为强了,因而也就有了下面的文章. 介绍Yii 是一个基于组件.纯OOP的.用于开发大型 Web 应用的高性能 PHP 框架.它将 Web 编程中的可重用性

  • PHP 基于Yii框架中使用smarty模板的方法详解

    第一种方法按照YII系统的办法生成视图觉得有点麻烦,觉得用smarty更省事.尝试着把smarty模板加进来了. 复制代码 代码如下: date_default_timezone_set("PRC");class PlaceController extends CController {protected $_smarty;function __construct(){parent::__construct('place');//需要一个参数来调用父类的构造函数,该参数为控制器ID$p

  • 在Yii框架中使用PHP模板引擎Twig的例子

    Twig是一款快速.安全.灵活的PHP模板引擎,它内置了许多filter和tags,并且支持模板继承,能让你用最简洁的代码来描述你的模板.他的语法和Python下的模板引擎Jinjia以及Django的模板语法都非常像. 比如我们在PHP中需要输出变量并且将其进行转义时,语法比较累赘: 复制代码 代码如下: <?php echo $var ?><?php echo htmlspecialchars(\$var, ENT_QUOTES, 'UTF-8') ?> 但是在Twig中可以这

  • Python的Flask框架中的Jinja2模板引擎学习教程

    Flask的模板功能是基于Jinja2模板引擎来实现的.模板文件存放在当前目前下的子目录templates(一定要使用这个名字)下. main.py 代码如下: from flask import Flask, render_template app = Flask(__name__) @app.route('/hello') @app.route('/hello/<name>') def hello(name=None): return render_template('hello.html

  • YII框架中使用memcache的方法详解

    本文实例讲述了YII框架中使用memcache的方法.分享给大家供大家参考,具体如下: yii中可以很方便的使用memcache 一.配置 在main.php的components中加入cache配置 array( 'components'=>array( 'cache'=>array( 'class'=>'CMemCache', 'servers'=>array( array( 'host'=>'server1', 'port'=>11211, 'weight'=&g

  • Yii框架中jquery表单验证插件用法示例

    本文实例讲述了Yii框架中jquery表单验证插件用法.分享给大家供大家参考,具体如下: 运行效果图如下: 视图层: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtm

  • Yii框架中sphinx索引配置方法解析

    本文实例讲述了Yii框架中sphinx索引配置方法.分享给大家供大家参考,具体如下: 请先将var/test/documents.sql导入数据库,并配置好以下的MySQL用户密码数据库 #源定义 source mysql { type = mysql sql_host = localhost sql_user = root sql_pass = root sql_db = yii2 sql_port = 3306 sql_query_pre = SET NAMES utf8 sql_query

  • 实例讲解如何在PHP的Yii框架中进行错误和异常处理

    Yii已经默认已经在CApplication上实现了异常和错误的接管,这是通过php的set_exception_handler,set_error_handler实现的.通过这两个PHP内置函数,可以对程序中未捕获的异常以及错误进行接管处理,从而提高程序的可维护性.这在大型系统是至关重要的,当发生错误时,我们希望能将相关详细信息记录,甚至是即时发送报警,从而缩短故障修复时间,提高整个系统的稳定性. 默认情况下,Yii会将异常处理分配给CApplication::handleException,

  • Yii框架中使用PHPExcel的方法分析

    本文实例分析了Yii框架中使用PHPExcel的方法.分享给大家供大家参考,具体如下: PHPExcel是一个比较好用的php读取excel文件的类库,今天遇到了在yii中如何加载PHPExcel类文件的问题,因为Yii的autoload机制是安装类名去找文件,即文件名就是相应的类名,而PHPExcel的类文件命名方式则是:dir_dir_classname.php,即文件名把文件的目录名都记录了,这种命名方式yii肯定识别不了.怎么办? 其实PHPExcel也有自己的autoload方法(PH

  • laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例

    本文实例讲述了laravel框架实现为 Blade 模板引擎添加新文件扩展名.分享给大家供大家参考,具体如下: 因为一些原因,我准备把 Blessing Skin 的框架换成 Laravel 了(之前是自己搭建的一个框架),但是在模板迁移的时候遇到了一点问题. 之前我是使用的 XiaoLer/blade这个从 Laravel 中抽离出来的 Blade 模板引擎,并且自定义为使用 .tpl文件后缀.你问为啥不用默认的 .blade.php 而是用这个 Smarty 的模板扩展名?能有啥,好看呗 :

  • PHP中迭代器的简单实现及Yii框架中的迭代器实现方法示例

    本文实例讲述了PHP中迭代器的简单实现及Yii框架中的迭代器实现方法.分享给大家供大家参考,具体如下: 在维基百科中我们可以看到其定义如下: 迭代器有时又称光标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如list或vector)上遍访的接口,设计人员无需关心容器物件的内容. 各种语言实作Iterator的方式皆不尽同,有些面向对象语言像Java, C#, Python, Delphi都已将Iterator的特性内建语言当中,完美的跟语言整合,我们称之隐式迭代器

随机推荐