Selvin Ortiz

Storing Global Variables In Craft

November 28, 2014 by

Cover Image for Storing Global Variables In Craft

In Craft, the process of creating global content has been standardized using the Global Set Element Type otherwise known as Globals.

I want to propose another way of doing so without having to create any global sets, field layouts, or having to log into your dashboard. Think of it as a developer oriented approach that we can use to store key/value pairs in our configuration files and have them available in our templates.

Let’s see how we would do this using globals first because they are the "Craft Way" of doing things and they are your best option when you need to deal with complex content structures, localization, or when having the ability to edit the content from the dashboard is a requirement.

Storing variables using globals #

The craft documentation provides a very nice description of what Globals are and how to use them. I suggest you give that a read if you’re not familiar with them.

To create globals, you will most likely follow a recipe similar to the one below.

  1. Create a Global Set
  2. Create a set of fields with the desired type
  3. Attach those fields to the field layout of your global set
  4. Go to the globals page in the dashboard and populate those fields
  5. You can now use them in your template
{{ globalSetHandle.globalFieldHandle }}

Your milage may vary but that is pretty much how I go about it.

If on the other hand, what I need is a set of key/value pairs to use in my templates, config variables is what I reach for.

Storing variables using environment configs #

Environment configs can serve as an efficient way to store key/value pairs that you can then access within your template without having to create any global sets.

Craft already does this, it is the way we tell it what our database credentials are and how we configure the thousand other things it gives us the freedom to.

So, this is how I go about that…

First, I update my craft/config/general.php file by adding my desired key/value pairs to act as my "global content" that I can use in my template.

return array(
    '*' => array(
        'globalContent' => array(
            'titlePlacement'  => 'after',
            'titleSeparator'  => ' | ',
            'resourceVersion' => 'v1.0',
        )
    )
);

I can now fetch those values in my template like this:

{% set globalContent = craft.config.get('globalContent') %}
{% set siteTile      = 'Site' %}
{% set pageTitle     = 'My Page' %}

{% set title %}
    {% if globalContent.titlePlacement == 'after' %}
        {{- pageTitle ~ globalContent.titleSeparator ~ siteTitle -}}
    {% else %}
        {{- siteTitle ~ globalContent.titleSeparator ~ pageTitle -}}
    {% endif %}
{% endset %}

{{ title }}
{# My Page | Site #}

{{ includeCssFile '/main.css?' ~ resourceVersion }}
{# <link> to /main.css?v1.0 #}

As you can probably tell, we are adding a special key (globalContent) to our global environment (*) and grabbing it from our template using craft.config.get(), we are then using those values to display the desired title format on our pages and bust cache on our stylesheet.

That’s it, define your variables in your config file and grab them in your template.

Now wrapped in a plugin #

I’ve formalized this technique into a plugin (more on that on the next article) which I’ve been using in production with improved performance, mainly because we are bypassing Element Queries (which can have some overhead) and we’re using the config service which Craft is already using and temporarily caching during first load.

As I’ve demonstrated, I don’t need to use a plugin for this but doing so gives me the following benefits.

  1. I can use dot syntax to access values inside dimensional arrays
  2. I can use back references inside my variable definition
  3. I can have my variables scoped to the plugin name (craft.ini)
  4. My variables can be defined per environment

Quick example using the plugin #

Let’s define our variables again but this time, let’s use back reference and array traversing dot syntax.

return array(
    '*' => array(
        'globalContent' => array(
            'author'    => array(
                'name'  => 'Selvin Ortiz',
            ),
            'site'      => array(
                'title'          => '{author.name}',
                'titlePlacement' => 'after',
                'titleSeparator' => ' | ',
            )
            'resourceVersion'    => 'v1.0',
        )
    )
);

Accessing these variables within my template (granted the plugin is installed) would be as easy as…

{{ craft.ini.author.name }}
{# Selvin Ortiz #}

Since the plugin has a public api, another plugin could use your defined variables as well.

// Notice dot notation at work here
public function someAwesomeMethodOnAnotherPlugin()
{
    $name = craft()->ini->get('author.name');
}

Final notes #

Try not to use environmentVariables as the key for your global content because Craft uses that for parsing placeholders like {siteUrl}, {fileSystemPath}, etc. This parsing takes place within a for loop, so the more variables your store there the more cycles the loop will go through.

An additional tip would be to define your variables in a separate file that returns an array and require it from craft/config/general.php as the value for your config key.

return array(
    '*' => array(
        'globalContent' => include 'path/to/file.php'
    )
);

If you have any related tips or tricks, please feel free to share then in the comments and I’ll update this article as necessary if it makes sense.

Thanks for reading this article, your support is appreciated!

Categorized As