YiiフレームでPHPテンプレートエンジンTwigを使用した例
しかし、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のビューを書くときによくこのように書くなど、表現に困難があります.
beginWidget('CActiveForm'); ?>
Login
-
label($model,'username'); ?>
textField($model,'username'); ?>
label($model,'password'); ?>
passwordField($model,'password'); ?>
error($model,'password'); ?>
endWidget(); ?>
しかし、このような文法はtwigでは表現できないので、Twigの機能を拡張して、私たちがカスタマイズしたwidgetラベルをサポートして、自動的に必要なコードに解析したいと思っています.TokenParserとNodeの2つのクラスが必要です.次は直接コードします.
/*
* 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("
");
$compiler->indent()->subcompile($this->getNode('body'));
$compiler->raw('$context["this"]->endWidget();');
}
}
?>
その後、Twig初期化の場所で文法解析クラスを追加します.
$twig->addTokenParser(new Yii_WidgetBlock_TokenParser);
twigのテンプレートにこう書くことができます
{% beginwidget 'CActiveForm' as form %}
-
{{ form.label(model, 'username') }}
{{ form.textField(model, 'username') }}
-
{{ form.label(model, 'password') }}
{{ form.passwordField(model, 'password') }}
{% endwidget %}