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

 更新时间:2014年06月13日 10:59:28   投稿:junjie   我要评论
这篇文章主要介绍了在Yii框架中使用PHP模板引擎Twig的例子,Twig是一款简洁的PHP模板引擎,在此小编也介绍一下,需要的朋友可以参考下

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 %}

相关文章

  • PHP传值到不同页面的三种常见方式及php和html之间传值问题

    PHP传值到不同页面的三种常见方式及php和html之间传值问题

    这篇文章主要介绍了PHP传值到不同页面的三种常见方式及php和html之间传值问题的相关资料,需要的朋友可以参考下
    2015-11-11
  • php解压文件代码实现php在线解压

    php解压文件代码实现php在线解压

    这篇文章主要介绍了php解压文件代码,根据这个代码可以实现php在线解压功能,需要的朋友可以参考下
    2014-02-02
  • 基于PHP生成静态页的实现方法

    基于PHP生成静态页的实现方法

    本篇文章是对PHP生成静态页的实现方法进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • PHP中SSO Cookie登录分析和实现

    PHP中SSO Cookie登录分析和实现

    单点登录SSO(Single Sign-On)是身份管理中的一部分。SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证
    2015-11-11
  • YII中Ueditor富文本编辑器文件和图片上传的配置图文教程

    YII中Ueditor富文本编辑器文件和图片上传的配置图文教程

    本文主要给大家介绍了YII中Ueditor富文本编辑器文件和图片上传的配置图文教程,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • Laravel 5框架学习之表单验证

    Laravel 5框架学习之表单验证

    Laravel 通过 Validation 类让您可以简单、方便的验证数据正确性及查看相应的验证错误信息。如果是更复杂的验证场景,你可能需要创建一个"表单请求"。表单请求是一个自定义的请求类包含了一些验证的逻辑。你可以通过 Artisan 的命令行 make:request 来创建一个表单请求类
    2015-04-04
  • Laravel中9个不经常用的小技巧汇总

    Laravel中9个不经常用的小技巧汇总

    这篇文章主要给大家总结介绍了关于Laravel中9个不经常用的小技巧,文中通过示例代码介绍的非常详细,对大家学习或者使用Laravel具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • Zend Framework教程之前端控制器Zend_Controller_Front用法详解

    Zend Framework教程之前端控制器Zend_Controller_Front用法详解

    这篇文章主要介绍了Zend Framework教程之前端控制器Zend_Controller_Front用法,详细分析了前端控制器Zend_Controller_Front的功能,使用方法与相关注意事项,需要的朋友可以参考下
    2016-03-03
  • wampserver改变默认网站目录的办法

    wampserver改变默认网站目录的办法

    大家在做php项目时,很多项目都会用到wampserver。WampServe集成了Apache、MySQL、PHP、phpmyadmin,支持Apache的mod_rewrite,PHP扩展、Apache模块只需要在菜单“开启/关闭”上点点就搞定,省去了修改配置文件的麻烦,这里就简写成wamp。
    2015-08-08
  • php面向对象与面向过程两种方法给图片添加文字水印

    php面向对象与面向过程两种方法给图片添加文字水印

    使用许多编程语言时,你通常只能使用面向对象或面向过程二者之一的编程方式。而在PHP中,你可以自由选择或混用,下面通过面向对象与面向过程两种方法给图片添加水印,需要的朋友可以参考下
    2015-08-08

最新评论