Any hack to get around "{% include %}" not supporting variables?

Hi everyone =)

This is what I currently have :

{% set card_type = section.extra.card_type | default(value="simple") %}
   {% if card_type == "simple" -%}
      {%- include "cards/simple.html" -%}
   {% elif card_type == "featured" -%}
      {%- include "cards/featured.html" -%}
   {% else -%}
      <p>Unknown Card Type 🤷</p>
{% endif -%}

I’d like to be able to include a template based on a variable. Does anyone know how to do that ?

I’ve tried to use load_data() (and successfully gathered and printed the appropriate template content) but {{ variables }} inside said template don’t seem to be parsed this way…

Any help would be greatly appreciated !

What do you see when you run this? Out of the 3 options from the if, elif, else, which of them gets rendered?

Well it depends on the initial value of section.extra.card_type. The snippet above works as intended.
What I’d like to do is something like this :

{% set card_type = section.extra.card_type | default(value="simple") %}
{%- include "cards/" ~ card_type ~ ".html" -%}

So that users of my theme are able to implement new card types with no macro-related change required (this snippet is inside a macro).

Here’s a link to the complete code if it helps understanding what I’m trying to achieve : https://gitlab.com/cyril-marpaud/hayflow/-/blob/main/templates/macros.html#L14

Ok, so when you run that code snippet what’s the result?

It depends on the value of section.extra.card_type :

  • simple → cards/simple.html is rendered
  • featured → cards/featured.html is rendered
  • anything else → “<p>Unknown Card Type 🤷</p>” is rendered.

Ok, I there’s been some misunderstanding on my part, sorry about that. I was asking about the output of your include snippet that used concatenating with a variable, because I couldn’t run any code from my phone and your first code snippet looked fine, so I wasn’t sure which one was broken or what error you were seeing.

Anyways, no I don’t think there’s a hack around it if your requirement is that you must be using include, because, as you probably know, it requires a string literal as an argument. Your if/elif/else chain could be put into a macro or shortcode, and whenever you add a new card template, you could just add to the chain. The macro can accepts arguments, so you can pass in your card_type there as well, and just referencing your macro from the rest of your code is more or less as concise as using include + a variable.

Otherwise, I’m having a hard time of thinking of anything that’s more generic or dynamic. Hope that helps.

That’s actually exactly what I’m doing, the snippet is already inside a macro.
But adding a new card_type requires macro editing and I’d like to avoid that.
I understand the limitation of include though, I just hoped there would be some kind of workaround.
Thx for the help anyway :wink:

My pal spongebob would say, 11 months later…

I use macros opposed to including various files for this situation. (not knowing the full details)
Also they do accept variables. in the example i pass page but it could be section and config if needed.

Ive used the macro capability to create widgety doodads for resuable elements.

macro/cards.html

{% macro simple_card(page, config) %}
page.title
SIMPLE CARD
{% endmacro simple_card %}

{% macro simple_card(page, config) %}
page.title
FEATURED CARD
{% endmacro simple_card %}

And then use it within the template as such

{% import "macros/cards.html as cards %}

{% set card_type = section.extra.card_type | default(value="simple") %}
   {% if card_type == "simple" -%}
      {{ cards.simple(page=page, config=config)}}}
   {% elif card_type == "featured" -%}
      {{ cards.simple(page) }}
   {% else -%}
      {{cards.unknown(page=page, config=config) }}
{% endif -%}
1 Like