Search code examples
twigweb-componentsilextemplatingamp-html

How to push values to array in templates and partials to output them in layout?


We are using Twig as our templating engine but I'm stuck with a problem of the rendering order now. See - https://straightupcraft.com/articles/twig-processing-order

We are using amp for our new site and with amp and web components in general it is necessary to import the components (once) to use them. So the idea was to create a Twig Extension to accomplish exactly this. Everytime a component is used it is called via this twig function call. The function is checking the component, adding it to a stack and you can use it from now on. The stack then is transformed into a list of imports for the head of the page.

The problem here is Twigs top to bottom rendering. When I call said function in a partial or a template the rendering of "layout.twig" already took place and all function calls below/after are not affecting the stack.

Is there an option to change the rendering to inside out, so that the rendering is first using the lowest partial and "bubbles" up to templates and finally layout without them rendering before? Another way to get the values in layout would nice as well.

Desired behavior:

Layout.twig

{{ getAllComponents() }}
{# should output component1 and component2 #}
{% block content %}

Page.twig

{% extends Layout.twig %}
{{ addComponent('component1') }}
{% include partials.twig %}
<component1>...</component1>

partials.twig

{{ addComponent('component2') }}
<component2>...</component2>

Actual behavior:

Layout.twig

{{ getAllComponents() }}
{# is empty #}

Solution

  • There is no option to change this behavior. However you can use a trick to archive this: Render your content to a variable before you call getAllComponents()

    layout.twig

    {% set mainContent %}
        {% block content %}{% endblock %}
    {% endset %}
    
    {{ getAllComponents() }}
    
    {{ mainContent }}