<p>With Craft 3 and/or Twig, there is a nice easy way to manage this now.</p>
<p>To output environment variables, config variables, globals, etc you can use <code>{{ view.renderString(entry.richText) }}</code>, the <a href="https://docs.craftcms.com/api/v3/craft-web-view.html#method-renderstring" rel="nofollow noreferrer">renderString</a> method will parse a template as a string.</p>
<p>There is also Twig's <a href="https://twig.symfony.com/doc/3.x/functions/template_from_string.html" rel="nofollow noreferrer">template_from_string()</a> which allows you to parse any text as a Twig template, with access to variables, as well. Compared to renderString it works with include, extends &amp; embed to if you need that</p>
<p><code>{{ include(template_from_string(entry.richText)) }}</code></p>
<p>These are both useful cleaner ways than what is discussed above.
I have since moved away from the complicated way of having to do it in Craft 2 and used these cleaner methods in Craft 3.</p>

CC BY-SA 4.0
2020-09-16T23:35:54.930Z
2020-09-16T23:35:54.930Z
zizther
<p>You can use my <a href="https://github.com/lindseydiloreto/craft-filterenvvar" rel="nofollow"><strong>Filter Environment Variables</strong></a> plugin, which will get you about half-way there. It will automatically parse out any environment variables which show up in your dynamic fields...</p>

<pre><code>{{ entry.myField | envvar }}
</code></pre>

<hr>

<p>Once you've got that installed, it's fairly easy to adjust the logic to accommodate for globals as well.</p>

<p>Go to <code>/filterenvvar/twigextensions/FilterEnvVarTwigExtension.php</code>, and change this:</p>

<pre class="lang-php prettyprint-override"><code>public function envvar($string)
{
    return craft()-&gt;config-&gt;parseEnvironmentString($string);
}
</code></pre>

<p>... to this:</p>

<pre class="lang-php prettyprint-override"><code>public $globals = array();

public function __construct()
{
    foreach (craft()-&gt;globals-&gt;allSets as $globalSet)
    {
        foreach ($globalSet-&gt;content-&gt;attributes as $field =&gt; $value)
        {
            $this-&gt;globals[$globalSet-&gt;handle.'.'.$field] = $value;
        }
    }
}

public function envvar($string)
{
    $string = craft()-&gt;config-&gt;parseEnvironmentString($string);
    $string = $this-&gt;parseGlobals($string);
    return $string;
}

public function parseGlobals($string)
{
    foreach ($this-&gt;globals as $key =&gt; $value)
    {
        $string = str_replace('{'.$key.'}', $value, $string);
    }

    return $string;
}
</code></pre>

<p>This gives you the ability to parse global variables, in addition to your environment variables.</p>

<p>For your global variables, you'll need to include the global set <strong>handle</strong> in the token name:</p>

<pre><code>my global field value is {globalSetHandle.fieldHandle}
</code></pre>

<p>This allows multiple global sets to use the same field.</p>

CC BY-SA 3.0
2015-10-22T18:11:36.037Z
Great work @LindseyD
zizther
CC BY-SA 3.0
2015-10-25T14:39:56.780Z
this works great for global variables, but not working for environment variables. I have tried with single and double curly brackets. Any thoughts?
zizther
CC BY-SA 3.0
2015-10-25T17:33:05.740Z
@zizther: Make sure you use single curly braces, with **no padding spaces**. Like this: `{myVar}`
Lindsey D
CC BY-SA 3.0
2015-10-25T17:36:50.700Z
I have tested that way, but it doesn't seem to work. I am trying {siteName} and {basePath}. Example usage {{ entry.title | envvar }}
zizther
CC BY-SA 3.0
2015-10-25T17:38:37.010Z
I tested this answer before posting it, so it _should_ work... DM me on Slack, and we can work through it. We'll post the results back here on this thread for future readers. :)
Lindsey D
CC BY-SA 3.0
2015-10-22T18:02:09.173Z
2015-10-22T18:02:09.173Z
Lindsey D
<p>You could enable your client to use <a href="http://buildwithcraft.com/docs/reference-tags" rel="nofollow">Reference Tags</a> by adding the <a href="http://buildwithcraft.com/docs/reference-tags" rel="nofollow"><code>parseRefs</code></a> filter.</p>

<pre><code>{% set str = '&lt;p&gt;Since {globalset:42:yearEstablished}&lt;/p&gt;' %}
{{ str|parseRefs|raw }}
</code></pre>

<p>But this would enable them to access field values of (almost) any element (entries, assets, tags, ..), not just from global sets.
And they would also have to remember the global set's ID.</p>

<p>So your current <a href="http://buildwithcraft.com/docs/templating/filters#replace" rel="nofollow"><code>replace</code></a> filter solution is a good approach in my opinion. You can pass multiple replacements pairs like so
(and no, you won't notice if there's 1 or 100 of them):</p>

<pre><code>{% set str = '&lt;p&gt;Since {yearEstablished}&lt;/p&gt;' %}
{% set replacements = {
    '{yearEstablished}': companyInfo.yearEstablished,
    '{siteName}': siteName,
} %}
{{ str|replace(replacements)|raw }}
</code></pre>

<p>You could also consider building that replacements array programatically.</p>

CC BY-SA 3.0
2015-10-22T17:30:36.853Z
thanks. The replace filter is working well and because I am using it multiple times it works great as a macro. How you you see it working programmatically?
zizther
CC BY-SA 3.0
2015-10-22T17:36:16.463Z
Oh, I just meant you could loop through all of a global sets fields to build your array. But doing it manually gives you more fine control, rename things a bit for the client or skip some fields. So if there isn't very many fields it's probably not worth it.
carlcs
CC BY-SA 3.0
2015-10-22T17:43:43.843Z
That is what I had in mind. At the moment there is only 1 environment variable and 2 globals, so works quite well. Programmatically does male sense for manageability though. You could make it work by having a check box to decide whether or not to include it in the filter with another field for a custom name.
zizther
CC BY-SA 3.0
2015-10-22T14:13:14.107Z
2015-10-22T14:13:14.107Z
carlcs
<p>I want the ability to parse environment variables such as {siteName} and globals from channel fields, for example a rich text field.</p>

<p>I have been using <code>{{ include(template_from_string(entry.fieldName)|raw) }}</code>, but this is not suitable because it gives authors the full power of twig.
Brandon Kelly pointed out that using the replace filter can work <code>{{ entry.fieldName|replace('{siteName}', siteName)|raw }}</code></p>

<p>Using a macro I can make this manageable.</p>

<p>I would like the ability to use globals too, what is the best way to have all globals being options to replace or using another method?</p>

<p>Would having 20 possible variable options to replace cause any issues, I would be calling this 3-4 times in a template.</p>

<globals><environmentvariables>
How to parse environment variables and globals from a field
# How to parse environment variables and globals from a field

(Asked by: username_0 on 2015-10-22)

I want the ability to parse environment variables such as {siteName} and globals from channel fields, for example a rich text field.

I have been using `{{ include(template_from_string(entry.fieldName)|raw) }}`, but this is not suitable because it gives authors the full power of twig.
Brandon Kelly pointed out that using the replace filter can work `{{ entry.fieldName|replace('{siteName}', siteName)|raw }}`

Using a macro I can make this manageable.

I would like the ability to use globals too, what is the best way to have all globals being options to replace or using another method?

Would having 20 possible variable options to replace cause any issues, I would be calling this 3-4 times in a template.

**Tags:** globals, environmentvariables

---

## 3 answers

### Answer by username_0 on 2020-09-16. Score: 1 | Accepted answer

With Craft 3 and/or Twig, there is a nice easy way to manage this now.

To output environment variables, config variables, globals, etc you can use `{{ view.renderString(entry.richText) }}`, the [renderString](https://docs.craftcms.com/api/v3/craft-web-view.html#method-renderstring) method will parse a template as a string.

There is also Twig's [template\_from\_string()](https://twig.symfony.com/doc/3.x/functions/template_from_string.html) which allows you to parse any text as a Twig template, with access to variables, as well. Compared to renderString it works with include, extends & embed to if you need that

`{{ include(template_from_string(entry.richText)) }}`

These are both useful cleaner ways than what is discussed above.
I have since moved away from the complicated way of having to do it in Craft 2 and used these cleaner methods in Craft 3.


---

### Answer by username_1 on 2015-10-22. Score: 3

You can use my Filter Environment Variables plugin, which will get you about half-way there. It will automatically parse out any environment variables which show up in your dynamic fields...
{{ entry.myField | envvar }}


Once you've got that installed, it's fairly easy to adjust the logic to accommodate for globals as well.
Go to /filterenvvar/twigextensions/FilterEnvVarTwigExtension.php, and change this:
public function envvar($string)
{
    return craft()->config->parseEnvironmentString($string);
}

... to this:
public $globals = array();

public function __construct()
{
    foreach (craft()->globals->allSets as $globalSet)
    {
        foreach ($globalSet->content->attributes as $field => $value)
        {
            $this->globals[$globalSet->handle.'.'.$field] = $value;
        }
    }
}

public function envvar($string)
{
    $string = craft()->config->parseEnvironmentString($string);
    $string = $this->parseGlobals($string);
    return $string;
}

public function parseGlobals($string)
{
    foreach ($this->globals as $key => $value)
    {
        $string = str_replace('{'.$key.'}', $value, $string);
    }

    return $string;
}

This gives you the ability to parse global variables, in addition to your environment variables.
For your global variables, you'll need to include the global set handle in the token name:
my global field value is {globalSetHandle.fieldHandle}

This allows multiple global sets to use the same field.

> **Comments:**
> **username_0**: Great work @LindseyD  
> **username_0**: this works great for global variables, but not working for environment variables. I have tried with single and double curly brackets. Any thoughts?  
> **username_1**: @zizther: Make sure you use single curly braces, with **no padding spaces**. Like this: `{myVar}`  
> **username_0**: I have tested that way, but it doesn't seem to work. I am trying {siteName} and {basePath}. Example usage {{ entry.title | envvar }}  
> **username_1**: I tested this answer before posting it, so it _should_ work... DM me on Slack, and we can work through it. We'll post the results back here on this thread for future readers. :)  

---

### Answer by username_2 on 2015-10-22. Score: 2

You could enable your client to use Reference Tags by adding the parseRefs filter.
{% set str = 'Since {globalset:42:yearEstablished}' %}
{{ str|parseRefs|raw }}

But this would enable them to access field values of (almost) any element (entries, assets, tags, ..), not just from global sets.
And they would also have to remember the global set's ID.
So your current replace filter solution is a good approach in my opinion. You can pass multiple replacements pairs like so
(and no, you won't notice if there's 1 or 100 of them):
{% set str = 'Since {yearEstablished}' %}
{% set replacements = {
    '{yearEstablished}': companyInfo.yearEstablished,
    '{siteName}': siteName,
} %}
{{ str|replace(replacements)|raw }}

You could also consider building that replacements array programatically.

> **Comments:**
> **username_0**: thanks. The replace filter is working well and because I am using it multiple times it works great as a macro. How you you see it working programmatically?  
> **username_2**: Oh, I just meant you could loop through all of a global sets fields to build your array. But doing it manually gives you more fine control, rename things a bit for the client or skip some fields. So if there isn't very many fields it's probably not worth it.  
> **username_0**: That is what I had in mind. At the moment there is only 1 environment variable and 2 globals, so works quite well. Programmatically does male sense for manageability though. You could make it work by having a check box to decide whether or not to include it in the filter with another field for a custom name.  

---

