Introduction

This Article aims to cover how nested dynamic content can be used in Siteglide and to provide a troubleshooting service for when things don't work as expected. The two most common problems are:

  • Performance - When nesting dynamic content, the requests made to the database for content can increase exponentially. We'll show you how a few changes can make your code more efficient and speed up your Page
  • Scoping - Sometimes nested content can inherit Liquid variables from its parent Layout which will cause unexpected behaviour. Setting extra parameters will neutralise these variables and return the behaviour to the default.

Performance

My Page is Too Slow + My Page is hitting a 500 Error saying it has Timed Out

When using the original method of outputting Datasources, there are known issues with performance. This can cause Pages to load slowly and in some cases hit a 500 Server Error as the Page times out. A timeout happens if a Page takes longer than 10 seconds to load, however, really you'll want to be aiming for much faster Page loads than that anyway, for User Experience, SEO and many more obvious reasons!

Step 1) Pre-fetch Datasource Content

The first point of call here will be to implement our newer Datasource method as fully as possible.

The pre-fetching method does not yet cover all use-cases, as explained in the Article, so you may need to implement as fully as possible, then continue with these steps.

Step 2) Consider whether you can reduce the amount of Datasourced content, without inconveniencing the Client?

Although Datasources are incredibly useful, you and your Client may decide that some of your Datasource Content can be hard-coded in order to gain faster Page Load Speeds.

Step 3) Advanced - GraphQL Solution

Using custom GraphQL you may be able to Pre-fetch Datasource Content yourself more efficiently (as you know exactly what you need!) The related_models property will allow you to do this. (Docs coming soon).

This also comes without the inherent limits that come from us "guessing" what sort of content you'll need. With custom GraphQL you'll be able to pre-fetch content with any number of levels of nesting, and with any number of Datasource fields.

Step 4) Advanced- Analyse the performance of your Page using pOS tools and Best Practice

If you get in touch with us via live chat, we can help you out with this step, but if you're interested in measuring Liquid Execution Time and other Best Practice ideas you can read about it on the PlatformOS documentation.

Errors Displaying Correct Nested Content

The following troubleshooting advice applies to all nested content where you use an {% include %} tag inside another {% include %} tag- or if you are using an {% include %} tag inside a Detail Page Layout.

My nested Model Layout is not displaying any Content

Step 1) Check the IDs of your {% include %} tags

This sounds silly, but even we get this mixed up sometimes. Make sure you've used the correct IDs in your include tags. A common mistake is to either add the parent tag's ID to the child's tag, or to use the same ID for both when you did not intend to (although this is perfectly valid if you did intend it!)

Step 2) Check for Liquid Scoping Problems

When you include a WebApp or Module tag inside of another, some optional parameters become mandatory.

This is because in Liquid, variables are "scoped" so that each {% include %} tag inherits the variables of the parent file.

Step 2) a) OPTIONAL Choose the datasource or sub_model parameter to suppress pagination and other settings

If your child include tag is not pulling in data-source content, you may want to set the parameter sub_model: 'true'. This will stop it from inheriting:

  • The current page number in the URL- the nested content should always load the first results in the List.
  • Any category_id filter
  • If the child model is a Module, the Layouts for the child module will now be found within the parent model's Layout directory.
  • This allows you to add nested content without filtering it by ID.

If using nested Datasource include tags, set the parameter datasource: 'true' on the child model's include tag. This will have the same effects as the above sub_model parameter but will additionally:

  • Set the parameter type: 'list' for you
  • If no item_ids have been specified- we'll assume this means no Datasource content is available and we'll display no results. Without this parameter, the default would be to display all results from this Datasourced model.

Step 2) b) When including a List View inside a Detail View Layout, add the "type" parameter to the child {% include %} tag.

For example, if you have a Blog Detail Layout which nests a List View of eCommerce Products, the ordinary Liquid tag will not return any Products.

The reason for this behaviour is that the eCommerce List view {% include %} tag does not have a type parameter. Normally the type parameter defaults to "List", but inside a Detail view the type variable has a value of "detail". The value is inherited by the nested tag, which then tries to filter the content and look for Items related to the slug in the URL, usually returning errors.

It is therefore necessary to set the nested tag to have the type: 'list' parameter, to reset to the usual default.

In this case- you may choose not to use the sub_model parameter in the step above- particularly if you want to filter the nested content by Category. As there is no way to change page on the Detail page, it is less important to set sub_model. However, if the content is Datasourced, we'd still recommend setting the datasource parameter.

Step 2) c) When filtering the parent model, make sure to reset any filters you won't need on the child model

This step should only be necessary if you choose not to follow step 2) a)

When you apply a filter to the parent tag, that filtering will be inherited by the child tag.

For example, let's say that we have a Recipes WebApp which Datasources an Ingredients WebApp. We filter the Recipes WebApp to find recipes in the "Vegetarian" Category.

Now we might have assigned Categories to the Ingredients, but in this example, let's say we haven't. The parent WebApp's filter parameter will be inherited by the child WebApp. Siteglide will try to find ingredients in the Vegetarian Category and this will fail to find any.

The solution is to reset the filter. You can do this by resetting the parameter on the child tag to have the value nil which in Liquid means "empty":

{% include "webapp", id: "5", item_ids: ingredient_ids, category_ids: nil, type: 'list' %}

In this example, there's no need to set item_ids to nil because I'm already using this filter to achieve the Datasource functionality. You only need to "reset" parameters to nil if you're not already deliberately setting them to a value.