Reputation: 642
The problem:
Consider that I have a sequence of mix of HTML/PHP code, pseudo code given bellow:
<html>
<section 1> ... </section 1>
<section 2> ... </section 2>
<section 3> ... </section 3>
</html>
Note that sections are just blocks of HTML/PHP code, details are not important.
However, for reason which is not important to story, I want to render code in section 3 and 2 first, then in section 1. In traditional PHP/HTML, I would achieve that by using anonymous functions:
<?php $buff = []; ?>
<?php $buff[] = function() { ?>
<html>
<?php }; ?>
<?php $buff[] = function() { ?>
<section 1> </section 1>
<?php }; ?>
<?php $buff[] = function() { ?>
<section 2> </section 2>
<?php }; ?>
<?php $buff[] = function() { ?>
<section 3> </section 3>
<?php }; ?>
<?php $buff[] = function() { ?>
</html>
<?php }; ?>
<?php
for ($i = count($buff)-1; $i >= 0; $i--) {
$buff[$i] = call_user_func($buff[$i]);
}
foreach($buff as $b) echo $b;
?>
So you get the idea, I would control the order of rendering via anonymous functions. Note that non of the sections depends on results of execution of previous section.
In order to achieve the stated -> idea is to use Twig's Node visitor. Of course, these anonymous function would have a reference to $context and $blocks variables:
function () use ($context, $blocks) {
...
}
This is quite double, now, question is: is there a better way and is there some potential hazard that I am missing?
Note that
<?php
for ($i = 0; $i < count($buff); $i++) {
$buff[$i] = call_user_func($buff[$i]);
}
foreach($buff as $b) echo $b;
?>
Should produce same result as sequential order of code execution, i.e. as we didn't modified template.
Now, this would be used only if specific tag is detected on the template, and purpose of this reordering of execution is to ensure that even though this tag is on top of the template -> to be executed last but displayed on top.
There is no other workaround -> it has to be like that, executed last, displayed on top.
Thank you
Upvotes: 0
Views: 1191
Reputation: 48865
Not sure I completely understand your requirements but it sounds like you basically want to sort your sections before rendering them? If so then a simple twig extension would do the trick.
// Controller
$sections = [ $section1, $section2, $section3];
// Twig
{% for section in sections | section_reorder %}
// Twig extension http://symfony.com/doc/current/cookbook/templating/twig_extension.html
public function sectionReorderFilter($sections)
{
// Adjust the order of the sections as needed
return $sectionsReordered;
If your reordering algorithm needs additional information then use a function instead of a filter. Same basic idea.
On the other hand, I might not have any idea as to what you asking.
Upvotes: 1