找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2057|回复: 0
打印 上一主题 下一主题

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

[复制链接]

2560

主题

2560

帖子

7622

积分

论坛元老

Rank: 8Rank: 8

积分
7622
跳转到指定楼层
楼主
发表于 2018-2-14 05:57:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            Twig是一款快速、安全、灵活的PHP模板引擎,它内置了许多filter和tags,并且支持模板继承,能让你用最简洁的代码来描述你的模板。他的语法和Python下的模板引擎Jinjia以及Django的模板语法都非常像。 比如我们在PHP中需要输出变量并且将其进行转义时,语法比较累赘:
[U]复制代码[/U] 代码如下:
但是在Twig中可以这样写:
[U]复制代码[/U] 代码如下:
{{ var }}
{{ var|escape }}
{{ var|e }}         {# shortcut to escape a variable #}
遍历数组:
[U]复制代码[/U] 代码如下:
{% for user in users %}
  * {{ user.name }}
{% else %}
  No user has been found.
{% endfor %}
但是要在Yii Framework集成Twig就会遇到点麻烦了,官方网站中已经有能够集成Twig的方案,所以这里我也不再赘述。但是由于Twig中是不支持PHP语法的,所以在有些表达上会遇到困难,比如我们在写Form的视图时,经常会这么写:
[U]复制代码[/U] 代码如下:
beginWidget('CActiveForm'); ?>
    Login
   
  

  •     label($model,'username'); ?>
                    textField($model,'username'); ?>
      
      

  •     label($model,'password'); ?>
                    passwordField($model,'password'); ?>
      
      
        Login
      

        error($model,'password'); ?>
    endWidget(); ?>
    但是这样的语法是没法在twig中表达的,所以想去扩展下Twig的功能,让他能够支持我们自定义的widget标签,然后自动解析成我们需要的代码。 总共需要两个类:TokenParser和Node,下面直接上代码:
    [U]复制代码[/U] 代码如下:
    /**
    * 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:UNCTUATION_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初始化的地方增加我们的语法解析类:
    [U]复制代码[/U] 代码如下:
    $twig->addTokenParser(new Yii_WidgetBlock_TokenParser);
    然后我们就可以在twig的模板里这么写了:
    [U]复制代码[/U] 代码如下:
    {% beginwidget 'CActiveForm' as form %}

      

  •     {{ form.label(model, 'username') }}
        {{ form.textField(model, 'username') }}
      
      

  •     {{ form.label(model, 'password') }}
        {{ form.passwordField(model, 'password') }}
      

    {% endwidget %}
                
                
    您可能感兴趣的文章:
  • PHP 基于Yii框架中使用smarty模板的方法详解
  • Yii PHP Framework实用入门教程(详细介绍)
  • yiic命令时提示“php.exe”不是内部或外部命令的解决方法
  • Yii中使用PHPExcel导出Excel的方法
  • 详细解读PHP的Yii框架中登陆功能的实现
  • PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
  • PHP的Yii框架中Model模型的学习教程
  • PHP yii实现model添加默认值的方法(两种方法)
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端