Skip to main content

Hierarchies

On this page we'll explain how to create content type schemas so that you can add content items to hierarchies, how to sort hierarchy nodes and what information you can retrieve using the filter API.

We've also included several examples: a simple hierarchy, a hierarchy that contains multiple content types and a hierarchy that is used to tag content. The examples are all included in the schema example templates in the Dynamic Content app, so it's easy to add them to your hub. See the example schemas section for more details.

For more information about the hierarchy user interface see the working with hierarchies page.

note

You can list and filter both published and unpublished hierarchical content using the filter API. However, you currently can't retrieve unpublished hierarchical content within a content preview. See using the filter API with unpublished content for more details.

About hierarchies
Link copied!

Hierarchies allow you to model tree structures of content. A hierarchy is a natural way of using a tree structure to represent the relationship between objects. It might be a page structure for a website, a list of worldwide store locations organised by country and city, a structured list of product content, app settings or a list of ingredients and meal types for a recipe site. Hierarchies lend themselves to many use cases.

In Dynamic Content, a hierarchy provides a new way to link content items together. The content items in a hierarchy are normal content items that have relationships to each other. Because they are normal content items, you can work with these content items independently and manage and publish items in the normal way. The main difference is that a content item that is part of a hierarchy will have a relationship with its parent.

The example below shows one possible use case, a website menu that's built from a hierarchy. On the left you can see the hierarchy as modelled in Dynamic Content. Users can see at a glance how the website is structured and where content should be displayed. On the right is how the hierarchy is consumed in the app, providing the structure for the site navigation.

An example use case: a site menu

Hierarchies let users see the whole context. It might be a page or website layout, a buyer's guide or a list of tags to apply to blog posts. The user interface makes it easy to see all of the tree, and decide where to add and remove nodes if they need to.

Creating a schema for a hierarchy node
Link copied!

A hierarchy is a tree of nodes, each of which is a content item. Each node can have descendants, or child nodes. You can model a hierarchy in which all nodes are the same content type, or choose to define your hierarchy so it can contain items of multiple content types.

In each content type schema that defines a content item that can be added as a node to a hierarchy, you will need to specify the content types of the items that can be added as child nodes. To do this you will make use of Amplience specific extensions to the JSON Schema standard.

Including the hierarchy definitions
Link copied!

In your schema core definitions you will need to include the hierarchy definitions as follows:

"$ref": "http://bigcontent.io/cms/schema/v2/hierarchy#/definitions/hierarchy-node"

Your schema will now look something like:

{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/site-menu-item",

"title": "Site menu",
"description": "A node in the site menu hierarchy",

"allOf": [
{
"$ref": "http://bigcontent.io/cms/schema/v1/core#/definitions/content"
},
{
"$ref": "http://bigcontent.io/cms/schema/v2/hierarchy#/definitions/hierarchy-node"
}
],

...

}

The hierarchy trait
Link copied!

The trait keyword is an Amplience specific keyword that is used to include additional information about a schema. By including trait:hierarchy you can specify that a content item created from this schema can be added to a hierarchy. You also provide a childContentTypes array that defines the type of content items that can be added as child nodes. You can leave this array blank if you want a node created from the schema to be a leaf node with no children.

In the example shown below, we are modelling a hierarchy for a site menu. Each node in the hierarchy will be the same content type, so we just include the schema itself in the array. Only content items created from the schema registered with the URL https://example.com/site-menu-item can be added as children.

"trait:hierarchy": {
"childContentTypes": [
"https://example.com/site-menu-item"

]
},

The schema editor includes shortcuts to make it easier to add traits to your schemas.

note

If you change a schema to include the hierarchy-trait object, any content items created with the schema prior to the change will need to be converted to reflect the update to being hierarchical content. Your users will be notified if a content item needs converting. See Converting items for use with hierarchies.

Examples
Link copied!

Example 1: The site menu
Link copied!

The simple example shown below is a simple hierarchy representing the menu for a website, including sections for mens, womens, electricals and a blog.

The site menu hierarchy.

Each node in the hierarchy will be a site-menu-item content item, so the childContentTypes array in our schema will include a single entry for the https://example.com/site-menu-item content type schema.

Because hierarchies are just content items, you can link all or part of a hierarchy to another content item with a content-link or content-reference. For example, we could assign a category such as electricals to a banner so that appropriate content is shown when the user browses to each section of the site.

The schema also includes a title and a description for each section. The complete schema is shown below.

{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/site-menu-item",
"title": "Title",
"description": "Description",
"allOf": [
{
"$ref": "http://bigcontent.io/cms/schema/v1/core#/definitions/content"
},
{
"$ref": "http://bigcontent.io/cms/schema/v2/hierarchy#/definitions/hierarchy-node"
}
],
"trait:hierarchy": {
"childContentTypes": ["https://example.com/site-menu-item"]
},
"type": "object",
"properties": {
"title": {
"title": "Title",
"description": "Title used for the menu item",
"type": "string",
"minLength": 0,
"maxLength": 100
},
"description": {
"title": "Description",
"description": "description",
"type": "string",
"minLength": 0,
"maxLength": 100
}
},
"propertyOrder": [],
"required": ["title"]
}

The filter API can be used to traverse the tree and find the children of each node.

Example 2: multiple content types: the page hierarchy
Link copied!

This more advanced example makes use of two content types to implement an ideas and advice section on a website.

The page hierarchy example.

The page-hierarchy content type (1 in the image above) represents a category such as "Lighting and electrical" or "Heating and plumbing". It contains a title, description, image and a ranking. The page-hierarchy-node content type (2 in the image above) is the help page itself, including content such as text and images.

The start of the page-hierarchy schema is shown below. The childContentTypes array in the trait:hierarchy object contains two items: the page-hierarchy and the page-hierarchy-node. This is because we want to be able to add one category as a child of another and to add the help pages as children of a category.

The page-hierarchy schema
Link copied!

{
"$schema":"http://json-schema.org/draft-07/schema#",
"$id":"https://schema-examples.com/page-hierarchy",
"title":"Page Category",
"description":"Category that can contain pages or subcategories",
"allOf":[
{
"$ref":"http://bigcontent.io/cms/schema/v1/core#/definitions/content"
},
{
"$ref":"http://bigcontent.io/cms/schema/v2/hierarchy#/definitions/hierarchy-node"
}
],
"trait:hierarchy":{
"childContentTypes":[
"https://schema-examples.com/page-hierarchy",
"https://schema-examples.com/page-hierarchy-node"
]
},

The page-hierarchy-node schema
Link copied!

Note that for the page-hierarchy-node schema the childContentTypes array is empty because we don't want to add any children to page hierarchy nodes.

{
"$schema":"http://bigcontent.io/cms/schema/v2/schema#",
"$id":"https://schema-examples.com/page-hierarchy-node",
"title":"Page",
"description":"Page as a hierarchy node",
"allOf":[
{
"$ref":"http://bigcontent.io/cms/schema/v1/core#/definitions/content"
},
{
"$ref":"http://bigcontent.io/cms/schema/v2/hierarchy#/definitions/hierarchy-node"
}
],
"trait:hierarchy":{
"childContentTypes":[

]
},

Example 3: using a hierarchy to tag content: the ingredients hierarchy
Link copied!

In this example an ingredients hierarchy is used to tag recipes. There are 2 content type schemas: the ingredients hierarchy and the recipe schema which uses an array of content types to allow the user to choose one or more items from the hierarchy. This puts the user in control by allowing recipes to be tagged dynamically rather than having to choose from a preset list of values.

The ingredients hierarchy.

The recipe content item tagged with multiple items from the hierarchy is shown below. Note that this schema makes use of the hierarchy extension to make it easy to browse and add items from a hierarchy rather than a flat view of content items.

A recipe item tagged with multiple items from the ingredients hierarchy.

The ingredients property in the recipe schema is an array of content links of the ingredients-list type. Users can choose one or more ingredients to tag the recipe. A search index could then be used to allow the user to find recipes which have been tagged with their chosen ingredients.

   "ingredients":{
"title":"ingredients",
"type":"array",
"minItems":0,
"maxItems":10,
"items":{
"allOf":[
{
"$ref":"http://bigcontent.io/cms/schema/v1/core#/definitions/content-link"
},
{
"properties":{
"contentType":{
"enum":[
"https://schema-examples.com/ingredients-list"
]
}
}
}
]
}
}

Sorting nodes
Link copied!

By default, nodes will be shown in the order in which they are added, but you can define a sort order to specify a property that will be used for sorting.

To define a sort order, include trait:sortable in your schema and specify one or more properties to use for sorting in the paths array. The sort order is specified in JSON pointer format.

In this example we will sort the hierarchy tree using the title of each content item. The children of a node will be sorted in ascending order by the title property.

"trait:sortable": {
"sortBy": [
{
"key": "default",
"paths": ["/title"]
}
]
}

In the page-hierarchy schema we've included a ranking property that allows the user to control the order in which nodes are sorted. The ranking is included in the sort, so nodes will be sorted in ascending order of ranking and, if the ranking is equal, the title will be used.

"trait:sortable":{
"sortBy":[
{
"key":"default",
"paths":[
"/ranking",
"/title"
]
}
]
}

Using hierarchies with the Content Delivery API
Link copied!

When you publish a hierarchy node you can choose whether to publish it on its own or together with its dependents. The Content Delivery API includes some additional information about a node under the hierarchy element. Here's an example of the content returned for the root of the hierarchy- that is the node that has no parent item. You can see that root is set to true.

{
"content": {
"_meta": {
"name": "Website menu",
"schema": "https://example.com/site-menu-item",
"hierarchy": {
"root": true
},
"deliveryId": "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c"
},
"title": "Website menu",
"description": "Menu for our website"
}
}

Here's the content returned for an item named "Clearance", you will notice that this includes a parentId element. This is the node's immediate parent, in this case the root node shown above. You can use the parentId to traverse back up the tree or with the filter API to find all the children of the parent.

{
"content": {
"_meta": {
"name": "Clearance",
"schema": "https://example.com/site-menu-item",
"hierarchy": {
"parentId": "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c",
"root": false
},
"deliveryId": "da2cc1b1-d7f5-4743-b7c0-a3c893363c3e"
},
"title": "Clearance",
"description": "Items that must go"
}
}

Listing all children of a hierarchy node
Link copied!

Using the filter API you can list all the children of a specified parent node by setting the filter path to /_meta/hierarchy/parentId,as shown in the content returned from the Delivery API, and setting the parent id to the deliveryId of the item whose children you want to return.

In the example filter API request shown below we are requesting all the children of the hierarchy node with the id "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c". Note that just the immediate children will be returned. You will need to go through each of the nodes returned in the response to find their child nodes.

{
"filterBy": [
{
"path": "/_meta/hierarchy/parentId",
"value": "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c"
}
]
}

Try it out
Link copied!

To try out the filter request use the following cURL.

curl -d '{
"filterBy":[
{
"path":"/_meta/hierarchy/parentId",
"value":"b158fe6b-fe4b-46e3-92c5-33f8a4e5675c"
} ]
}' -H "Content-Type: application/json" -X POST 'https://ampproduct-doc.cdn.content.amplience.net/content/filter'

An example response is shown below. These are the items that have the node with the id "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c" as their parent.

{
"responses": [
{
"content": {
"_meta": {
"name": "Homewares",
"schema": "https://example.com/site-menu-item",
"hierarchy": {
"parentId": "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c",
"root": false
},
"deliveryId": "44ca42f3-8953-4ff5-99a8-ac48980e63d2"
},
"title": "Homewares",
"description": "For the home"
}
},
{
"content": {
"_meta": {
"name": "Clearance",
"schema": "https://example.com/site-menu-item",
"hierarchy": {
"parentId": "b158fe6b-fe4b-46e3-92c5-33f8a4e5675c",
"root": false
},
"deliveryId": "da2cc1b1-d7f5-4743-b7c0-a3c893363c3e"
},
"title": "Clearance",
"description": "Items that must go"
}
}
],
"page": {
"responseCount": 2
}
}

Removing a node from a hierarchy
Link copied!

When you remove a node from a hierarchy, the link between the node and its parent is still there in the published version of your content. Currently, in order to ensure that the node is not included when you list all children of its parent, you must remove the node and re-publish it so that the link to its parentId is removed as well.

In the example below we're removing the "Bathroom" node from its hierarchy.

Removing a node from a hierarchy.

The bathroom node is no longer part of the hierarchy, but as you can see from the JSON returned by the Content Delivery 2 API, the parentId still contains the value of its previous parent node.

The removed node still contains a link to its parent.

When the item is re-published, the parentId will not longer be included in the JSON response and the item will no longer be returned as part of the hierarchy.

When the node is re-published, the link to its parent is removed.

Another approach you can use, if you're implementing something like a page hierarchy, is to include an "isActive" flag in the Content Type schema that you can use with the filter API to return only those nodes that are marked as active. This allows the user to choose which nodes will be returned.

The hierarchy chooser extension
Link copied!

The hierarchy content field extension allows users to browse and add content items from a hierarchy rather than having to find these items in the Content Library. In the example of the recipe hierarchy, by using the hierarchy extension, it's easy to to browse and add multiple ingredients.

Tagging a recipe with items from the ingredients hierarchy using the hierarchies extension.

To use the hierarchy extension you need to include the content item id of the hierarchy node from which the hierarchy can be browsed in the extension parms. You can find the content item id from the properties pane in the content form, as shown in the image below.

Finding the content item id of the node from which the hierarchy can be browsed.

The ingredients property shown below uses the extension registered as "hierarchy-extension" and passes the id of the root node of the ingredients hierarchy- the content item named "Ingredients".

   "ingredients":{
"title":"ingredients",
"type":"array",
"minItems":0,
"maxItems":10,
"ui:extension":{
"name":"hierarchy-extension",
"params":{
"nodeId":"ea3e494b-f001-491a-9508-6387fecca1e0"
}
},
"items":{
"allOf":[
{
"$ref":"http://bigcontent.io/cms/schema/v1/core#/definitions/content-link"
},
{
"properties":{
"contentType":{
"enum":[
"https://schema-examples.com/ingredients-list"
]
}
}
}
]
}
}

Registering the hierarchy chooser extension
Link copied!

To register the hierarchy extension, go the development home page and click the extensions icon, or choose "Extensions" from the Development menu. Click the "Register extension" button.

  • In the registration window, choose "Content field" as the category.

  • Add a label and name. The name will be used as the value of the "name" field in the ui:extension section of a property that uses the extension. In the ingredients property shown above the extension is named "hierarchy-extension".

  • Enter https://hierarchy-chooser.extensions.content.amplience.net/ as the URL.

  • Click the "Permissions" tab to set the extension permissions. Set the "Read access" and "Allow same origin" permissions.

Registering the hierarchy extension.

You can specify additional parameters from the "Installation parameters" tab or add them directly in your schema. The available parameters are as follows:

ParameterDescriptionRequired / Optional
nodeIdThe content item id of the item to use as the root of the hierarchyRequired
typeThe display size of each node: large, small or chipOptional. The default is "large"

When you've finished setting up the extension, click "Save" and the extension will be registered and available to include in your schemas.

Example schemas
Link copied!

The schemas used in this page are all included in the schema example templates in the Dynamic Content app. Go to the using the schema examples page for more details.

You can also find the schemas on the following pages:

Adding traits in the schema editor
Link copied!

The schema editor includes shortcuts for adding a trait:hierarchy object to your schema. Just type control + space and and choose "trait:hierarchy" from the popup menu.

Using a shortcut to add a hierarchy trait in the schema editor.

The trait will be added to your schema. Click inside the trait object, type control + space again and choose "childContentTypes" from the menu. Then add any content types you want to allow to be added as children of nodes of the type defined in the schema.

Adding the childContentTypes array.

Working with hierarchies

List, filter and sort content

Registering extensions