Everything a developer changes on a Core dna site lives in its theme repository. This guide covers the repository and its build, printing records in templates, stylesheets and client-side code, and the parts of a site around the main content.
L1–L2
Unit 05 · Around the main content
Site data and feature flags
Around the main contentPage 32 of 35Updated
How to read a site-data value in a template, why a JSON value comes back as a structure rather than a single value, and the access pattern that keeps a switched-off feature off.
Who this is for. Developers who want a setting or a feature switch that an administrator changes without a deploy. After this page you can store a value in site data, read it in Smarty and Twig, and test a switch so that a feature renders only when it is on.
What site data is
Site data is a list of named values stored with the site: configuration and short copy that templates read. An administrator edits it under System › Sites › Site Data, a superadmin screen. Each row has four fields:
Field
What it holds
Site
The site the row belongs to. Left blank, the row applies to every site on the client
Key
The name a template asks for, matched exactly, case included, with no wildcards
Type
scalar (the default) for a single value, or json for a structure
Content
The value
When a key has a row for the current site and a client-wide row, the site's row wins, so a client with several sites can set a default once and override it per site.
Site data holds configuration and copy, never secrets. A template can print any value, and any authenticated backend user can read site data through the API, so keep API keys and passwords out of it.
Reading a value
_siteData is in every frontend template. get('key') returns the value, or null when no row has that key. $_siteData->key (Twig _siteData.key) is the same call written as a property, and isset($_siteData->key) is true only when the value is not null. A key with a hyphen cannot be written as a property, so read keys such as personalisation-settings with get().
What comes back depends on the row's type:
scalar: the stored string or number, as it is;
json: an array, already decoded. There is nothing to parse in the template.
A dotted key is a name, not a path: get('social.facebook') looks for a row whose key is exactly social.facebook. To keep related values together, store one json row named social and read its facebook field.
A structure is always true
A feature switch is usually a json row, because it carries the feature's settings with it. Suppose the row personalisation-settings holds:
JSON
{
"enabled": false
}
Read back, that is an array with one entry, and an array with any entry in it counts as true. A test on the whole value therefore renders the feature even though enabled is false:
Template code
{* wrong: a structure with anything in it is true, enabled or not *}
{if $_siteData->get('personalisation-settings')}
<script src="/dist/personalisation.js"></script>
{/if}
{# wrong: a structure with anything in it is true, enabled or not #}
{% if _siteData.get('personalisation-settings') %}
<script src="/dist/personalisation.js"></script>
{% endif %}
The access pattern
Read the value once into a variable, then test the field you mean:
{% set personalisationSettings = _siteData.get('personalisation-settings') %}
{% if personalisationSettings.enabled %}
<script src="/dist/personalisation.js?v={{ _currentSite.getLastVcsHash() }}" nonce="{{ _inlineScriptNonce }}"></script>
{% endif %}
When the row does not exist, the variable is null, the field test is false, and the feature stays off until an administrator creates the row. Name each key for what it controls, and write down the fields it expects in the header comment of the template that reads it (Documenting a template's inputs), so the administrator knows what to enter.
Site data, custom fields or an environment check
Use
For
Read with
Site data
A site-wide setting or feature switch an administrator changes without a deploy