2

In each matrix block, I'm allowing users to set a background image, background color etc with a settings field.

In each matrix block template, I have:

{% block content %}

  {% set backgroundColor = '' %}
  {% set backgroundImage = '' %}

  {% for row in block.settings %}
    {% set backgroundColor %}background-color: {{ row.backgroundColor }};{% endset %}
    {% set backgroundImage %}background-image: url({{ row.backgroundImage.first().url }});{% endset %}
    ... more fields go here...
  {% endfor %}

  <div style="{{ backgroundColor }} {{ backgroundImage }}">
    ... content here ...
  </div>

{% block content %}

Rather than repeating {% for row in block.settings %} in each template, is there a way that I could write it once and reuse it using a single include call?

I could use

{% include "_widgets/_settings" with { 
  backgroundColor: backgroundColor,
  backgroundImage: backgroundImage
} %}

But that doesn't really reduce the amount of code duplication. Ideally I like to use a single of code to make these variables available.

  • Hi Anna, how are you looping through your Matrix block templates? Do you have something like {% include '_partials/blocks' ~ block.type %} dynamically including each block template that you have the above code in? Also, how does the {% block content %} tag fit into your template picture? The block tag is typically used to override code in a parent template that is being extended, but you seem to be using it for Matrix Blocks in some way. Can you clarify how the block templates relate to the loop of matrix blocks and how the block tag is being used on the page? – Ben Parizek Aug 20 '15 at 13:55
3

Take 2:

I think you may be looking to use a Twig Macro. Here's the gist of that approach, but I don't fully understand the layout of your template yet, so my answer may be a bit out of context until I do.

You'll need to create your macro higher in your template or in a separate file and import it into the template you are working in. (See the docs linked above on how to import a macro for your situation.)

You could then simplify your block output to something like this. I'm using fairly verbose names for this example but you can shorten the variable names to have less code if you prefer.

{% import "_widgets/_settings.html" as settingsMacro %}
{% set settings = block.settings %}

<div style="{{ settingsMacro.backgroundColor(settings) }} {{ settingsMacro.backgroundImage(settings) }}">
  ... content here ...
</div>

In your macro file, you'll take those settings and process them as you need to:

_widgets/_settings.html

{% macro backgroundColor(settings) %}
  {% set backgroundColor = '' %}

  {% for row in settings %}
    background-color: {{ row.backgroundColor }};
  {% endfor %}
{% endmacro %}

{% macro backgroundImage(settings) %}
  {% set backgroundImage = '' %}

  {% for row in settings %}
    background-image: url({{ row.backgroundImage.first().url }});
  {% endfor %}
{% endmacro %}

I think, due to how many matrix blocks are fairly short templates, the amount of code you may need to avoid reuse still may be a couple lines after you import a macro and call the specific macros. But like the include, this could be another way to help ensure consistency in the code being used in multiple places. Hopefully this gives you a few more ideas to work with to find a satisfying solution. I'd need to have a better understanding of your full template picture to offer a more specific solution on how to implement.


Take 1:

If I understand correctly, I believe one way you can do what you are trying to do is by using the include with syntax and making sure you are passing your variables to the include template:

{% include "_widgets/_settings" with { 
  backgroundColor: backgroundColor,
  backgroundImage: backgroundImage
} %}

This assumes that you are defining backgroundColor and backgroundImage before your include, and that the include has the following code:

<div style="{{ backgroundColor }} {{ backgroundImage }}">
 ... content here ...
</div>

Also note, adding the underscore to your folder path hides all files within it. So, if you don't want to have to add underscores in front of every file, you still have hidden files if they are within a hidden folder, i.e: _widgets/settings

  • Unfortunately that doesn't really simplify the code much. Thank you anyway. – Leah Aug 20 '15 at 3:53
  • 1
    Aside from simplification, does it make the code work and solve the Variable "backgroundColor" does not exist error? Your example is broken up over several code blocks and it's not exactly clear what the relationship is between the block templates and include you describe is. It's likely a Twig macro or more dynamic use of includes can help, but hard to offer a solution in your context without a better understanding of the full picture in the templates. – Ben Parizek Aug 20 '15 at 5:05
  • See updated post. Does that make it clearer? – Leah Aug 20 '15 at 6:43
  • Hi @Anna, I've taken another shot and updated my answer to discuss Twig Macros as well. – Ben Parizek Aug 20 '15 at 14:25
  • Take 2 was exactly what I was after. I've read up on macros to further extend your code. Thank you! – Leah Aug 26 '15 at 10:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.