Extend template shareware in Twig

Take the following tree structure:

β”œβ”€β”€β”€base β”‚ β”œβ”€β”€β”€0001 β”‚ β”‚ └───pages β”‚ β”‚ file.twig β”‚ β”‚ file_content.twig β”‚ └───ext β”‚ └───store β”‚ β”‚ └───pages β”‚ β”‚ └───all β”‚ β”‚ β”‚ file.twig β”‚ β”‚ └───0001 β”‚ β”‚ file.twig β”‚ └───newsletter β”‚ └───pages β”‚ └───all β”‚ β”‚ file.twig β”‚ └───0001 β”‚ file.twig └───pages β”‚ file.twig └───0001 file.twig 

As you can see, the file.twig load is scattered there.

I want to display the contents of the file base/0001/pages/file_content.twig .
But I want the following files to be able to modify contents inside blocks:

  • ext/<...>/pages/0001/file.twig
  • ext/<...>/pages/all/file.twig
  • /pages/0001/file.twig
  • /pages/file.twig

But these files may or may not exist, may or may not be necessary, and must be able to modify the contents of any block.

Is there any way to make this work?

So far I have the following:

 {% embed 'base/pages/file_content.twig' %} {% block page_file %} {{ parent() }} {% if data.store_enabled %} {% include [ 'base/ext/store/pages/0001/file.twig', 'base/ext/store/pages/all/file.twig' ] ignore missing %} {% endif %} {% include ['pages/0001/file.twig', 'pages/file.twig'] ignore missing %} {% endblock %} {% endembed %} 

This "works" in the sense that it displays the page, but does not allow you to block any block.

How can I do this job?


As an example, consider this file structure (yes, files are missing and expected):

  β”œβ”€β”€β”€base β”‚ β”œβ”€β”€β”€0001 β”‚ β”‚ └───pages β”‚ β”‚ file.twig β”‚ β”‚ file_content.twig β”‚ └───ext β”‚ └───store β”‚ β”‚ └───pages β”‚ β”‚ └───0001 β”‚ β”‚ file.twig └───pages file.twig 

The file base/0001/pages/file_content.twig has the following:

 {% block page_file %} {% block title %}<h1>Nice title</h1>{% endblock %} {% block price %}{% endblock %} <div class="clearfix"></div> {% endblock %} 

The file base/ext/store/pages/0001/file.twig has the following content:

 {% block price %}<span class="price">55 &euro;</span>{% endblock %} 

And the pages/file.twig has:

 {% block title %}{{ parent() }}<hr>{% endblock %} {% block price %}<div>{{ parent() }}</div>{% endblock %} 

The result that I expect is as follows:

 <h1>Nice title</h1><hr> <div><span class="price">55 &euro;</span</div> <div class="clearfix"></div> 

But with this code, all other file changes are ignored, and the output is performed only as follows:

 <h1>Nice title</h1> <div class="clearfix"></div> 

Note:

It is important to note that I am using Twig 1.33.2 and using the Twig_Autoloader::register(); method Twig_Autoloader::register(); .

I cannot use Twig 2.x, since it requires PHP 7.0+, and I'm limited to PHP 5.3.29.

+5
source share
1 answer

After several attempts, I finally decided how to do it.

It's as ugly as it might seem ...

Assuming structure:

 β”œβ”€β”€β”€base β”‚ β”œβ”€β”€β”€0001 β”‚ β”‚ └───pages β”‚ β”‚ file.twig β”‚ β”‚ file_content.twig β”‚ └───ext β”‚ └───store β”‚ β”‚ └───pages β”‚ β”‚ └───0001 β”‚ β”‚ file.twig └───pages file.twig 

The main file ( base/pages/file.twig ) has the following code:

 {% if data.store_enabled %} {% include [ 'base/ext/store/pages/0001/file.twig', 'base/ext/store/pages/all/file.twig', 'base/pages/file_content.twig' ] ignore missing %} {% else %} {% include [ 'pages/0001/file.twig', 'pages/file.twig', 'base/pages/file_content.twig' ] ignore missing %} {% endif %} 

This will contain the files inside base/ext/store/pages/ , if they exist. If the file is not there, then the file base/pages/file_content.twig .

All files inside base/ext/store/pages/ should have the following code above:

 {% extends [ 'pages/0001/file.twig', 'pages/file.twig', 'base/pages/file_content.twig' ] %} 

And the files inside pages/ should have the following:

 {% extends 'base/pages/file_content.twig' %} 

This allows you to override any block inside base/pages/file_content.twig , and files will only be included / expanded if they exist.

If you have a file with a guarantee (in this case base/pages/file_content.twig should ), it will still display the default content and will not cause an unpleasant exception.


Outside the scope of this answer, I initially found a very similar approach that used conditional values.

Try: https://twigfiddle.com/u06tur

0
source

All Articles