Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep indentation level for included Twig subtemplate

Tags:

twig

symfony

I'm working with the Twig template engine and want to include a sub-template linke the following example:

<header>
  <div id="menu">
    {% include 'menu.twig' %}
  </div>
</header>

The included file contains the following code:

<ul>
  <li>item 1</li>
  <li>item 2</li>
</ul>

Now Twig generates the followig HTML code:

<header>
  <div id="menu">
    <ul>
  <li>item 1</li>
  <li>item 2</li>
</ul>
  </div>
</header>

As you can see the indentation level is only correct for the first line of the included file which leads to the code above which is quite untidy and bad to maintain.

How is it possible to get a correct output from Twig with correct indentation like this?

<header>
  <div id="menu">
    <ul>
      <li>item 1</li>
      <li>item 2</li>
    </ul>
  </div>
</header>
like image 244
ProgUser44 Avatar asked Jul 26 '15 16:07

ProgUser44


2 Answers

I don't think there is a way to maintain indentation when including templates. The only solution I can imagine would be to pass the indentation level in a variable and use a loop in the included template to prefix that amount of whitespaces in each line. Obviously this "solution" would be crazy and a nightmare to maintain.

Regarding this comment: "[...] which leads to the code above which is quite untidy and bad to maintain." I'd like to say the following:

  • It doesn't matter if the HTML is "untidy". Browsers won't complain and users won't see it.
  • It's true that it's bad to maintain. Luckily, you maintain the beautifully aligned Twig template, not the generated HTML code.

All the above would be different if the Twig template was generating a format where "perfect alignment" is mandatory. But in the case of HTML, please don't waste your time aligning the tags.

like image 166
Javier Eguiluz Avatar answered Nov 14 '22 00:11

Javier Eguiluz


If you just want to maintain the exact indentation of the included sub-template, you can do this:

<header>
  <div id="menu">
{% include 'menu.twig' %}
  </div>
</header>

i.e. put all the "include" directives at the beginning of the line. The result will be:

<header>
  <div id="menu">
<ul>
  <li>item 1</li>
  <li>item 2</li>
</ul>
  </div>
</header>

But somehow I feel this is not good enough. Another solution is to add the indentation in the sublayout, i.e.

    <ul>
      <li>item 1</li>
      <li>item 2</li>
    </ul>

but of course it only works if the sublayout is always included at a certain level of indentation.

I suggest you take a completely different route and format the response after it is generated, e.g. with a listener on the kernel.response event.

like image 1
Francesco Abeni Avatar answered Nov 14 '22 01:11

Francesco Abeni