For all intents and purposes you build this in the exact same way as any other HTML file. Where things start to get interesting are when we look at how to add dynamic content.

What is Liquid?

Liquid is the templating engine, developed for and used by Shopify. Used in conjunction with your HTML It’s a simple programming language that tells our app what content to put where.

It supports basic data output using double curly braces

<p>{{ some_variable_name }}</p>

or more advanced logic such as loops

<ul>
	{% for item in collection %}
		<li>{{ item.some_property }}</li>
	{% endfor %}
</ul>

Giving you a full rundown of how Liquid works is a bit beyond the scope of this guide. However Shopify do an excellent job of it, so if you want to dive into the language, we suggest you read their documentation on it.


Available variables

We provide you with a collection of objects which you can use on your status page. Here we’ll look at what each one is for, and how you can output their details.

Page

The page is the overarching parent object which is available to you. All other objects are contained within this, and you’ll be access them through it.

<div>
	<h1>{{ page.name }}</h1>
</div>
{{ page.content_for_head }}
This must be included somewhere in the <head /> of your document and is used for including analytics, monitoring and profiling scripts.
{{ page.content_for_body }}
This must be included somewhere in the <body /> of your theme, preferably after any JS includes you make yourself. It is used for including analytics, monitoring and profiling scripts.
{{ page.name }}
This gives you the name of your status page, the one you chose when you created it.
{{ page.visible_to_search }}
A simple true/false value which tells you if this page is open to indexing by search engines. This can be used for setting meta robots tags.
{{ page.meta_title }}
This gives you the the value to be used in your pages <title /> - if the user has not set anything specific this will fallback to the pages name.
{{ page.meta_description }}
This gives you the value to be used in your <meta name="description" />. You should always set this value where possible to avoid search engines indexing specific notices.
{{ page.locale }}
A simple string which represents the language used for the page, defaults to 'en' but could be any valid locale name. Should be used to set things like the 'lang' attribute on the html tag, or localize JavaScript libs.
{{ page.copyright }}
This gives you a link and copyright / powered-by notice which should be included in the footer of every status page.
{{ page.brand }}
A collection of colours, logos and other images related to the page.
{{ page.support }}
A collection of support contact details for the page.
{{ page.components }}
A collection of component objects. This collection contains all the components which have been created on your status page.
{{ page.components.roots }}
A collection of component objects. This collection only contains the top level components (those without a parent) which can be helpful when recursively displaying nested/grouped components.
{{ page.notices }}
A collection of notice objects. This collection contains all open notices and all notices closed in the past [n] days, ordered by the date in which they were created. If no notices are available on the page then this will be an empty array.
{{ page.notices.future }}
This collection acts as above but only contains notices scheduled to occur in the future.
{{ page.notices.present }}
This collection acts as above but only contains open notices.
{{ page.notices.past_recent }}
This collection acts as above but only contains notices which were closed in the past 7 days.
{{ page.notices.planned }}
This collection acts as above but only contains planned notices.
{{ page.notices.unplanned }}
This collection acts as above but only contains unplanned notices.
{{ page.subscription_option }}
A collection of subscription options. This collection contains options for reads to subscribe to status updates for the page, currently supports 'Slack'.

Brand

This contains all the configured colours, logos and icons for a page. These should be applied to your theme to allow people who use it to easily customize the theme to match their brand.

<header>
	<img src="{{ page.brand.logo.url }}" alt="The company logo." />
</header>
{{ brand.logo }}
The customers uploaded logo. This providers 'url' and 'content_type' properties.
{{ brand.favicon }}
The customers uploaded favicon. This providers 'url' and 'content_type' properties, as it could be both png and ico.
{{ brand.header_background }}
The customers uploaded favicon. This providers 'url' and 'content_type' properties, as it could be both png and ico.
{{ brand.color_state_ok }}
Most likely to be a share of green, this should be used to signify a positive status.
{{ brand.color_state_warning }}
Most likely to be a share of orange or red, this should be used to signify a negative status.
{{ brand.color_navbar_* }}
Background, Text & Button colours for use on the navigation. .e.g. {{ brand.color_navbar_background }}
{{ brand.color_header_* }}
Background, Text & Link colours for use on the page header. .e.g. {{ brand.color_navbar_background }}
{{ brand.color_body_* }}
Background, Text & Link colours for use on the body. .e.g. {{ brand.color_body_background }}

Support

This contains all the configured support contact details for the page, including an email address, telephone number and URL.

<header>
	<a href="mailto:{{ page.support.email }}">Contact Support</a>
</header>
{{ support.email }}
The user supplied support email address. i.e. helpdesk@example.com
{{ support.telephone }}
The user supplied support telephone number. i.e. 08000 123 456
{{ support.url }}
The user supplied support url. i.e. http://example.com/helpdesk

Component

The page may or may not have a collection of components attached to it, these components can be recursively nested to form groups of associated components. They also include their own state which is determined from any associated notices, or the state of ancestor/descendant components.

<ul>
	{{ for component in page.components.roots }}
		<li><string>{{ component.name }}</string></li>
	{{ endfor }}
</ul>
{{ component.state }}
Determined by any associated open notices, or the state of it's ancestors and descendants. One of 'operational', 'degraded', 'partially-degraded'.
{{ component.name }}
The name of the component i.e. Database Server.
{{ component.description }}
An optional description of what the component is, displayed next to the name.
{{ component.position }}
Used to order components on the status page, lower numbers display higher than those with higher numbers. Component collections are already ordered using this property by default.
{{ component.parent }}
Returns a single component object which is the parent of this one, may be null if it's a top level component.
{{ component.children }}
A collection of component objects. These are to be sat under this component, and may themselves contain children recursively.

Notice

The page may or may not have a collection of notices attached to it. Each notice is it’s own object with it’s own set of details.

<ul>
	{{ for notice in page.notices }}
		<li><span>{{ notices.created_at }}</span></li>
	{{ endfor }}
</ul>
{{ notice.type }}
Either 'planned' or 'unplanned', planned notices include expected start times and durations, often used for maintenance.
{{ notice.state }}
The current state of the notice. Available states depend on the notice type. For planned: 'scheduled', 'underway', 'complete' and for unplanned: 'investigating', 'identified', 'recovering', 'resolved' and 'false_alarm'
{{ notice.timeline_state }}
This give you an idea of whether a notice is 'future', 'present' or 'past_recent'.
{{ notice.subject }}
The subject line of the notice, this is determined by the user when they’re publishing the notice.
{{ notice.synopsis }}
This is a short description for the notice, usually pulled from the first update which was posted against it.
{{ notice.updates }}
Each notice contains a collection of subsequent updates. If no updates are made to an notice this will be an empty array.
{{ notice.components }}
Each notice may contain a collection of component objects. While the notice is ongoing the state of these components will be affected.
{{ notice.begins_at }} 'planned' only
The date/time a planned notice is expected to go underway.
{{ notice.ends_at }} 'planned' only
The date/time a planned notice is expected to be complete.
{{ notice.expected_duration }} 'planned' only
The expected duration of a planned notice in minutes.
{{ notice.began_at }}
The date/time which the incident first began, sometimes differed from the created_at which determines when it was first posted to the status page.
{{ notice.ended_at }}
The time that the incident was ‘closed’ or marked as resolved.
{{ notice.duration }}
The actual duration of a past notice in minutes.
{{ notice.created_at }}
This is a date/time stamp that the notice was first created.
{{ notice.updated_at }}
This is a date.time stamp that the notice was last updated.

Subscription Option

The page may or may not have a collection of subscription options. Each option contains a link which allows the user to begin the subscription process.

{% if page.subscription_options.slack %}
    <form action="{{ page.subscription_options.slack.url }}" method="get">
        <button class="btn btn-subscribe navbar-btn navbar-header-btn">Get Updates Via Slack</button>
    </form>
{% endif %}
{{ subscription_option.url }}
The url to be followed to begin the subscription process for this option.

Update

The final object you have at your disposal are notice updates. These are just very simple comment-like objects.

<ul>
	{{ for update in notice.updates }}
		<li><span>{{ update.created_at }}</span> {{ update.content }}</li>
	{{ endfor }}
</ul>
{{ update.content }}
This is the text content for the update. e.g. ‘We have now identified the problem with the phone system and are working to fix it.’
{{ update.created_at }}
This is the date/time that the update was added to the notice.