Global Twig Variables

I’m battling with this simple requirement with Twig.

I want to define a twig variables at the begining of a theme layouts, so that I can reuse this variable in different other partials like so:

#account_layout.htm

<body>
    {% partial 'account/menu_definition' %}
...
   {% partial 'account/dropdown_menu` %}
   {% partial 'account/menu` %}
...

#account/menu_definition

{% 
    set account_menu = {
        ...
        ...
        ...
   }

%}

#account/desktop_menu

{{ account_menu | map((menu ) => "<a>{{ menu.title }} </a>" | join('') | raw }}

#account/menu

{{ account_menu | map((menu ) => "<a>{{ menu.title }} </a>" | join('') | raw }}

but twig error is raised saying that

The "map" filter expects a sequence or a mapping and indeed account_menu is null inside account/menu and account/desktop_menu

any suggestions on how best to proceed guys ?

Hi @chris,

Maybe the variable account_menu should be set in account_layout.htm:

{% 
    set account_menu = {
        ...
        ...
        ...
    } 
%}

And then, it can be used in the partials “menu_definition”, “desktop_menu”…

yes this works if I defined the variable inside the layout, but I am trying to reuse the variable in another layout as well, hence trying to set it inside a reusable partial.

Hi @chris,

If the variable is what’s important (rather than the partial itself), do hooking into an event like page.beforeDisplay or cms.page.init would be an option?

Hi @apinard

thanks, I thought about that as well, that would need a refactoring of the twig code into php code, as the twig variables builds link, translated text based on many different permissions and settings.

in the spirit of DRY, that would be the best option.

I aslo tried to play around using placeholder and put but couldnt make it work.

Placeholders should be a viable solution. Did you move the ‘account_definition’ partial to the end of your layout? I think the placeholders need to be defined before you can use ‘put’.

Another options might be a macro, but that will probably mean that your menu needs to be built/calculate for each instance. You could circumvent this with the cache tag - but I’m not sure if this is supported and then you’ll have to deal with a cache…