<p>Using <code>macro</code> command you can replace the <code>set</code> command, avoiding the disadvantage of long code every time you need to call a variable. I had the same need, and my solution is:</p>
<p>Parent template &quot;main.twig.html&quot;:</p>
<pre><code>{% import &quot;constants.twig&quot; as constants %}
var priceA = {{ constants.priceA }}
</code></pre>
<p>Child template &quot;constants.twig&quot;:</p>
<pre><code>{% macro priceA () %}   15.10   {% endmacro %}
{% macro priceB () %}   26.20   {% endmacro %}
{% macro priceC () %}   30.40   {% endmacro %}
</code></pre>
<p>This is nice and simple to read AND short to write whenever you need to call a variable.</p>
<p><strong>[EDIT 2022-05-18]</strong></p>
<p>Here it is a full working example for file &quot;main.twig.html&quot;:</p>
<pre><code>{% import &quot;constants.twig&quot; as constants %}
&lt;html&gt;&lt;body&gt;
&lt;div id=&quot;tot&quot;&gt;&lt;/div&gt;
    &lt;script&gt;
        let quantity_A = 3, quantity_B = 5;
        let total_amount = {{ constants.priceA }} * quantity_A  + {{ constants.priceB }} * quantity_B ;
        document.getElementById(&quot;tot&quot;).innerHTML = total_amount; // Result will be 176.3
    &lt;/script&gt;
&lt;/body&gt;&lt;/html&gt;
</code></pre>

CC BY-SA 4.0
2019-08-24T00:07:05.610Z
This is my preferred solution because then you can access the variable from inside another macro.
kmgdev
CC BY-SA 4.0
2022-05-13T10:15:16.120Z
Problem is a number or boolean is a string, so "false" would equate to true :(
iamkeir
CC BY-SA 4.0
2022-05-16T08:20:13.613Z
@iamkeir I am not clear what you are referring to. Your comment does not seem to apply to my code.
Kar.ma
CC BY-SA 4.0
2022-05-17T09:35:54.583Z
@Kar.ma sorry, to be more clear, macros can only return values as strings, so 15.10, for example, will return as a string not a number, so you can't do math logic with it. You'd need to do `{{ constants.priceA | number }}`. Annoying limitation of macros. Just thought important to point out for people. Equally if return "false", it'll be a string of "false", not a boolean of false, and the string of "false" will actually return as boolean true.
iamkeir
CC BY-SA 4.0
2022-05-17T09:36:30.540Z
@Kar.ma I do actually use the macro approach for constants/functions myself, but have to workaround the string limitation.
iamkeir
CC BY-SA 4.0
2022-05-18T13:25:12.450Z
@iamkeir Macros don't act any differently than other Twig commands, at least in my experience. I have no need to work around any string limitation. I don't know how you are testing my code, so I edited my answer so that following my example could be easier.
Kar.ma
CC BY-SA 4.0
2022-05-19T14:07:36.273Z
@Kar.ma Macros can only return strings (well, a Twig markup object containing the resultant string) so the problem is thus: `{{ constants.priceA * 2 }}` results in `TypeError - Unsupported operand types: Twig\Markup * int`. To fix, `{{ constants.priceA|number * 2 }}`. This is not criticism of your code, it's a "heads up" to people using this approach. Your maths is of course working as you are doing it in Javascript, not Twig.
iamkeir
CC BY-SA 4.0
2019-01-22T17:39:42.490Z
2022-05-18T13:20:10.630Z
2022-05-18T13:20:10.630Z
Kar.ma
<p>Another option would be to create a small plugin with a variables file dedicated to storing this data. </p>

<pre><code>class MyPluginVariable {

    public function exampleVariable($optional = null)
    {
        return "Return anything you want.";
    }

}
</code></pre>

<p>Then in your template, you can just use:</p>

<pre><code>{{ craft.myPlugin.exampleVariable }}
</code></pre>

CC BY-SA 3.0
2014-12-17T16:59:16.920Z
2014-12-17T17:22:01.003Z
2014-12-17T17:22:01.003Z
Douglas McDonald
<p>It looks like another good solution is to use a <a href="http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail" rel="nofollow">template hook</a>. I just became aware of these, but they look very useful for this type of thing.</p>

CC BY-SA 3.0
2014-12-18T13:35:21.273Z
2014-12-18T13:35:21.273Z
Tim Kelty
<p>Use macros in your <strong>variables.html</strong>:</p>

<pre><code>{% macro myMacro(param1, param2) %}
  {{param1}} / {{param2}}
{% endmacro %}`
</code></pre>

<p>Put this in your <strong>layout.html</strong>:</p>

<p><code>{% import 'folder/to/variables' as helpers %}</code></p>

<p>and then in your partials:</p>

<p><code>{{helpers.myMacro(param1, param2)}}</code></p>

CC BY-SA 3.0
2018-02-26T16:57:14.640Z
2018-02-26T16:57:14.640Z
elf acht


<p>There are actually two issues with this approach. The first, and the direct reason you’re getting that Twig error, is that templates that extend another template can only output things within <code>{% block %}</code> tags. Any HTML that gets output outside of those tags (either directly or via <code>{{ output tags }}</code>) will result in that Twig error.</p>

<p>The <code>{% include %}</code> tag is in the same boat. Its only purpose (as far as the parent template is concerned) is to output the results of a child template. So like <code>{{ output tags }}</code>, you can’t place it outside of <code>{% block %}</code> tags. If you really want to include a template within these nested templates, you will need to move it to within your <code>{% block %}</code>.</p>

<p>Even if you did that, though, you’d then run into the second issue: Any variables that are set/modified within an included template will <strong>not</strong> bubble back up to the parent template. For example, if you had these two templates:</p>

<ul>
<li><p>parent template:</p>

<pre class="lang-twig prettyprint-override"><code>{% include "_inc" %}
{{ foo }}
</code></pre></li>
<li><p>child template (_inc.html):</p>

<pre class="lang-twig prettyprint-override"><code>{% set foo = 'bar' %}
</code></pre></li>
</ul>

<p>That <code>foo</code> variable would actually be discarded as soon as Twig was finished rendering _inc.html; nothing that happens in there will have any effect on the parent template. (As I said, the <strong>only</strong> purpose of the <code>{% include %}</code> tag as far as the parent template is concerned is to output the rendering result of the included template.)</p>

<p><em>However,</em> it’s still probably possible to achieve what you want when you consider the order in which these templates are going to be processed:</p>

<ol>
<li>Everything <em>besides</em> the <code>{% block %}</code> tags in the requested template (the one with the <code>{% extends %}</code> tag)</li>
<li>The layout template (_layouts/default.twig), <em>including</em> its <code>{% block %}</code> tags</li>
<li>The requested template’s <code>{% block %}</code> tags</li>
</ol>

<p>Knowing that, you can probably just set your variables you’re trying to set from within _layouts/default.twig, and they will be available within the requested template’s <code>{% block %}</code> tags.</p>

<ul>
<li><p>requested template:</p>

<pre class="lang-twig prettyprint-override"><code>{% extends '_layouts/default.twig' %}

{% block content  %}
    {{ foo }}
{% endblock %}
</code></pre></li>
<li><p>layout template (_layouts/default.twig):</p>

<pre class="lang-twig prettyprint-override"><code>{# Set the variables you were trying to set in _resources/variables.twig #}
{% set foo = 'bar' %}

{% block content %}
{% endblock %}
</code></pre></li>
</ul>

CC BY-SA 3.0
2014-12-18T09:22:09.977Z
You could wrap the whole page in a single block (for example named "HTML") in _layouts/default.twig and extend the variables template using `{% extends '_resources/variables.twig' %}`. This allows you to separate variables and layout HTML.
carlcs
CC BY-SA 3.0
2014-12-24T13:21:36.963Z
Brandon, that solution doesn't work for me when trying to set variables from an entry. I have a need to set meta data from the current entry on ALL pages, so I've tried this layout: https://gist.github.com/russback/230310fe4c8f849958bb. However the data doesn't get rendered. Am I missing something? In my partials/_global_header.html template I am attempting the output those variables. @carics, I don't follow your suggestion - do you have an example?
Russ Back
CC BY-SA 3.0
2014-12-24T15:25:31.807Z
@RussBack That’s not quite the same question. Can you please post a new one?
Brandon Kelly
CC BY-SA 3.0
2014-12-24T21:09:49.387Z
Brandon, thanks. Done at http://craftcms.stackexchange.com/questions/5400/how-can-i-globally-set-variables.
Russ Back
CC BY-SA 3.0
2014-12-17T17:02:59.813Z
2014-12-17T17:02:59.813Z
Brandon Kelly
<p>I'm essentially looking for a way to have a template that runs through a bunch of <code>set</code>s that I might use throughout my templates.</p>

<p>The problem is, if I <code>include</code> in a template with an <code>extends</code>, it dies up with:</p>

<blockquote>
  <p>A template that extends another one cannot have a body.</p>
</blockquote>

<pre><code>{% include '/_resources/variables.twig' %}
{% extends '/_layouts/default.twig' %}
</code></pre>

<p>Some research indicates that maybe this isn't easily done with Twig parsing alone:
<a href="https://stackoverflow.com/questions/20410194/use-twig-custom-set-variables-from-an-include">https://stackoverflow.com/questions/20410194/use-twig-custom-set-variables-from-an-include</a>
<a href="https://groups.google.com/forum/#!topic/twig-users/QKdpWAxLdjE" rel="noreferrer">https://groups.google.com/forum/#!topic/twig-users/QKdpWAxLdjE</a></p>

<p>So, what would be the best way to achieve this? My initial thought would be a plugin that you gave the path of a template, which preloaded things into variables.</p>

<p>I realize some variables (strings) could be done via macros. But, for example, I have a <code>set usStates = {...}</code> that is a big hash of state codes and names.</p>

<templating><include>
Include a template that sets variables (global template variables)
# Include a template that sets variables (global template variables)

(Asked by: username_0 on 2014-12-17)

I'm essentially looking for a way to have a template that runs through a bunch of sets that I might use throughout my templates.
The problem is, if I include in a template with an extends, it dies up with:

A template that extends another one cannot have a body.

{% include '/_resources/variables.twig' %}
{% extends '/_layouts/default.twig' %}

Some research indicates that maybe this isn't easily done with Twig parsing alone:
https://stackoverflow.com/questions/20410194/use-twig-custom-set-variables-from-an-include
https://groups.google.com/forum/#!topic/twig-users/QKdpWAxLdjE
So, what would be the best way to achieve this? My initial thought would be a plugin that you gave the path of a template, which preloaded things into variables.
I realize some variables (strings) could be done via macros. But, for example, I have a set usStates = {...} that is a big hash of state codes and names.

**Tags:** templating, include

---

## 5 answers

### Answer by username_6 on 2014-12-17. Score: 18 | Accepted answer

There are actually two issues with this approach. The first, and the direct reason you’re getting that Twig error, is that templates that extend another template can only output things within {% block %} tags. Any HTML that gets output outside of those tags (either directly or via {{ output tags }}) will result in that Twig error.
The {% include %} tag is in the same boat. Its only purpose (as far as the parent template is concerned) is to output the results of a child template. So like {{ output tags }}, you can’t place it outside of {% block %} tags. If you really want to include a template within these nested templates, you will need to move it to within your {% block %}.
Even if you did that, though, you’d then run into the second issue: Any variables that are set/modified within an included template will not bubble back up to the parent template. For example, if you had these two templates:

parent template:
{% include "_inc" %}
{{ foo }}

child template (_inc.html):
{% set foo = 'bar' %}


That foo variable would actually be discarded as soon as Twig was finished rendering _inc.html; nothing that happens in there will have any effect on the parent template. (As I said, the only purpose of the {% include %} tag as far as the parent template is concerned is to output the rendering result of the included template.)
However, it’s still probably possible to achieve what you want when you consider the order in which these templates are going to be processed:

Everything besides the {% block %} tags in the requested template (the one with the {% extends %} tag)
The layout template (_layouts/default.twig), including its {% block %} tags
The requested template’s {% block %} tags

Knowing that, you can probably just set your variables you’re trying to set from within _layouts/default.twig, and they will be available within the requested template’s {% block %} tags.

requested template:
{% extends '_layouts/default.twig' %}

{% block content  %}
    {{ foo }}
{% endblock %}

layout template (_layouts/default.twig):
{# Set the variables you were trying to set in _resources/variables.twig #}
{% set foo = 'bar' %}

{% block content %}
{% endblock %}

> **Comments:**
> **username_7**: You could wrap the whole page in a single block (for example named "HTML") in _layouts/default.twig and extend the variables template using `{% extends '_resources/variables.twig' %}`. This allows you to separate variables and layout HTML.  
> **username_8**: Brandon, that solution doesn't work for me when trying to set variables from an entry. I have a need to set meta data from the current entry on ALL pages, so I've tried this layout: https://gist.github.com/russback/230310fe4c8f849958bb. However the data doesn't get rendered. Am I missing something? In my partials/_global_header.html template I am attempting the output those variables. @carics, I don't follow your suggestion - do you have an example?  
> **username_6**: @RussBack That’s not quite the same question. Can you please post a new one?  
> **username_8**: Brandon, thanks. Done at http://craftcms.stackexchange.com/questions/5400/how-can-i-globally-set-variables.  

---

### Answer by username_1 on 2019-01-22. Score: 5

Using macro command you can replace the set command, avoiding the disadvantage of long code every time you need to call a variable. I had the same need, and my solution is:
Parent template "main.twig.html":
{% import "constants.twig" as constants %}
var priceA = {{ constants.priceA }}

Child template "constants.twig":
{% macro priceA () %}   15.10   {% endmacro %}
{% macro priceB () %}   26.20   {% endmacro %}
{% macro priceC () %}   30.40   {% endmacro %}

This is nice and simple to read AND short to write whenever you need to call a variable.
[EDIT 2022-05-18]
Here it is a full working example for file "main.twig.html":
{% import "constants.twig" as constants %}

> **Comments:**
> **username_2**: This is my preferred solution because then you can access the variable from inside another macro.  
> **username_3**: Problem is a number or boolean is a string, so "false" would equate to true :(  
> **username_1**: @iamkeir I am not clear what you are referring to. Your comment does not seem to apply to my code.  
> **username_3**: @Kar.ma sorry, to be more clear, macros can only return values as strings, so 15.10, for example, will return as a string not a number, so you can't do math logic with it. You'd need to do `{{ constants.priceA | number }}`. Annoying limitation of macros. Just thought important to point out for people. Equally if return "false", it'll be a string of "false", not a boolean of false, and the string of "false" will actually return as boolean true.  
> **username_3**: @Kar.ma I do actually use the macro approach for constants/functions myself, but have to workaround the string limitation.  
> **username_1**: @iamkeir Macros don't act any differently than other Twig commands, at least in my experience. I have no need to work around any string limitation. I don't know how you are testing my code, so I edited my answer so that following my example could be easier.  
> **username_3**: @Kar.ma Macros can only return strings (well, a Twig markup object containing the resultant string) so the problem is thus: `{{ constants.priceA * 2 }}` results in `TypeError - Unsupported operand types: Twig\Markup * int`. To fix, `{{ constants.priceA|number * 2 }}`. This is not criticism of your code, it's a "heads up" to people using this approach. Your maths is of course working as you are doing it in Javascript, not Twig.  

---

### Answer by username_4 on 2014-12-17. Score: 4

Another option would be to create a small plugin with a variables file dedicated to storing this data. 
class MyPluginVariable {

    public function exampleVariable($optional = null)
    {
        return "Return anything you want.";
    }

}

Then in your template, you can just use:
{{ craft.myPlugin.exampleVariable }}


---

### Answer by username_0 on 2014-12-18. Score: 2

It looks like another good solution is to use a [template hook](http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail). I just became aware of these, but they look very useful for this type of thing.


---

### Answer by username_5 on 2018-02-26. Score: 1

Use macros in your variables.html:
{% macro myMacro(param1, param2) %}
  {{param1}} / {{param2}}
{% endmacro %}`

Put this in your layout.html:
{% import 'folder/to/variables' as helpers %}
and then in your partials:
{{helpers.myMacro(param1, param2)}}


---

