Introduction


What is a Datasource again?

A WebApp or Module can include a datasource field. This field stores the IDs of items from other WebApps or Modules which might be related to the original item in some way. For example:

  • A Blog Post might store the ID of its author in an "Authors" datasource field. 
  • A recipes WebApp Item might datasource an "Ingredients" WebApp and a "Chef" WebApp.

Terminology

In the rest of this Article, we'll use the following terminology to avoid confusion:

  • model - This term is a catch-all term for WebApps and Modules
  • parent model - The WebApp or Module you initially output on your Page, Detail Page or in an Email. 
  • child model - The WebApp or Module you fetch using the parent model's data-source field.

Why have we made improvements?

In the past, we would fetch the parent model's data and then make an extra request for each datasourced child model.

Each individual request takes time and this system was inefficient, so we've been working to improve it.

With our updates to datasource, you tell us which datasources you'll want to output in a particular layout, either by the field names, or by their IDs. We then efficiently fetch all the data at once. 

What are the benefits?

  • This should significantly improve Page load speed, specifically "Server Response Time" when datasources are used.
  • For added flexibility, you can choose whether to pre-load "all" datasource data from a model or specify specific fields. This allows you to fine-tune Layouts based on your requirements.
  • You'll be able to customise datasource Layouts.
  • Only minimal code changes will be needed to implement the improvements; we'll document these below.

Implementation


If you're upgrading a Site which already uses datasources, you will have already completed steps 2 + 3, but we'll include them for completeness.

Step 1) Update System Files


Make sure you have up-to-date System Files.

Step 2) Set up a parent model (WebApp / Module)


In this example we output a WebApp as our Parent Model. 

We've added three Custom Fields which datasource to the following models:

  • eCommerce Products (Module items)
  • Gallery Items (a WebApp)
  • Blog Items {Module Items)

You can use one you've already got on your Site - we'll just be adding a new parameter in the next step.

It's not yet possible to add datasource fields to most Modules, but you could choose to use a Module which already has datasource fields set up, for example the Blog Module already has a datasource field set up to reference the Authors module:

Step 3) Output your parent model (WebApp / Module)

{%- include 'webapp', id: '3', layout: 'custom', per_page: '20', show_pagination: 'true', sort_type: 'properties.name', sort_order: 'asc' -%}

Step 4) Specify which data-source fields you need in this Layout

As we are pre-fetching the datasource data, you'll need to use a parameter to specify which datasource fields we should fetch data from.

It might be that you have multiple datasource fields, but this specific Layout doesn't use them all. In which case, specifying fields means we won't slow down the Page loading data you're not using.

There are two choices to make here:

  • Fetch Fields by ID or Name?
  • Fetch all Fields or specify the fields you need.

The first is a matter of preference mainly. Names are easier to remember, but if you change the name in Admin, you'll need to change in the code too. IDs are for that reason easier to maintain.

You can find out the IDs by viewing an Item in Admin and using the toggle "Show Custom Field IDs":

All Fields

You can either fetch all fields by name:

{%- include 'webapp', id: '3', layout: 'custom', per_page: '20', show_pagination: 'true', sort_type: 'properties.name', sort_order: 'asc', datasource_fields_by_name: "all" -%}

Or all fields by ID:

{%- include 'webapp', id: '3', layout: 'custom', per_page: '20', show_pagination: 'true', sort_type: 'properties.name', sort_order: 'asc', datasource_fields_by_id: "all" -%}


List of Fields

You can list fields by name:

{%- include 'webapp', id: '3', layout: 'custom', per_page: '20', show_pagination: 'true', sort_type: 'properties.name', sort_order: 'asc', datasource_fields_by_name: "Product Link,WebApp 1 Link,Blog Link" -%}

Or list fields by ID:

{%- include 'webapp', id: '3', layout: 'custom', per_page: '20', show_pagination: 'true', sort_type: 'properties.name', sort_order: 'asc', datasource_fields_by_id: "webapp_field_3_1,webapp_field_3_3,webapp_field_3_4" -%}


We'll now prefetch the fields you asked for.

Step 5) Presenting the Data


Finally, you'll need to decide whether to output the data within the parent's Layout, or whether to include a Datasource Layout for the child model.


Option 1: Including a Datasource Layout


Syntax

{% include "datasource", datasource_field: "Product Link_datasource", layout: "datasource_products_test" %}


Notes:

The include file is datasource

The Parameter datasource_field should be given either of the following:

  1. A String with the "name" of the datasource field + "_datasource". E.g. Product Link_datasource 
  2. A String with the format properties. + the ID of the datasource field + _datasource. Which one will depend whether you originally chose to specify fields by name or ID on the parent "include" tag. e.g. properties.webapp_field_4_1_datasource 

The layout parameter allows you to specify your Layout name.

When the child is a Module

If your child model is a WebApp, you can use the Layout exactly as before. However if your child model is a module, you'll need to replace the get_items tag in your wrapper.liquid layout file with the following to link to your item.liquid file:

{%- include 'modules/siteglide_system/get/get_datasource_items' -%}


Example: 

The following Screenshot is achieved using the example code. It outputs a different layout for each type of datasource child.


Each child Layout uses the exact same code as it did before the datasource update. Although - I have reduced the image heights for demonstration purposes.

<div class="parent-container">
  <h2>{{this['name']}}</h2>

  <h3>Similar Products</h3>
 
  <div class="card-deck">
    {% include "datasource", datasource_field: "Product Link_datasource", layout: "datasource_products_test" %}
  </div>
  <h3>Related News</h3>
 
  <div class="card-deck">
    {% include "datasource", datasource_field: "Blog Link_datasource", layout: "datasource_blog" %}
  </div>
 
  <h3>Similar WebApps</h3>
 
  <div class="card-deck">
    {% include "datasource", datasource_field: "WebApp 1 Link_datasource", layout: "portfolio_2" %}
  </div>
</div>


Option 2: Output the Datasource Data inside the Parent Layout


This option is newly available.

For each datasource field in the this object, we also provide a version of that field with the String "_datasource" appended on the end. You can use dot notation to access the fields inside this object.

When specifying fields by name, you may have to use square brackets and quotes [" "] where your names have spaces in them.

For example, the following fields are available from the Product datasource on the parent Layout:

{{this['Product Link_datasource']}} - Output all fields in this datasource as data
{{this['Product Link_datasource'].first.name}} - Outputs this datasource's first item's name.

You can loop over Datasource Items and output an HTML component for each one:

<div class="card-deck">
{% for this in this['Product Link_datasource'] %}
  <div class="card">
    {{this.name}}
    {{this.full_slug}}
    {{this.release_date}}
  </div>
{% endfor %}
</div>


If you'd like to learn more about Dot Notation and Liquid For Loops, you can follow our Developer tutorials on using Liquid Dot Notation.

Did this answer your question?