Export Page

Here we provide a series of end-to-end development demonstrations that that go all the way from content creation to consumption. The demonstrations follow a logical sequence with each one building on the one that went before, so it makes most sense to work through them in order.

Prior to working through these development scenarios (or "developer use cases") you might want to familiarize yourself with the Content Authoring workflow and the quick-start steps.

 See the "Simple Text" Development Demonstration...

Content Authoring "Simple Text" Development Demonstration

This first scenario demonstrates the creation and consumption of simple text content. 

Step 1: Create the "Hello World" Simple Text Schema

The "Hello World" JSON schema (hello-world.json) provided below contains a single text field named "text" which has a limit of 256 characters. For the purposes of this demonstration you can simply copy this code into the Content Authoring application's Schema Editor as described in Step 1 of the Content Authoring Quick Start.

 See the hello-world.json schema code...




 Save the Schema as a content type named "Hello World".

Step 2: Create the Content in the Content Type Form

Each developer-created JSON schema is reflected as a content type in the Content Authoring application. You can click the "Hello World" content type icon to launch the Content Type Form:

Once the required text content has been added and saved, and the content has been published as described in Step 3 of the Content Authoring Quick Start, you can obtain the Asset ID and JSON URL for the resulting content asset as shown next. This will be used subsequently to consume the content via the Delivery API.

In this case the Asset ID is C76EAC2B-8FC9-47F3-BD6F-193C64400A8F. The JSON URL can be can be deduced by clicking the link labelled "View Live Delivery URL" and then copying the URL from the browser window that appears:

In our case the URL to be provided to the Delivery API as follows (but yours will be different):

Step 3: Consume the Content

Now we build a simple web application to consume the content.

Step 3.1: Logging Out the "Hello Word" Text with AJAX and jQuery

The example page at does the following:

  • Gets data using AJAX & jQuery.
  • Logs out data.
  • Finds result and graph ID.
  • Finds graph item with matching ID.
  • Logs out the "Hello World!" text content using console.log.

You can see the result by inspecting the web page and viewing the Console as shown here:

The underlying code can be viewed by using the "View page source" option to reveal:

Step 3.2: Logging Out the "Hello World" Text with the SDK

The example page at does the same thing, but using the Amplience CMS SDK. The code in this case is:

Step 3.3: Building Some Basic HTML

In the real world we would not be logging out the results, we'd be presenting them on a web page. So on the next example web page at we build some basic HTML. The code, which now writes the text to a DIV on the page, looks like this:

And the result is:

Step 3.4: Replacing Manual HTML Manipulation with a Handlebars Template

Rather than relying on manual HTML manipulation, we use a Handlebars template in the example at The result is pretty much the same as the previous picture, but in this case the HTML code underlying the web page is:

Step 3.5: Add Some Style

In the final step, demonstrated at, we apply some simple styling:

The additional styling code enclosed within the <style> tag looks like this:

 See the "Simple Text and Image" Development Demonstration...

Content Authoring "Simple Text and Image" Development Demonstration

This use case extends the Simple Text scenario to include an image.

Include an Image Definition in the Simple Text Schema

The simple text schema now contains an image definition within the "definitions" section of the schema. An image must validate as a "di-asset-link" and must be of semantic type "asset".

Create and Consume the Content

Via the Content Authoring app we can add an image to the content type that represents the schema we just created:

Then we publish the content:

In this case the details are:

Asset ID:



Here you can see the image included in the API response:

Consume the Content

Having constructed the schema and populated it with content, we can now consume the content.

Step 1: Construct the Image Retrieval URL

The "graph" section of the response (shown above) contains fields for the image that identify its defaultHost (, endpoint (playground) and name (womanwall). Taken together, these allow us to construct the following URL to retrieve the image:

We can even append some Dynamic Media parameters to manipulate the returned image on-the-fly:,1,1,7&fliph=true

The end result looks like this:

Step 2: Update the Rendering Template to Include the Image

Although the image is included in the API response, it does not yet render alongside the "Hello World!" text on the example page at (see below) because the image is not yet in the template.

Here is the modified Handlebars template to include the image, which utilises the image.defaultHostimage.endpoint and from the API response in order to compose the image URL.


The result at now looks like this:

Step 3: Restyle the Image and the Text

In the previous step the image is too big, and the end result would look much better like this:

So the final example at contains code to restyle the image and the text:

 See the "Responsive Imaging" Development Demonstration...

Content Authoring "Responsive Imaging" Development Demonstration

In the "Simple Text and Image" use case we created a schema that contains image content references, and we used Dynamic Media parameters to manipulate images on-the-fly. In this use case we go further by utilising Dynamic Imaging to deliver "responsive" or "adaptive" images that adjust to the size of the device screen or web browser window.

Please Note: While the following examples expose and code the dynamic imaging parameters directly in the image URL for simplicity and clarity, for best practice we would recommend putting these transformation parameters into Transformation Templates (TT's). You can find more details about this herehere and here.

The current image tag, which loads a single fixed-size image into the page, is:

<img src="https://{{image.defaultHost}}/i/{{image.endpoint}}/{{}}?w=400">

A couple of concrete examples using the Dynamic Imaging service are:

Step 1: Use the SRCSET Attribute

In this example, we'll re-use the existing image tag template and update it to use the SRCSET attribute to define different image sizes for different screen widths. Specifically, we will:

  • Load a 500px wide image if the screen is 500px wide.
  • Load a 1000px wide image if the screen is 1000px wide.
  • Load a 2000px wide image if the screen is 2000px wide.
  • Default to a 400px wide image if the web browser does not support the SRCSET attribute.

We make coding these tags simple by defining image transformations directly in the URL, and by supporting template systems such as Handlebars for re-use. The code is:

<img src="https://{{image.defaultHost}}/i/{{image.endpoint}}/{{}}?w=400" srcset="https://{{image.defaultHost}}/i/{{image.endpoint}}/{{}}?w=500 500w, https://{{image.defaultHost}}/i/{{image.endpoint}}/{{}}?w=1000 1000w, https://{{image.defaultHost}}/i/{{image.endpoint}}/{{}}?w=2000 2000w">

Note that in our examples, the image reference is always the same. Only the parameters change, to transform the image to match the SRCSET rules.

The example web page at can be resized (as shown below) to see how the image adapts accordingly.

Step 2: Incorporate the Picture Element

The picture element allows us to set up different sources of media for different breakpoints, for example for the image to adjust at certain boundaries (320w, 768w, 1024w, 1440w, 1920w, 2560w) rather than adjusting continuously as the size of the browser window changes. Each source can then have its own SRCSET of media, with the SRCSET controlling the pixel density (e.g. 1x or 2x). 

The unique code for this example is:


The complete code for this example can be found in the page source at Launch the page and resize the browser window to see how the image size changes only at discrete size boundaries.

Step 2.1: Image dimensions

Towards the bottom of the previous code sample, you will see some extra parameters assigned to the lower resolution media:


These parameters will crop the media to ensure that the response has a 1:1 aspect ratio that crops by default around the centre of the image. Here are some alternative aspect ratio examples that illustrate what difference it makes:

Example original:

Example at 1:1 aspect:

Example at 4:3 aspect:

Example at 1:2 aspect:

Step 3: Using Point of Interest

The problem with cropping around the centre of the image is that this may not be where the "action" is; i.e. not what the viewer really wants to see in the image. Consider the following 1:2 aspect ratio example (w=500&sm=aspect&aspect=1:2) that leaves the model lady out of the shot.

This is where a "point of interest" comes in useful as our way of ensuring that an image is cropped around the most interesting part of an image. The Amplience "Point of Interest" app allows us to assign a point of interest on an image as shown here:

This point of interest information is retrievable as metadata, which we can use in commands to ensure that the image always crops around the required point rather than around the centre:


POI example images can be viewed at the following URLs for the 1:1 and 1:2 aspect ratios respectively:{$this.metadata.pointOfInterest.x},{$this.metadata.pointOfInterest.y},{$this.metadata.pointOfInterest.w},{$this.metadata.pointOfInterest.h}{$this.metadata.pointOfInterest.x},{$this.metadata.pointOfInterest.y},{$this.metadata.pointOfInterest.w},{$this.metadata.pointOfInterest.h}

In both cases, the model is always in-shot:

The final example using a point of interest image can be found at

Step 4: Adapting for SEO

We can apply some simple additions to images that will help with search engine optimisation. The following examples all use the same textual content.

Add an "alt" and "title" Attributes to the Image
Use the "figure" and "figcaption" Elements

Use the 'Apparent Filename' Functionality

We can also use the Amplience apparent filename / SEO filename functionality as described in the SEO section at

Taking the original image request of, we can apply an apparent filename to give

Next we can apply transformation parameters to give{$this.metadata.pointOfInterest.x},{$this.metadata.pointOfInterest.y},{$this.metadata.pointOfInterest.w},{$this.metadata.pointOfInterest.h}

Before using this in our template, we must make sure that there are no special characters or spaces in the filename for the image. The following code adds a new attribute named "seotext" to the data from the service, which has any special characters replaced with '-' hyphens.

Then we can use this attribute or property when generating image URLs. Look out for "seotext" in this code:

The final example web page for this use case can be found at

Further Reading

Additional "point of interest" documentation can be found at and

Additional information about the Dynamic Media platform can be found at and

 See the "Validation" Development Demonstration...

Content Authoring "Validation" Development Demonstration

The purpose of validation in schemas is to ensure that entered data is in a correct format. In this use case we extend the original "Hello World" image schema to include validation. An extract from the new schema (hello-world-image-validation.json) is shown below, and we will refer back to it.

This schema defines two properties or fields, one for text and the other for an image, and we will step through the validation for each of these in turn.

Step 1: Text Validation

The first thing to note about the text field is that it is mandatory, hence this code at the foot of the schema definitions shown above:

"required": ["text","image"]

This also defines the image field as being mandatory, but we're getting ahead of ourselves.

As well as being mandatory, we specify that any user-entered text must begin with a capital letter and must be between 5 and 50 characters in length. We do this using the "minLength", "maxLength" and "pattern" attributes:

The result of this validation can be seen when a content editor user tries to enter incompatible information into the fields of the content type form for this schema. First the UI displays an asterisk next to the "Text" field to denote it as mandatory (1); then it displays an error message when the user tries to save the form without entering any text (2):

Next, the UI responds appropriately with error messages when the user tries to enter text that breaks the validation rules:

Step 2: Image Validation

We also need to define the image object as being compliant with the di-asset-link schema, as being of mediaType "image", and as being of semanticType "asset":

We showed earlier how the image (as well as the text) could be defined as being mandatory:

"required": ["text","image"]

This results in the image place-holder being annotated with an asterisk in the UI. It also triggers the display of an error message if the user attempts to save the content type form without specifying an image:

Complete Schema Code

 See the complete code for this schema that includes validation...

 See the "Relationships" Development Demonstration...

Content Authoring "Relationships" Development Demonstration

As with any type of software coding, schema coding can benefit greatly from modularisation. There are two ways to link sub-schemas to a containing schema: Content Linking (aka Nested Schemas), and Inlining.

In this example, we would like to create a new schema that can contain multiple existing "Hello World" schemas, but without pasting the same sub-schema code into the containing schema multiple times.

 See the "Hello World" schema code (which will be our included sub-schema)...
 See the content linking / nesting approach...

Content Linking

In this case, the Hello World schema will be linked to the containing schema such that any container content instance will contain one or more independently-existing "Hello World" content instances. 

Below is the framework for the containing schema. As well as defining a "headline" within the set of definitions, it also defines a number of content items as asset links within an array. Each of these links must validate against the "Hello World" schema that is referenced by its Schema ID. 

Step 2: Create the "Hello World" Content Items

First we create some "Hello World" content items that have their own independent existences outside of the container.

Step 3: Create the Container Content

Next we create the content for the containing schema, which has a "headline" at the container level plus place-holders for the "contained" content items.

Step 4: Add a Linked Content Item

Now we can proceed to add a content item of the "Hello Validation" content type (next three pictures).

Step 5: Add (and Create) More Linked Content Items

Because we defined an array list of contained items in the containing schema, we can add a second linked item:

We can even create an entirely new one to be linked (next two pictures):

Step 6: Save, Publish and View

Now we publish the container content, and get its link... that we can build the example page rendering at On this page you can view the linked content items rendered in sequence, and you can view the page source to see how we did it.

 See the inlining approach...

Inlining Content

Alternatively it is possible to use inlining in those cases where you wish to reuse schema definitions that exist in a separate schema, but not reuse content that exists independently.

Step 1: Create the Containing Schema with the Inline Schema Referenced

In the inlining case, the JSON code for the containing schema looks like this:

In this case, the code to include one or more array items of the included schema is:

"$ref": "{{}}"

Notice the much simplified "items" section, with no necessity to use the allOf validation for the array type(s). But we do need to include the "interpolate": true flag so that the Content Authoring UI knows that this is an inline rather than a nested / linked schema.

"_interpolate": true

And we include the following label code to override the label that was defined at the "Hello World" sub-schema level, so that it makes more sense when adding content items of the sub-schema type. 

"value": "Hello World Image",
"hint": "Hello World schema to show a textual example with an image and validation"

Step 2: Create the Content

When adding content for this container schema (and sub-schema), the content type form looks like this:

Notice how the entire set of fields for the inlined content (in this case "Text" and "Image") are available for editing right on the container form... but shown visually as embedded within an outline box. Because the containing schema's array definition allows more than one item, we can click the "ADD HELLO WORLD IMAGE" link to add another Text+Image "Hello World" combo. This is what it looks like with two items added:

Step 3: Save, Publish and Consume the Content

Once the content is published and saved in the usual way, it can be consumed by a front-end application.

An example request for the content would be:

The response would look like this:

Although the response structure differs in the cases of linked and inlined content, our JavaScript SDK inlineContent() method makes the content suitable for rendering using exactly the same rendering template in both cases.

An example page showing the end result can be found at

 See the "Reusing Data" Development Demonstration...

Content Authoring "Reusing Data" Development Demonstration

In this use case we retrieve exactly the same content as with the previous Relationships example, and present it in different ways. In the page sources for both of the examples demonstrated below, you will find the same asset ID 7f0e2816-d25e-4a44-8569-6f8b05321de3 for the retrieved content. We are therefore demonstrating the decoupling of content and presentation.

Data Displayed using Masonry

The web page at uses the Masonry JavaScript grid layout library to display the content. It looks like this:

Same Data Used on a Carousel Page

The web page at presents the exact same content in the form of a carousel.

 See the "Content Authoring - "Simple Video" Developer Demonstration...

Content Authoring "Simple Video" Development Demonstration

This use case shows an example consuming Amplience Video in a HTML5 video tag. The end result can be seen here:

Step 1: Create a Simple Video Schema

The simple video schema contains a video title and a video. A video must validate as a "di-asset-link" and must be of semantic type "asset".

Create and Consume the Content

Via the Content Authoring app we can add a video to the content type that represents the schema we just created:

Then we publish the content:

In this case the details are:

Asset ID:



Here you can see the video included in the API response:

Consume the Content

Having constructed the schema and populated it with content, we can now consume the content.

Step 1: Construct the Video Retrieval URL

The "graph" section of the response (shown above) contains fields for the image that identify its defaultHost (, endpoint (playground) and name (AnyaFinn-Shoppable). Taken together, these allow us to construct the following URL to retrieve the video.

Calling the video directly will give you the thumbnail image assigned to that video - we can add commands to size the image as appropriate:

The end result looks like this:

Step 2: Loading video information

We now need to retrieve video information from the video meta data api, so that we know the details of the video transcodes available for consumption. Useful reference links:

Playground for Amplience video:

Video API:

To do this, we will request the video as JSON:

You can see the API response below:

The example loads this as a simple AJAX request using the information from the CMS API:


Step 3: Sorting available videos (optional)

In this example, we will be sorting the available videos from the video meta data API in order of quality ( highest first ). To do this, we have created a simple helper function to transform the data and return in the correct order.

We can call this sending in the video meta data in order for it to be transformed:

Step 4: Add the video meta data to the CMS data

In this example, we are combining the data from the 2 API's so that can use a single handlebars template to produce the HTML output.

Step 5: Create a simple video Rendering Template

This template will display:

  • Video Title
  • Video tag with poster image
  • Video sources in order of quality.

Template is below:

Notice that this template uses a helper called "getVideoFormat". This ensures that the video sources have the right attributes to describe the video to the browser in the right format. This helper is listed below and accepts an individual transcoded video from the API:

Step 6: See the result



 See the "Content Authoring - "Simple Video - VideoJS" Developer Demonstration...

Content Authoring "Simple Video - Video JS" Development Demonstration

This use case builds on the previous Content Authoring - "Simple Video" Developer Demonstration and uses the same schema. It introduces the use of the VideoJS video player instead of the default HTML5 offering.

The end result can be see here:

Step 1: Include VideoJS files in HTML

VideoJS has some dependant JS & CSS. Below is an example with the latest files at the time of production.

Step 2: Amend Handlebars template to match VideoJS Structure 

VideoJS has required some extra classes and data attributes. The below Handlesbars template takes this into consideration from


Step 3: Instantiate the VideoJS Player

Once the HTML has been created for the Video, we can instantiate the VideoJS player

Step 4: See the result


  • No labels