<p>I would use a <a href="https://twig.symfony.com/doc/3.x/tags/macro.html" rel="nofollow noreferrer">macro</a> to output the contents of a single nugget (matrix block), this way you don't have to repeat the <code>include</code> statement multiple times. The only thing you need to keep track of is the current index, i.e. which item is next. You can't do this inside the macro, since a macro can't have persistent state. You have two options:</p>
<ol>
<li>Set up a variable to keep track of the current index and increment it every time you include the macro.</li>
<li>Since you have six predefined positions where nuggets may be displayed, you can just hardcode the index and output the item at that index, if it exists.</li>
</ol>
<h2>Macro definition</h2>
<pre><code>{% macro nugget(nugget = null) %}
    {% if nugget %}
        {% include '_includes/_components/nugget.twig' with {
            self: {
                size: 'xl',
                bgColor: nugget.circleColour.color[0].class,
                iconPath: nugget.icon[0].path,
                body: nugget.nuggetBody[0].bodyPlain
            }
        } %}
    {% endif %}
{% endmacro %}

{% import _self as macros %}
</code></pre>
<p>Having the <code>if</code>-condition inside the macro to handle missing nuggets means you don't have to repeat that if-condition everywhere you want to include a nugget.</p>
<h2>Option 1: Index variable</h2>
<pre><code>{% set nuggets = entry.nuggets
    .with([
        'nugget:nuggetBody',
        'nugget:icon'
    ])
    .all() %}
{% set nuget_index = 0 %}

{# Nugget position #1 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}
</code></pre>
<h2>Option 2: Hardcoded nugget indexes</h2>
<pre><code>{# Nugget position #1 #}
{% include macros.nugget(nuggets[0] ?? null) %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[1] ?? null) %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[2] ?? null) %}
</code></pre>

CC BY-SA 4.0
2021-04-14T17:30:17.607Z
Brilliant approach MoritzLost. I will look at implementing this...Thank you.
Terry Upton
CC BY-SA 4.0
2021-04-13T09:12:06.677Z
2021-04-13T09:12:06.677Z
MoritzLost
<p>There is a better approach by which you can change positions from the admin panel. You need to create a matrix where there will be different <strong>blocks types</strong>, and display them in a loop.
<a href="https://i.sstatic.net/6cqVP.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/6cqVP.png" alt="enter image description here" /></a></p>
<pre><code>{% for block in entry.matrixField.all() %}
   {% switch block.type %}
      {% case 'one' %}
          {{ block.content }}
      {% case 'two' %}
          {{ block.content }}
   {% endswitch %}
{% endfor %}
</code></pre>

CC BY-SA 4.0
2020-11-13T13:45:40.720Z
The problem @PavelPavlovich is that I cannot loop them as they are not all output together. As I said in the post, these items are dotted around the design. So I need to inset the first one (at the top) and then in another part of the page insert the 2nd and 3rd one and then a forth one somewhere else. It is not a case of a simple matrix builder and looping all the items. I already use a matrix field to add these items. It is just if there is a better way ot output them when they are not in a single loop.
Terry Upton
CC BY-SA 4.0
2020-11-15T16:23:48.493Z
@TerryUpton If you have everything scattered dotted across the page, and all the content of the elements is added in a separate matrix, why don't you change their positions from the admin panel or are you already doing this?
Pavel Pavlovich
CC BY-SA 4.0
2020-11-13T08:30:19.103Z
2020-11-13T08:30:19.103Z
Pavel Pavlovich
<p>I have a matrix field that allows the user to add little 'designed' features throughout the page.
These are placed in certain positions on the page and so I want to loop through these but because they are <em>dotted</em> about he page,  I cannot do a simple, for loop.</p>
<p>Instead I could get all the blocks like this:</p>
<pre><code>  {% set nuggets = entry.nuggets
    .with([
    'nugget:nuggetBody',
    'nugget:icon'
  ])
    .all() %}
</code></pre>
<p>Then I could place them like so:</p>
<pre><code>{% set nugget = nuggets[0] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}


{% set nugget = nuggets[1] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}

etc etc
</code></pre>
<p>I wondered if there is a better or more streamlined way than this?
And what happens if they don't have 'enough' blocks, how to accomodate, if for example, I have placed 6 around the page in the design and code, but they only add 4.  I know I could do this...</p>
<pre><code>{% if nuggets|length &gt;= 3 %}
  {% set nugget = nuggets[2] %}
  {% include '_includes/_components/nugget.twig' with {
    self: {
      size:'xl',
      bgColor: nugget.circleColour.color[0].class,
      iconPath:nugget.icon[0].path,
      body: nugget.nuggetBody[0].bodyPlain
    }
  } %}
{% endif %}
etc
</code></pre>
<p>But is there a better approach...?</p>

<templating><matrix><loop>
Getting blocks from matrix and injecting them throughout a page, NOT a single loop statement
# Getting blocks from matrix and injecting them throughout a page, NOT a single loop statement

(Asked by: username_0 on 2020-11-13)

I have a matrix field that allows the user to add little 'designed' features throughout the page.
These are placed in certain positions on the page and so I want to loop through these but because they are dotted about he page,  I cannot do a simple, for loop.
Instead I could get all the blocks like this:
  {% set nuggets = entry.nuggets
    .with([
    'nugget:nuggetBody',
    'nugget:icon'
  ])
    .all() %}

Then I could place them like so:
{% set nugget = nuggets[0] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}


{% set nugget = nuggets[1] %}
{% include '_includes/_components/nugget.twig' with {
  self: {
    size:'xl',
    bgColor: nugget.circleColour.color[0].class,
    iconPath:nugget.icon[0].path,
    body: nugget.nuggetBody[0].bodyPlain
  }
} %}

etc etc

I wondered if there is a better or more streamlined way than this?
And what happens if they don't have 'enough' blocks, how to accomodate, if for example, I have placed 6 around the page in the design and code, but they only add 4.  I know I could do this...
{% if nuggets|length >= 3 %}
  {% set nugget = nuggets[2] %}
  {% include '_includes/_components/nugget.twig' with {
    self: {
      size:'xl',
      bgColor: nugget.circleColour.color[0].class,
      iconPath:nugget.icon[0].path,
      body: nugget.nuggetBody[0].bodyPlain
    }
  } %}
{% endif %}
etc

But is there a better approach...?

**Tags:** templating, matrix, loop


---

## 2 answers

### Answer by username_1 on 2021-04-13. Score: 2 | Accepted answer

I would use a macro to output the contents of a single nugget (matrix block), this way you don't have to repeat the include statement multiple times. The only thing you need to keep track of is the current index, i.e. which item is next. You can't do this inside the macro, since a macro can't have persistent state. You have two options:

Set up a variable to keep track of the current index and increment it every time you include the macro.
Since you have six predefined positions where nuggets may be displayed, you can just hardcode the index and output the item at that index, if it exists.

Macro definition
{% macro nugget(nugget = null) %}
    {% if nugget %}
        {% include '_includes/_components/nugget.twig' with {
            self: {
                size: 'xl',
                bgColor: nugget.circleColour.color[0].class,
                iconPath: nugget.icon[0].path,
                body: nugget.nuggetBody[0].bodyPlain
            }
        } %}
    {% endif %}
{% endmacro %}

{% import _self as macros %}

Having the if-condition inside the macro to handle missing nuggets means you don't have to repeat that if-condition everywhere you want to include a nugget.
Option 1: Index variable
{% set nuggets = entry.nuggets
    .with([
        'nugget:nuggetBody',
        'nugget:icon'
    ])
    .all() %}
{% set nuget_index = 0 %}

{# Nugget position #1 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[nugget_index] ?? null) %}
{% set nugget_index = nugget_index + 1 %}

Option 2: Hardcoded nugget indexes
{# Nugget position #1 #}
{% include macros.nugget(nuggets[0] ?? null) %}

{# Nugget position #2 #}
{% include macros.nugget(nuggets[1] ?? null) %}

{# Nugget position #3 #}
{% include macros.nugget(nuggets[2] ?? null) %}

> **Comments:**
> **username_0**: Brilliant approach username_1. I will look at implementing this...Thank you.  

---

### Answer by username_2 on 2020-11-13. Score: 0

There is a better approach by which you can change positions from the admin panel. You need to create a matrix where there will be different blocks types, and display them in a loop.

{% for block in entry.matrixField.all() %}
   {% switch block.type %}
      {% case 'one' %}
          {{ block.content }}
      {% case 'two' %}
          {{ block.content }}
   {% endswitch %}
{% endfor %}

> **Comments:**
> **username_0**: The problem @PavelPavlovich is that I cannot loop them as they are not all output together. As I said in the post, these items are dotted around the design. So I need to inset the first one (at the top) and then in another part of the page insert the 2nd and 3rd one and then a forth one somewhere else. It is not a case of a simple matrix builder and looping all the items. I already use a matrix field to add these items. It is just if there is a better way ot output them when they are not in a single loop.  
> **username_2**: @TerryUpton If you have everything scattered dotted across the page, and all the content of the elements is added in a separate matrix, why don't you change their positions from the admin panel or are you already doing this?  

---

