3

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.

2

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.

| improve this answer | |
  • 2
    Great work @LindseyD – zizther Oct 22 '15 at 18:11
  • this works great for global variables, but not working for environment variables. I have tried with single and double curly brackets. Any thoughts? – zizther Oct 25 '15 at 14:39
  • @zizther: Make sure you use single curly braces, with no padding spaces. Like this: {myVar} – Lindsey D Oct 25 '15 at 17:33
  • I have tested that way, but it doesn't seem to work. I am trying {siteName} and {basePath}. Example usage {{ entry.title | envvar }} – zizther Oct 25 '15 at 17:36
  • 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 Oct 25 '15 at 17:38
1

You could enable your client to use Reference Tags by adding the parseRefs filter.

{% set str = '<p>Since {globalset:42:yearEstablished}</p>' %}
{{ 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 = '<p>Since {yearEstablished}</p>' %}
{% set replacements = {
    '{yearEstablished}': companyInfo.yearEstablished,
    '{siteName}': siteName,
} %}
{{ str|replace(replacements)|raw }}

You could also consider building that replacements array programatically.

| improve this answer | |
  • 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 Oct 22 '15 at 17:30
  • 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 Oct 22 '15 at 17:36
  • 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 Oct 22 '15 at 17:43

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.