In this lab, you'll learn to make API calls to the Episerver Content API by building a small user interface for displaying content about a fictional music festival. The Episerver site and associated content have already been setup, and the Episerver Content API has been appropriately installed and configured to serve the relevant content.
You'll be writing Javascript to make API calls, but you'll be provided with code snippets to complete all functionality, so only a basic understanding of Javascript is required. You won't need to write any markup or HTML as that is provided for you.
In order to complete this Lab, you'll need the following:
- A code editor (Visual Studio Code works great - but whatever works best for you)
- Google Chrome (or a similar browser with capable developer tools for inspecting requests)
- Access to an Episerver instance with the Content API installed, and the Music Festival content added.
The goal of this activity is to setup your development environment, and gain a basic understanding of Vue.js before diving into Lab activities.
- Open the
index.html
file in a web browser
You should see simple page with the text "Welcome to the Music Festival lab". If this isn't showing up, ask for help or check the console for errors. During the lab, as you make updates to your code, you'll refresh this page to see the results.
- Open Chrome Developer Tools by right clicking the page and selecting "Inspect"
You won't see much for now, but we'll use the Network and Console tabs to view requests we make to the Content API and debug.
- Using your favorite code editor, open the
index.js
file
This lab uses Vue.js, a simple javascript framework often used for building single page applications. Within this file, you'll see that Vue is being initialized with a few things.
-
A
data
object with a set of empty properties - we'll refer to this as our view model going forward. As we update properties on our view model from code, our view withinindex.html
will automatically update. -
A
created
function - you can think of this as a constructor. When our Vue instance is created, this function will be called. You'll see it is callinggetSiteInfo
andgetArtists
functions - we'll wire up and explain those later. -
A
methods
object - this contains functions that we will wire up to build our page. ThegetSiteInfo
,getStartPage
,getInfoPageContent
, andgetArtists
functions will load information from the Content API in various ways by the end of the lab.
-
Update the
title
property of the view model to change it from "Welcome to the Music Festival lab" to be your name. -
Reload
index.html
within the browser, and you should see your name displayed in the hero area of the page. -
You're ready to dive in.
The goal of this activity is to learn to use the Content API to locate the Start Page for a site, load the
- In
index.js
, add an API call to the Site Definition API within thegetSiteInfo
function. In order to make the request, we'll use a simple framework called axios which is already referenced in the project:
var vm = this;
axios.get(vm.apiUrl + '/episerver/site/', {
headers: {
'Accept': 'application/json'
}
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
-
Reload your browser, and open Developer Tools. On the Network tab under
XHR
, you should see a request to the Site Definition API. Click on it, and select thePreview
tab in order to inspect the response. You will see that only one site is returned, with associated ContentRoot and Language information. -
In index,js, update the
then
function of the code you added in Step 1 to locate and store the Start Page reference from the API response. To do this, we'll grab the first (and only) site from the array, locate theStartPage
property within theContentRoots
object, and store it'sId
property within our view model. Finally, we'll call the getStartPage function, which we'll wire up later.
//Grab the first site in the list
var site = response.data[0];
//Store the Start Page ID, and call getStartPage
vm.startPageId = site.ContentRoots.StartPage.Id;
console.log('Stored startPageId: ' + vm.startPageId);
vm.getStartPage();
-
Reload your browser, and open the Console. You should see
Stored startPageId: 5
printed. -
Next, we'll load the actual data for the Start Page within the
getStartPage
function using our storedstartPageId
, and grab information from aContentReference
property. Inindex.js
, add an API call to the Content API to load the Start Page in English (language codeen
), and store theMusicFestivalInfoPage
reference ID within our view model.
var vm = this;
axios.get(vm.apiUrl + '/episerver/content/' + vm.startPageId, {
headers: {
'Accept': 'application/json',
'Accept-Language': 'en'
}
})
.then(function (response) {
console.log(response.data);
//Store the MusicFestivalInfoPage property as infoPageId, and call getInfoPageContent
var startPage = response.data;
vm.infoPageId = startPage.MusicFestivalInfoPage.Value.Id;
console.log('Stored infoPageId: ' + vm.infoPageId);
vm.getInfoPageContent();
})
.catch(function (error) {
console.log(error);
});
- Reload your browser, and open the Developer Console. You should see
Stored infoPageId: 107
printed.
The goal of this activity is to use the entry point we established in Activity 1 to load a single page from the Content API, and write code to display our content on the page.
- In
index.js
, add an API call to the Content API within thegetInfoPageContent
function using our storedinfoPageId
var vm = this;
axios.get(vm.apiUrl + '/episerver/content/' + vm.infoPageId, {
params: {
},
headers: {
'Accept': 'application/json',
'Accept-Language': 'en'
}
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
-
Reload your browser, and open Developer Tools. On the Network tab under
XHR
, you should see the request to load the Info Page. Click on it, and select thePreview
tab in order to inspect the response. You will see various standard Episerver properties, as well as properties specific to theInfoPage
content type. -
In
index.js
, update your call withingetInfoPageContent
to grab theTitle
,Preamble
andMainBody
properties from the response in thethen
function and update their values on the view model
var page = response.data;
//Set title, preamble, and main body properties from the loaded data
vm.title = page.Title.Value;
vm.preamble = page.Preamble.Value;
vm.mainBody = page.MainBody.Value;
-
Reload your browser, you should see the Title, Preamble, and MainBody properties displayed on the page once the API call completes.
-
Next, we'll add a background image for our hero content. The image we're looking for is within the
HeroContentArea
property of our page, but if you look at the response from the API, you won't find the the Url of the image because, by default, the Content Api returns references for items within a Content Area. To gain access to the Url, let's add anexpand
property on theparams
object to ask that the Content Api return the contents of theHeroContentArea
in the same request:
params: {
expand: 'HeroContentArea'
},
-
Reload your browser, and open Developer Tools to inspect the request again. If you look at the
HeroContentArea
property, you should see anExpandedValue
array which contains a full response object for each item referenced in the Content Area. This specific Content Area contains a singleImageData
instance, with a background image. -
Wire up the
heroImage
property of our view model using theUrl
of the image contained within the Content Area.
//Grab the hero image from the first item in the HeroContentArea
//expand parameter must indicate HeroContentArea to be able to access ExpandedValue
vm.heroImage = page.HeroContentArea.ExpandedValue[0].Url;
- Reload your browser, and you should see a a background image in the Hero area of the page.
The goal of this activity is to use the Language information returned from the Content API to create a language switcher on our page. This will allow us to fetch content in multiple languages from the Content API.
- In
index.js
update thegetSiteInfo
function to utilize the Languages returned in the Site Definition API call you crated in Activity 1 to wire up a language switcher. To make the language switcher operate, we'll push all languages returned from the Site Definition API call into thelanguages
property on our view model. Add the following code below thevm.getStartPage()
function call within thegetSiteInfo
function.
//Update the languages data property on our view model
site.Languages.forEach(function (language) {
var item = {
text: language.DisplayName,
value: language.Name
}
vm.languages.push(item);
});
-
Reload your browser, and a language switcher will appear at the top right of the page. You'll notice that English and Swedish options are available, based on the configured languages that are returned in the Site Definition API. However, the language switcher won't work just yet.
-
The language switcher works by binding and updating the
currentLanguage
property whenever the value of the dropdown is changed, and then re-calling the API calls we made in Activities 1 and 2. In order to wire everything up, we need to update our API calls to ensure we pass in the value ofcurrentLanguage
each time we make an API call. To do this, update theAccept-Language
header used in the existing API calls within thegetInfoPageContent
andgetStartPage
functions like this:
Old Value:
'Accept-Language': 'en'
New Value:
'Accept-Language': vm.currentLanguage
-
Reload your browser, and change the language to Swedish, and the content on the page should update accordingly.
-
Open Developer Tools, and change the language back and forth between Swedish and English. On the Network tab, inspect the API requests that are made, noting their
Accept-Language
header is different each time you change the language.
The goal of this activity is to gain an understanding of the Search API by building a grid of Music Festival artists on the page. You'll learn how to filter and sort content returned form the the Search API
- In
index.js
, add the following code to thegetArtists
function to make an API call to the Search API in order to fetch data about artists for the music festival from Episerver Find. In this call, we'll utilize thefilter
parameter to only grab content of typeArtistPage
. In addition, we'll instruct the Search API to return the first 50 results using thetop
parameter. Once the API call returns, we'll grab theResults
property of the data response, and update theartists
property on our view model.
vm.loadingArtists = true;
axios.get(vm.apiUrl + '/episerver/search/content/', {
params: {
'top': 50,
'filter': "ContentType/any(t:t eq 'ArtistPage')"
},
headers: {
'Accept': 'application/json',
'Accept-Language': vm.currentLanguage
}
})
.then(function (response) {
console.log(response.data);
//Grab the artists from the Results property
vm.artists = response.data.Results;
vm.loadingArtists = false;
})
.catch(function (error) {
vm.loadingArtists = false;
console.log(error);
});
-
Reload your browser, and you should see a grid of artists appear below the info page content. Open Developer Tools, and inspect the request made to the Search API, noting the structure of the request and response. In addition to the
Results
property containing data which matches our filter, there is also aTotalMatching
property indicating the total items in the index which match our filter. In our case, the total number of artists is less then thetop
parameter, so we received all artists within Episerver. -
Next, let's add some sorting capabilities to our Artist Grid. To do this, we'll add a
orderby
parameter to our API call, and bind it to thecurrentSort
property of our view model like this:
params: {
'top': 50,
'filter': "ContentType/any(t:t eq 'ArtistPage')",
'orderby': vm.currentSort
},
- To finish wiring up our sort options, let's add a list of potential sort options to our view model. In the view model, update the
sortOptions
property to provide a variety of sorting options to the user. In addition, set the default sort toArtistName/Value asc
by updating thecurrentSort
property. Update the values below:
Old Value:
currentSort: '',
sortOptions: [
]
New Value:
currentSort: 'ArtistName/Value asc',
sortOptions: [
{
text: "Artist Name",
value: "ArtistName/Value asc"
},
{
text: "Performance Time",
value: "PerformanceStartTime/Value asc"
},
{
text: "Headliner",
value: "ArtistIsHeadliner/Value desc, ArtistName/Value asc"
},
{
text: "Genre",
value: "ArtistGenre/Value, ArtistIsHeadliner/Value desc"
},
]
- Re-load the page, and note the new sort dropdown with the options bound to the values above. Update the value of the sort dropdown, and note the change in order of artists within the grid. Open Developer Tools, and as you update the sort dropdown, note the requests made back to the Search API, and the format of the
orderby
parameter.
- Let's add filtering. It will work similarly to our dynamic sorting, with another dropdown for the user to adjust what shows up in the Artist grid. To accomplish this, we'll first make the
filter
parameter in our Search API call dynamic. Update theparams
object to passvm.currentFilter
to thefilter
property instead of the current value.
Old Value:
params: {
'top': 50,
'filter': "ContentType/any(t:t eq 'ArtistPage')",
'orderby': vm.currentSort
},
New Value:
params: {
'top': 50,
'filter': vm.currentFilter,
'orderby': vm.currentSort
},
- Next, let's add a list of potential filter options to our view model. In the view model, update the
filterOptions
property to provide a variety of filtering options to the user. In addition, set the default filter toContentType/any(t:t eq 'ArtistPage')
by updating thecurrentFilter
property. Update the values below:
Old Value:
currentFilter: "",
filterOptions: [
],
New Value:
currentFilter: "ContentType/any(t:t eq 'ArtistPage')",
filterOptions: [
{
text: "All",
value: "ContentType/any(t:t eq 'ArtistPage')"
},
{
text: "Headliners",
value: "ContentType/any(t:t eq 'ArtistPage') and ArtistIsHeadliner/Value eq true"
},
{
text: "Saturday",
value: "ContentType/any(t:t eq 'ArtistPage') and PerformanceStartTime/Value lt 2018-04-01T03:00:00Z"
},
{
text: "Sunday",
value: "ContentType/any(t:t eq 'ArtistPage') and PerformanceStartTime/Value gt 2018-04-01T03:00:00Z"
},
],
-
Re-load the page, and note the new filter dropdown. As you change the value of the dropdown, the contents of the Artist Grid will change. Open Developer Tools, and inspect the requests made back to the Search API, noting the various filter options employed via the
filter
parameter. -
Brainstorm additional sorting and filtering options and try to add them to the
filterOptions
andsortOptions
arrays to provide additional functionality to the user. Perhaps, a filter for each Stage?