How to: Use Resources in Templates

What are resources

Resources are pieces of data related to a site that can be queried and inserted into templates. Resources can be part of a site’s store data like the item catalog or store locations. Resources can be things entered in the website editor like video. And finally resources can be related to a current browser session like cart or customer account.

Ways to access resources in templates

There are two ways to access resources in templates:

Template schemas and props

In your template you can use the schema tag to define what resources the template will utilize. For example:

{# templates/pages/my_page.html.twig #}
{{ my_item.name }}

{% schema %}
{
	"my_item": {
		"type": "item"
	}
}
{% endschema %}

In the above example my_item is the name used to reference a resource. The schema declares that my_item is of type item which means it will have all the properties of an item. The template doesn’t know which item will be provided from the site catalog. This ensures a separation between theme code and site data which allows theme templates to be used for different sites.

The specific item provided to the template is defined by a page. A page definition looks like:

{
	"template":"templates/pages/my_page",
	"route": "item-page",
	"props":{
		"my_item": {
			"filters": {
				"id": "example-id"
			}
		}
	}
}

The props section of a page definition corresponds to the template’s schema and fills in the resource data with data from the site. The same template could be applied to different pages and receive different data as props.

Right now page definitions are edited as json files found in the site/pages directory. Eventually the page data will also be used by the WYSIWYG editor to allow end users to make changes to pages without needing to write code.

Resource functions

Another way to access resources is with resource functions:

{{ item('example-id').name }}

{% for my_item in category('example-category-id') %}
	{{ my_item.name }}
{% endfor %}

{% for popular_item in popular_items() %}
	{{ popular_item.name }} - {{ popular_item|display_price() }}
{% endfor %}

With resource functions, a template can directly access the specific site resource.

Why use schemas vs resource functions

You should be aware of the following considerations when deciding which method to use for your implementation.

Template reuse. Using schema definitions to access resources allows templates to be written without knowledge of a site’s data. Templates request certain types of data to display without needing to know the specific IDs of those resources (such as item IDs, category IDs, or location IDs). This allows templates to work for any site.

If you’re building a theme that you want to work for many different sites, you should always use template schemas to either access resources directly or to pass parameters to resource functions. In the following example, the schema passes the productId parameter to the item resource function.

{% set item = item(productId) %}

{% schema %}
{
   "productId": {
      "type": "string"
   }
}
{% endschema %}

If you’re building a single site for a client, you can use resource functions or schema definitions. Some people prefer to use resource functions because it makes the code easier to read.

Nested items. Another consideration is the ability to access nested items or categories. With a schema definition, you can only access one level down. If you need to drill deeper (for example, to get all items within categories that are related to a given item), use resource functions. Alternatively, you can use the Site Theme SDK or the Resources API.

The SDK’s helper functions make it easier to perform site actions than calling client APIs directly.

Resource caching

All resource fetches in the schema and the template are cached when a template is rendered. The cache is invalidated when a catalog change occurs or the site is republished.

Keep in mind that certain resources cannot be cached. An example of a resource that cannot be cached is Cart.

Refer to this guide on how to load uncacheable resources with the template API.

Uncacheable Resources
Cart
LoyaltyProgram
CustomerAccount
ScheduleDay
ScheduleTime

Resource Query Types

As a theme developer, you may have a resource that is not expected to be used initially by a page render. An example of this is if you had a schema resource that loaded in a category-list, but the category-list was only diplayed in a modal if a site visitor clicked on a button.

Instead of loading in this category-list with the page render, you could specify the type as a category-list-query. The -query type suffix identifies the resource as one to skip resource loading for. The resulting value provided to the template is the filter object that can be used for fetching the resource via the the Resources API.

<button id="display-deferred">
	Display content
</button>

<div id="category-content">
</div>

<script>
	document.getElementById('display-deferred').addEventListener('click', () => {
		fetch('https://api.example.com/data',{
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
				'X-CSRF-TOKEN': 'csrf_token_from_csrf_meta_tag',
				'Accept': 'application/json'
			},
			body: JSON.stringify({
				input: {
					'categories': {{ deferred | json_encode }}
				}
			})
		}).then(data => document.getElementById('category-content').textContent = data);
	});
</script>

{% schema %}
{
   "deferred": {
      "type": "category-list-query"
   }
}
{% endschema %}

Query type resources are also eligible to be passed into the Template API.

See also