symfony 每块都用 spaceless

2022-01-22 00:00:00 php symfony html twig

如何用无空格包装每个块代码以从我的 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.

相关文章