symfony 每块都用 spaceless
如何用无空格包装每个块代码以从我的 twig/html 中裁剪空格
How i can wrap every block code with spaceless to crop whitespaces from my twig/html
例如现在我有:
{% block content %}
<div class="box clearfix clearall">
<div class="ct colcontainer">
<div class="col-1">
<div class="chars">
<table class="layout data-char">
<thead>
blabla
{% endblock %}
当 symfony 尝试渲染它时,我希望 symfony 看到
And when symfony try to render it, i want that symfony saw
{% block content %}
{% spaceless %}
<div class="box clearfix clearall">
<div class="ct colcontainer">
<div class="col-1">
<div class="chars">
<table class="layout data-char">
<thead>
blabla
{% endspaceless %}
{% endblock %}
推荐答案
定义一个自定义的 Twig 标签(复制粘贴方式)
您可以定义一个自定义的 Twig 标签 spacelessblock
它结合了 block
和 无空间
.然后你可以在你的模板中使用 {% spacelessblock xyz %}...{% endspacelessblock %}
.这是你如何快速而肮脏(复制和粘贴)的方式.
Define a custom Twig tag (the copy-and-paste way)
You can define a custom Twig tag spacelessblock
which combines block
and spaceless
. Then you can use {% spacelessblock xyz %}…{% endspacelessblock %}
in your templates. Here is how you do it the quick and dirty (copy and paste) way.
首先,定义一个类 Twig_Node_SpacelessBlock
(例如,在你的 bundle 的 Extension
目录中):
First, define a class Twig_Node_SpacelessBlock
(e.g. in the Extension
directory of your bundle):
class Twig_Node_SpacelessBlock extends Twig_Node_Block
{
public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
{
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
}
public function compile(Twig_Compiler $compiler)
{
// top part of Block.compile
$compiler
->addDebugInfo($this)
->write(sprintf("public function block_%s($context, array $blocks = array())
", $this->getAttribute('name')), "{
")
->indent()
;
// the content of the body is treated like in Spaceless.compile
$compiler
->write("ob_start();
")
->subcompile($this->getNode('body'))
->write("echo trim(preg_replace('/>s+</', '><', ob_get_clean()));
")
;
// bottom part of Block.compile
$compiler
->outdent()
->write("}
")
;
}
}
新的 Twig 令牌解析器
每当 Twig 在模板中找到 {% spacelessblock xyz %}
时,都需要在某处构建我们的新 Twig 节点.为此,我们需要一个令牌解析器,我们称之为 Twig_TokenParser_SpacelessBlock
.我们基本上是复制粘贴 Twig_TokenParser_Block
:
A new Twig token parser
Our new Twig node needs to be built somewhere whenever Twig finds a {% spacelessblock xyz %}
in a template. For that, we need a token parser which we call Twig_TokenParser_SpacelessBlock
. We basically copy and paste Twig_TokenParser_Block
:
class Twig_TokenParser_SpacelessBlock extends Twig_TokenParser
{
public function parse(Twig_Token $token)
{
// …
$this->parser->setBlock($name, $block = new Twig_Node_SpacelessBlock($name, new Twig_Node(array()), $lineno));
// …
}
public function decideBlockEnd(Twig_Token $token)
{
return $token->test('endspacelessblock');
}
public function getTag()
{
return 'spacelessblock';
}
}
把这件事告诉 Twig
在你的扩展类中:
Tell Twig about it
In your extension class:
class Extension extends Twig_Extension
{
public function getTokenParsers()
{
return array(
new Twig_TokenParser_SpacelessBlock(),
);
}
}
告诉 Symfony
如果尚未完成,请将以下内容添加到您的 services.yml
:
services:
# …
my.extension:
class: AcmeMyBundleExtensionExtension
tags:
- { name: twig.extension }
更好的选择
预处理器
更好的方法是使用预处理器来简单地替换
Better alternatives
Preprocessor
A better way would be to use a preprocessor to simply replace
{% spacelessblock xyz %}
…
{% endspacelessblock %}
由
{% block xyz %}{% spaceless %}
…
{% endspaceless %}{% endblock %}
它重用了 Twig 项目中已经编写的所有代码,包括可能的更改.
which reuses all the code that already has been written in the Twig project, including possible changes.
相关文章