<p>You're running into an issue with the way you are setting variables in the processing order. I believe <code>{% block %}</code> tags are processed after all other tags in the template, and then they are processed all at once, with any variables available at that point in time, and the related content in their respective block tags in the parent templates. So while you are creating your <code>slideImg</code> variable higher on the page, the <code>hero</code> and <code>footerJs</code> blocks are not processed from top to bottom on the page, they are processed simultaneously, and independently.</p>

<p>So, when you set <code>{% set slideImg = block.heroImg.first().url %}</code> within your Matrix loop, it's already too late to have that variable available modify the existing <code>slideImg</code> variable that you set outside of the block tags.</p>

<p>There are three approaches I can think of to address the issue:</p>

<ol>
<li>Use <code>set</code> tags instead of <code>block</code> tags</li>
<li>Process your matrix field outside of the <code>block</code> tags higher on the page</li>
<li>Write a plugin to help you out (I won't go into an example of this one here)</li>
</ol>

<h3>1. Use <code>set</code> tags instead of <code>block</code> tags</h3>

<p>While most of the examples in learning Twig use <code>block</code> tags for page layouts, it's less common to see people actually using them in a way that takes advantage of their uniqueness and very frequently you can just swap them out for <code>set</code> tags and get the same result.</p>

<p>For this, you'd need to modify your layout template and page template accordingly.  Here's a simplified example of your code above that should work:</p>

<p><strong>_layout</strong></p>

<pre><code>{% if hero is defined %}
    {{ hero }}
{% endif %}

{% if footerJs is defined %}
    {{ footerJs }}
{% endif %}
</code></pre>

<p><strong>index.html</strong></p>

<pre><code>{% extends "layout" %}

{% set slideImg = "" %}

{% set hero %}
  {% set slideImg = "image.png" %}
{% endset %}

{% set footerJs %}
  {{ slideImg }}
{% endset %}
</code></pre>

<p>I believe in this example, all that you would need to update to use the <code>set</code> tag is the <code>hero</code> block, and if you left the <code>footerJs</code> as a block, things would still work out because you'd be processing the Matrix block within the set tag higher on the page, and the variable would be updated by the time Twig was processing the <code>block</code> tag in your footer.</p>

<h3>2. Process your matrix field outside of the <code>block</code> tags higher on the page</h3>

<p>In this workaround, the goal is to process the variables you need outside of the <code>block</code> tags higher on the page, so the variables you set will be available to all of the <code>block</code> tags on your page when they get processed.</p>

<p>In the simplified example below, I assume your parent template stays the same and uses <code>block</code> tags for <code>hero</code> and <code>footerJs</code>, and set a new variable at the top of the page called <code>{{ heroContent }}</code> where we can loop through our Matrix blocks, set additional variables that are available to us in the page template, and that later gets output farther down the page within the <code>hero</code> block.</p>

<p><strong>index.html</strong></p>

<pre><code>{% extends "_layout" %}

{% set slideImg = "" %}

{% set heroContent %}
    {% for block in entry.hero %}

      {% set slideImg = block.heroImg.first().url %}

      {# Everything else you want to output in your hero block #}

    {% endfor %}
{% endset %}

{% block hero %}
  {{ heroContent }}
{% endblock %}

{% block footerJs %}
  {{ slideImg }}
{% endblock %}
</code></pre>

<p>For a longer discussion of the Twig processing order and there is a related article on Straight Up Craft called <a href="https://straightupcraft.com/articles/twig-processing-order" rel="nofollow">The Twig processing order in Craft templates</a>.</p>

CC BY-SA 3.0
2015-08-23T00:29:21.567Z
2015-08-23T00:29:21.567Z
Ben Parizek
<p>I'm not sure why this isn't working as I set the variable outside the scope of the matrix block. The variable is working inside the matrix block, but not accessible outside of it. What am I missing? </p>

<p><strong>Index template:</strong></p>

<pre><code>{% set slideImg = "" %}

{% block hero %}
    {% for block in entry.hero %}
        {% set slideImg = block.heroImg.first().url %}
    {% endfor %}
{% endblock %}

{% block footerJs %}
    &lt;script&gt;
        $(function() {
            $('#slide-1').backstretch('{{ slideImg }}');
        )};
    &lt;/script&gt;
{% endblock %}
</code></pre>

<p>Update: Full Index template</p>

<pre><code>{% extends "_layout" %}

{% set metaTitle = entry.seoTitle %}
{% set metaDescription = entry.seoDescription %}
{% set metaKeywords = entry.seoKeywords %}

{% set slideImg = "" %}

{% block hero %}
    {% for block in entry.hero %}
        &lt;h2&gt;{{ block.headline|raw }}&lt;/h2&gt;
        {% set slideImg = block.heroImg.first().url %}
        {% set link1 = block.buttonLink1.first() %}
        &lt;a href="{{ link1.url }}" class="btn-gradient"&gt;{{ block.buttonLabel1 }}&lt;/a&gt;
        {% if block.buttonLabel2%}
        {% set link2 = block.buttonLink1.first() %}
        &lt;a href="{{ link2.url }}" class="btn-gradient"&gt;{{ block.buttonLabel2 }}&lt;/a&gt;
        {% endif %}
    {% endfor %}
{% endblock %}

{% block footerJs %}
    &lt;script&gt;
        $(function() {
            $('#slide-1').backstretch('{{ slideImg }}');
        )};
    &lt;/script&gt;
{% endblock %}
</code></pre>

<p><strong>Update #2 _layout</strong></p>

<pre><code>&lt;!DOCTYPE html&gt;
&lt;!--[if lt IE 7]&gt;      &lt;html class="no-js lt-ie9 lt-ie8 lt-ie7"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;         &lt;html class="no-js lt-ie9 lt-ie8"&gt; &lt;![endif]--&gt;
&lt;!--[if IE 8]&gt;         &lt;html class="no-js lt-ie9"&gt; &lt;![endif]--&gt;
&lt;!--[if gt IE 8]&gt;&lt;!--&gt; &lt;html class="no-js"&gt; &lt;!--&lt;![endif]--&gt;
&lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;

    {% block head %}
        &lt;title&gt;{% if metaTitle is defined %}{{ metaTitle }}{% else %}{{ entry.title }}{% endif %}{{siteName}}&lt;/title&gt;
        {% if metaDescription is defined %}&lt;meta name="description" content="{{ metaDescription }}"&gt;{% endif %}
        {% if metaKeywords is defined %}&lt;meta name="keywords" content="{{ metaKeywords }}"&gt;{% endif %}
    {% endblock %}

    &lt;meta name="author" content="@siebird"&gt;

    &lt;link rel="stylesheet" href="/assets/css/normalize.min.css"&gt;
    &lt;link href='http://fonts.googleapis.com/css?family=Arvo:400,400italic|PT+Sans+Narrow:400,700' rel='stylesheet' type='text/css'&gt;
    &lt;link rel="stylesheet" href="/assets/css/styles.css"&gt;

&lt;/head&gt;
&lt;body&gt;
    &lt;!--[if lt IE 7]&gt;
        &lt;p class="browsehappy"&gt;You are using an &lt;strong&gt;outdated&lt;/strong&gt; browser. Please &lt;a href="http://browsehappy.com/"&gt;upgrade your browser&lt;/a&gt; to improve your experience.&lt;/p&gt;
    &lt;![endif]--&gt;
    &lt;div class="header{% if craft.request.firstSegment == '' %} big{% endif %}"&gt;
        &lt;div id="slide{% if craft.request.firstSegment == '' %}-int{% endif %}" class="slide"&gt;
            &lt;div class="row"&gt;
                &lt;h1&gt;{{ general.companyName}}&lt;/h1&gt;

                {% block hero %}

                {% endblock %}

            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div class="nav-bar"&gt;
        &lt;div class="buns"&gt;
            &lt;span&gt;MENU&lt;/span&gt;
            &lt;a href="#" class="hamburger nav-main"&gt;
                &lt;span&gt;&lt;/span&gt;
                &lt;span&gt;&lt;/span&gt;
                &lt;span&gt;&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;ul class="nav nav-main"&gt;
            &lt;li{% if craft.request.firstSegment == '' %} class="active"{% endif %}&gt;&lt;a href="{{ siteUrl }}"&gt;Home&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'who-we-are' %} class="active"{% endif %}&gt;&lt;a href="{{ url('who-we-are') }}"&gt;Who We Are&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'community' %} class="active"{% endif %}&gt;&lt;a href="{{ url('community') }}"&gt;Community&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'floorplans' %} class="active"{% endif %}&gt;&lt;a href="{{ url('floorplans') }}"&gt;Floor Plans&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'energy' %} class="active"{% endif %}&gt;&lt;a href="{{ url('energy') }}"&gt;Energy&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'gallery' %} class="active"{% endif %}&gt;&lt;a href="{{ url('gallery') }}"&gt;Gallery&lt;/a&gt;&lt;/li&gt;
            &lt;li{% if craft.request.firstSegment == 'agents' %} class="active"{% endif %}&gt;&lt;a href="{{ url('agents') }}"&gt;Agents&lt;/a&gt;&lt;/li&gt;
            &lt;li class="nav-btn"&gt;&lt;a href="{{ url('visit') }}"&gt;Schedule a Visit&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    {% block main %}

    {% endblock %}

    &lt;div class="footer"&gt;
        &lt;div class="row"&gt;
            &lt;div class="block-3"&gt;
                &lt;address&gt;{{ general.address }}&lt;br&gt; &lt;a href="{{ general.directions }}" target="_blank"&gt;Get Directions!&lt;/a&gt;&lt;/address&gt;
            &lt;/div&gt;

            &lt;div class="block-3"&gt;
                &lt;p&gt;Contact Us Today&lt;br&gt; &lt;a href="tel:{{ general.phoneNumber }}" class="tel"&gt;{{ general.phoneNumber }}&lt;/a&gt;&lt;/p&gt;
            &lt;/div&gt;

            &lt;div class="block-6"&gt;
                &lt;small&gt;&amp;copy; {{ now.year }} {{ general.companyName }}. All Rights Reserved.&lt;br&gt; &lt;a href="http://siebird.com"&gt;Website design &amp;amp; development by &lt;em&gt;Siebird&lt;/em&gt;&lt;/a&gt;&lt;/small&gt;
                &lt;img src="assets/img/eho.png" class="pull-right" alt="equal housing opportunity" height="51"&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"&gt;&lt;/script&gt;
    &lt;script&gt;window.jQuery || document.write('&lt;script src="assets/js/vendor/jquery-1.10.2.min.js"&gt;&lt;\/script&gt;')&lt;/script&gt;
    &lt;script src="/assets/js/plugins.js"&gt;&lt;/script&gt;
    &lt;script src="/assets/js/application.js"&gt;&lt;/script&gt;

    {% block footerJs %}

    {% endblock %}

  {#
  Google Analytics: change UA-XXXXX-X to be your site's ID.
    &lt;script&gt;
        (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
        function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
        e=o.createElement(i);r=o.getElementsByTagName(i)[0];
        e.src='//www.google-analytics.com/analytics.js';
        r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
        ga('create','UA-XXXXX-X');ga('send','pageview');
    &lt;/script&gt;
    #}

&lt;/body&gt;
&lt;/html&gt;
</code></pre>

CC BY-SA 3.0
2014-09-23T17:30:03.887Z
Are you getting any errors? What's getting output for slideImg here? `$('#slide-1').backstretch('{{ slideImg }}');`  The way your code currently is, the `slideImg` in the footerJs block should be equal to the first `heroImg` URL of the *last* Matrix block in `entry.hero`.
Brad Bell
CC BY-SA 3.0
2014-09-23T18:27:10.393Z
No template errors, just JS error as the `{{ slideImg }}` within the script tag does not parse anything. If I put it within the matrix `for` loop it parse the correct file path. To add context, the matrix can only have one row
Siebird
CC BY-SA 3.0
2014-09-23T18:30:48.650Z
So if you {{ slideImg }} after the {% endfor %} but before the hero {% endblock %} it shows up correctly?
Brad Bell
CC BY-SA 3.0
2014-09-23T18:45:28.807Z
Yep, just tested it and it works
Siebird
CC BY-SA 3.0
2014-09-23T18:58:21.557Z
Hrm... I'm stumped. I think that should work. Something else on the page overwriting it? Maybe you're leaving out some other template code that complicates things?
Brad Bell
CC BY-SA 3.0
2014-09-23T19:06:22.283Z
I'm stumped too. I just posted the full template to the original post. Just starting to convert the static template over to a craft template so there isn't much to it at the moment
Siebird
CC BY-SA 3.0
2014-09-23T19:53:15.787Z
Show in the dark here, but what happens if you put a `{% set slideImg = slideImg %}` right inside of `{% block hero %}` before the for loop?
Brad Bell
CC BY-SA 3.0
2014-09-23T20:00:37.053Z
Nadda. I'll update the thread if I figure out what the issue is
Siebird
CC BY-SA 3.0
2014-09-24T02:25:01.250Z
Can you post your _layout template?
Brandon Kelly
CC BY-SA 3.0
2014-09-24T03:03:16.773Z
Brandon, just updated the original post with the `_layout` template. It's puzzling...
Siebird
<assets><matrix><variable>
Setting Variable inside of Matrix
# Setting Variable inside of Matrix

(Asked by: username_0 on 2014-09-23)

I'm not sure why this isn't working as I set the variable outside the scope of the matrix block. The variable is working inside the matrix block, but not accessible outside of it. What am I missing? 
Index template:
{% set slideImg = "" %}

{% block hero %}
    {% for block in entry.hero %}
        {% set slideImg = block.heroImg.first().url %}
    {% endfor %}
{% endblock %}

{% block footerJs %}
    
{% endblock %}

Update: Full Index template
{% extends "_layout" %}

{% set metaTitle = entry.seoTitle %}
{% set metaDescription = entry.seoDescription %}
{% set metaKeywords = entry.seoKeywords %}

{% set slideImg = "" %}

{% block hero %}
    {% for block in entry.hero %}
        {{ block.headline|raw }}
        {% set slideImg = block.heroImg.first().url %}
        {% set link1 = block.buttonLink1.first() %}
        {{ block.buttonLabel1 }}
        {% if block.buttonLabel2%}
        {% set link2 = block.buttonLink1.first() %}
        {{ block.buttonLabel2 }}
        {% endif %}
    {% endfor %}
{% endblock %}

{% block footerJs %}
    
{% endblock %}

Update #2 _layout




  

    
    
    

    {% block head %}
        {% if metaTitle is defined %}{{ metaTitle }}{% else %}{{ entry.title }}{% endif %}{{siteName}}
        {% if metaDescription is defined %}{% endif %}
        {% if metaKeywords is defined %}{% endif %}
    {% endblock %}

    

    
    
    



    
    
        
            
                {{ general.companyName}}

                {% block hero %}

                {% endblock %}

            
        
    

    
        
            MENU
            
                
                
                
            
        
        
            Home
            Who We Are
            Community
            Floor Plans
            Energy
            Gallery
            Agents
            Schedule a Visit
        
    

    {% block main %}

    {% endblock %}

    
        
            
                {{ general.address }} Get Directions!
            

            
                Contact Us Today {{ general.phoneNumber }}
            

            
                © {{ now.year }} {{ general.companyName }}. All Rights Reserved. Website design & development by Siebird
                
            
        
    

    
    
    
    

    {% block footerJs %}

    {% endblock %}

  {#
  Google Analytics: change UA-XXXXX-X to be your site's ID.
    
    #}

**Tags:** assets, matrix, variable
> **Comments:**
> **username_1**: Are you getting any errors? What's getting output for slideImg here? `$('#slide-1').backstretch('{{ slideImg }}');`  The way your code currently is, the `slideImg` in the footerJs block should be equal to the first `heroImg` URL of the *last* Matrix block in `entry.hero`.  
> **username_0**: No template errors, just JS error as the `{{ slideImg }}` within the script tag does not parse anything. If I put it within the matrix `for` loop it parse the correct file path. To add context, the matrix can only have one row  
> **username_1**: So if you {{ slideImg }} after the {% endfor %} but before the hero {% endblock %} it shows up correctly?  
> **username_0**: Yep, just tested it and it works  
> **username_1**: Hrm... I'm stumped. I think that should work. Something else on the page overwriting it? Maybe you're leaving out some other template code that complicates things?  
> **username_0**: I'm stumped too. I just posted the full template to the original post. Just starting to convert the static template over to a craft template so there isn't much to it at the moment  
> **username_1**: Show in the dark here, but what happens if you put a `{% set slideImg = slideImg %}` right inside of `{% block hero %}` before the for loop?  
> **username_0**: Nadda. I'll update the thread if I figure out what the issue is  
> **username_2**: Can you post your _layout template?  
> **username_0**: Brandon, just updated the original post with the `_layout` template. It's puzzling...  

---

## 1 answers

### Answer by username_3 on 2015-08-23. Score: 3

You're running into an issue with the way you are setting variables in the processing order. I believe {% block %} tags are processed after all other tags in the template, and then they are processed all at once, with any variables available at that point in time, and the related content in their respective block tags in the parent templates. So while you are creating your slideImg variable higher on the page, the hero and footerJs blocks are not processed from top to bottom on the page, they are processed simultaneously, and independently.
So, when you set {% set slideImg = block.heroImg.first().url %} within your Matrix loop, it's already too late to have that variable available modify the existing slideImg variable that you set outside of the block tags.
There are three approaches I can think of to address the issue:

Use set tags instead of block tags
Process your matrix field outside of the block tags higher on the page
Write a plugin to help you out (I won't go into an example of this one here)

1. Use set tags instead of block tags
While most of the examples in learning Twig use block tags for page layouts, it's less common to see people actually using them in a way that takes advantage of their uniqueness and very frequently you can just swap them out for set tags and get the same result.
For this, you'd need to modify your layout template and page template accordingly.  Here's a simplified example of your code above that should work:
_layout
{% if hero is defined %}
    {{ hero }}
{% endif %}

{% if footerJs is defined %}
    {{ footerJs }}
{% endif %}

index.html
{% extends "layout" %}

{% set slideImg = "" %}

{% set hero %}
  {% set slideImg = "image.png" %}
{% endset %}

{% set footerJs %}
  {{ slideImg }}
{% endset %}

I believe in this example, all that you would need to update to use the set tag is the hero block, and if you left the footerJs as a block, things would still work out because you'd be processing the Matrix block within the set tag higher on the page, and the variable would be updated by the time Twig was processing the block tag in your footer.
2. Process your matrix field outside of the block tags higher on the page
In this workaround, the goal is to process the variables you need outside of the block tags higher on the page, so the variables you set will be available to all of the block tags on your page when they get processed.
In the simplified example below, I assume your parent template stays the same and uses block tags for hero and footerJs, and set a new variable at the top of the page called {{ heroContent }} where we can loop through our Matrix blocks, set additional variables that are available to us in the page template, and that later gets output farther down the page within the hero block.
index.html
{% extends "_layout" %}

{% set slideImg = "" %}

{% set heroContent %}
    {% for block in entry.hero %}

      {% set slideImg = block.heroImg.first().url %}

      {# Everything else you want to output in your hero block #}

    {% endfor %}
{% endset %}

{% block hero %}
  {{ heroContent }}
{% endblock %}

{% block footerJs %}
  {{ slideImg }}
{% endblock %}

For a longer discussion of the Twig processing order and there is a related article on Straight Up Craft called The Twig processing order in Craft templates.


---

