The platform's central abstraction, in one line: an input type defines what an editor can enter, a layout area binds one input type to a named slot, a layout groups areas and points at a template, a record or component holds the content for each area, and the template reads it back. Read this book straight after the template languages.
L1–L3
Unit 05 · Components, collections and global components
Global components
Components, collections and global componentsPage 18 of 45Updated
A global component is one component with its own identifier and revisions, shown wherever a template or a collection asks for it. How identifiers are scoped to sites, how to reach one from any template in both engines, and when a global beats repeated local copies.
Who this is for. Developers building headers, footers, banners and other blocks that must be the same everywhere, and content modellers deciding whether a block is shared or authored per page. After this page you can choose the right kind of block, reach a global component from any template and test that it exists.
What a global component is
A local component lives inside the record that holds it. Its content is stored with the revision of that page, post or book page, and a new revision of the record copies the component along with everything else. It has no revisions of its own.
A global component is a record in its own right. It renders through a component layout like any component, but it is versioned by itself: its content lives in its own revisions, independent of every page that shows it. It also carries an identifier, the string a template uses to ask for it. Edit it once and every place that shows it changes.
A global component reaches a page in two ways:
Through a component or collection area. A component area, or an element of a collection, holds either a local component or a link to a global component (Components and collections). The template does not need to know which: a collection element's getComponent() returns the local component when there is one and the global component otherwise, so the collection loop renders both without a branch.
By identifier, from a template. Any template can fetch one through $_globalComponents, with no area involved. This is how a header, a footer or a site-wide banner reaches every page.
Older themes branch on isGlobal() in the loop and call getGlobalComponent(); that does the same as the loop without the branch, which can replace it.
Creating one, and what the identifier is for
A global component needs a component layout, which decides its areas and the template that renders it; an identifier; and a site, or no site to share it across all the client's sites. Its content is then authored in its own revisions.
The identifier is what makes it addressable. It is unique per site: one identifier can exist once for each site, and once more as a shared global component with no site. When a template asks for an identifier, the platform looks on the current site first and falls back to the shared one. So a site-specific global component overrides a shared one with the same identifier: give the shared footer the identifier footer, and a site that needs its own footer gets a site-specific footer with no template change.
If neither exists, the lookup returns null. Treat an identifier like an area name: templates name it as a string, so renaming it in the admin leaves every template that asks for the old name with nothing. Settle on a stable, descriptive identifier, such as footer, site-banner or newsletter-cta, before templates use it.
Reaching one from a template
$_globalComponents (_globalComponents in Twig) is available in every template. Its get() takes an identifier and returns the global component, or null when none matches. Print it with getHtml(), which renders it through its layout's template exactly as a local component is rendered. A site-wide banner in the base template:
Template code
{* in the base template: a site-wide banner *}
{$banner = $_globalComponents->get('site-banner')}
{if !empty($banner) && !$banner->isBlank()}
{$banner->getHtml()}
{/if}
{# in the base template: a site-wide banner #}
{% set banner = _globalComponents.get('site-banner') %}
{% if banner is not empty and not banner.isBlank() %}
{{ banner.getHtml() }}
{% endif %}
Test the value get() returns, as above. get() also ties the page's cached copy to the global component, so a change to the global component reaches the cached pages that show it.
In Twig, _globalComponents.footer is a shorter form of get('footer') for an identifier that is a valid name; get() takes any identifier, hyphens included.
Existence tests always pass
_globalComponents reports every name as set, whether or not a global component has that identifier. So is defined in Twig and isset() in Smarty are always true on it and guard nothing. Test the returned value: not empty, and not blank.
getHtml() takes the same variables as for a local component: pass a heading level or a variant down as an array, and the component's template receives it. Give passed variables names of their own and never pass component, which would replace the component being rendered; The collection loop and rendering a component has the full contract. When a template wants one value rather than the rendered block, read the area with the shorthand: a global component is versioned, so the value comes from its active revision.
Template code
{$footer = $_globalComponents->get('footer')}
{if !empty($footer)}
{$footer->getHtml(['headingLevel' => 3])}
{/if}
{* one value, not the whole block *}
{$brand = $_globalComponents->get('brand')}
{if !empty($brand)}
<a class="brand" href="/">{$brand->heading}</a>
{/if}
{% set footer = _globalComponents.get('footer') %}
{% if footer is not empty %}
{{ footer.getHtml({'headingLevel': 3}) }}
{% endif %}
{# one value, not the whole block #}
{% set brand = _globalComponents.get('brand') %}
{% if brand is not empty %}
<a class="brand" href="/">{{ brand.heading }}</a>
{% endif %}
Global or repeated local
The rule: global when one edit must change every appearance; local when each appearance is authored on its own.
Global component
Local component
Content stored
In its own revisions
In the revision of the record that holds it
One edit changes
Every page that shows it
That one appearance
History
Its own, independent of any page
Each holding record's, with the record's other content
Maintenance cost
One appearance cannot differ without being copied out to a local component first
N appearances need N edits
Suits
A header, a footer, a site-wide banner, a shared call to action
A hero, a page section, a quote written for one page
The admin follows the same rule. Its Edit as local copy and Duplicate as a local copy actions turn a shared global component into a one-off where a single appearance needs to differ, leaving the shared original as it is.
When a block is the same everywhere but must also be authored per page in a few places, keep the global component for the common case and make local copies only for the exceptions. A block that is copied out on most pages was never shared: make it local from the start.