Creating a Carousel Widget using APIv2

Table of Contents

Overview

In this tutorial, we will be creating a simple Javascript carousel using Olapic APIv2 to display the most recently published content from your Olapic account.

For Olapic APIv2’s full technical specs, please refer to the APIv2 documentation.

Full Code

You can view the full code for this tutorial here.

Click the navigation arrows to interact with the widget.

Authentication

API Key

  1. To make valid API calls, you will need your Olapic API Key.

    You can find your API Key in the Olapic Platform by clicking the Settings icon in the top right corner:

    Settings Icon

    Copy the API key by clicking the COPY button:

    API Key

Customer ID

  1. You can hit our root endpoint using your API Key to return the Customer object associated with the API key.

    For more information on the Customer object, please refer to the Customer Endpoints in our APIv2 documentation.

    Example request:

    GET https://photorankapi-a.akamaihd.net/auth_token={api_key}&version=2.2

    Example response:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
     {
       metadata: {
       code: 200,
       message: "OK",
       version: "v2.0"
       },
       data: {
         _links: {
           self: {
             href: "//photorankapi-a.akamaihd.net/?auth_token=0a40a13fd9d531110b4d6515ef0d6c529acdb59e81194132356a1b8903790c18&version=v2.2"
           }
         },
         _fixed: true,
         _embedded: {
           customer: {
             _links: {
               self: {
                 href: "//photorankapi-a.akamaihd.net/customers/215757?auth_token=0a40a13fd9d531110b4d6515ef0d6c529acdb59e81194132356a1b8903790c18&version=v2.2"
               }
             },
             id: "215757",
             _fixed: true,
             name: "Demo Account",
             domain: "",
             template_dir: "demo",
             language: "en_US",
     ...
    

Dependencies

The standard Olapic widgets have a “list” view of UGC in the form of a carousel or a gallery, and a “detail” view in the form of a lightbox. Many clients using the API may seek to emulate that experience. Although our widgets have been customized for Olapic’s specific requirements, it’s certainly possible to achieve this functionality using your own custom JavaScript and off-the-shelf libraries.

For this exercise, we will be using following libraries:

Keep in mind that there are many alternate libraries for carousels, galleries, and lightboxes; the API can work with any of them. You could also of course write your own.

Setup

We’ll create an index.html page that will contain all of our HTML. Our <head> section will contain links to our stylesheets, JavaScript files and any dependencies. Here is what it looks like so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<head>

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Olapic API Examples</title>

  <!-- CSS -->
  <link rel="stylesheet" type="text/css" href="css/owl.carousel.min.css">
  <link rel="stylesheet" type="text/css" href="css/owl.theme.default.min.css">
  <link rel="stylesheet" type="text/css" href="css/main.css">

  <!-- jQuery -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <!-- Owl Carousel JS-->
  <script src="js/owl.carousel.min.js"></script>

  <!-- main JS -->
  <script src="js/main.js"></script>

</head>

The <body> section will be simple since we will be adding HTML via JavaScript. We will create two <div> containers. One as a parent container and one as a requirement for OwlCarousel to target.

1
2
3
4
5
6
7
<body>

  <div class="olapic-api-example">
    <div class="owl-carousel owl-theme"></div>
  </div>

</body>

The final HTML code should look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Olapic API Examples</title>

  <!-- CSS -->
  <link rel="stylesheet" type="text/css" href="css/owl.carousel.min.css">
  <link rel="stylesheet" type="text/css" href="css/owl.theme.default.min.css">
  <link rel="stylesheet" type="text/css" href="css/main.css">

  <!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

  <!-- Owl Carousel JS-->
  <script src="js/owl.carousel.min.js"></script>

  <!-- main JS -->
  <script src="js/main.js"></script>

</head>
<body>

  <div class="olapic-api-example">
    <div class="owl-carousel owl-theme"></div>
  </div>

</body>
</html>

We’ll need to create a main.js file that contains our JavaScript for building a carousel. Essentially, we’ll follow four steps:

  1. Build the API request URL for getting content
  2. Fetch the content from that endpoint via an AJAX call
  3. Build the carousel
  4. Bind our lightbox so that enlarged UGC is displayed when clicked

Creating an API endpoint

To make sure our JavaScript code is executed once the DOM is ready, we’ll use the $(document).ready() callback:

1
2
3
$(document).ready(function(){

});

Inside this function is where we’ll execute the code that makes a call to the Olapic API to retrieve the most recent content and display it in the carousel.

Before we construct the AJAX call, we’ll create a variable that will store the URL we want to call. Since the goal of this tutorial is to display the most recent images, we’ll be making a call to the Get Media of a Customer endpoint.

The HTTP Request for this endpoint looks like:

GET /customers/{customer_id}/media/{sorting_option}?rights_given={rights_given}&include_tagged_galleries={include_tagged_galleries}
Host: photorankapi-a.akamaihd.net

See all required/optional parameters and their definitions of the endpoint here.

Now that we understand all the parameteres available for this endpoint, we’ll construct our request:

1
var olapicEndpoint = "https://photorankapi-a.akamaihd.net/customers/215757/media/recent?rights_given=0&include_tagged_galleries=0&auth_token=0a40a13fd9d531110b4d6515ef0d6c529acdb59e81194132356a1b8903790c18&version=v2.2";

Looking at the endpoint, we’re calling on the most recent media of customer 215757 sorted by recent order. We’ve also specified to remove any streams with the status TAG from the embedded object in the response (include_tagged_galleries=0).

Alternate common API endpoints

The following API endpoints are commonly used in fetching content:

Use case Endpoint Details
Product Detail Page (PDP) /streams/bytag/{key} Key is the product key which is sent to Olapic in your Product Feed or created manually in the platform
Multiple Product Page (MPP) /customers/{customer_id}/categories/search?tag_key={key} Key is the category key which is sent to Olapic in your Product Feed or created manually in the platform

Fetch UGC from the API

Now let’s construct our AJAX call to this endpoint and see what the response looks like. For now, we’ll log the response in the console so that we know what to traverse when we start to extract data.

Here is what we have so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$(document).ready(function() {
  var olapicEndpoint = "https://photorankapi-a.akamaihd.net/customers/215757/media/recent?rights_given=0&include_tagged_galleries=0&auth_token=0a40a13fd9d531110b4d6515ef0d6c529acdb59e81194132356a1b8903790c18&version=v2.2";

  $.ajax({
    dataType: "json",
    url: olapicEndpoint,
    type: "GET",
    data: {
      format: "json"
    },
    success: function(data) {
      console.log(data);
    },
    error: function(error){
      console.log(error);
    }
  });
});

We’re making a GET request to this endpoint and expecting to receive a response in JSON format. If the response is returned successfully, we’ll log the response to the console. If there’s an error, we’ll log the error to the console.

Console:

Media List Console

After traversing the response, we see the media array lives under data._embedded.media. Let’s capture the array in a variable called mediaArray so that we can iterate through the array.

1
2
3
4
5
6
7
	...
  success: function(data) {
    var mediaArray = data.data_embedded.media;
    console.log(mediaArray);
  },
	...
});

If we log the mediaArray to the console, we should see the array of media objects:

Media Object console

We’ll want to iterate through this to grab the URL of the media so that we can display it in the carousel.

Let’s look at first media object to see where we can find the URL hosting the image.

Media Sizes

Looking at the first media object, we see the images object property contains five different versions of the asset. Here are the specifications of each version of the asset:

  • Square: 90x90px image. Cropped, does not maintain original ratio.
  • Thumbnail: 150x150px image. Maintains original ratio.
  • Mobile: 320x320px image. Maintains original ratio.
  • Normal: 640x640px image. Maintains original ratio.
  • Original: original image without modifications.

Now that we know where in the media object to get the image URL, we will construct a for loop that will loop through mediaArray. Each time it hits a media object in the array we’ll store the mobile image asset in a variable and append HTML inside the owl-carousel <div>.

1
2
3
4
5
6
7
8
9
10
11
12
13
for (x=0; x < mediaArray.length; x++) {
	var mediaItem = mediaArray[x];

	// Create the UGC preview using the smallest image
	var mediaEl = '<img src="' + mediaItem.images.mobile + '" />';

	// Define a larger image resource for use in the lightbox
	var mediaUrl = mediaItem.images.normal;

	// Append the generated UGC item to the carousel
	$(".owl-carousel").append('<a href="' + mediaUrl + '" ' + featherlightAttrs + ' class="item olapic-image">' + mediaEl + "</a>");

};

The end result is 20 additional <div> containers with <img> tags appended inside the owl-carousel <div>.

HTML render

We now know it’s working so we can move on to setting up the carousel.

For the carousel, we’ll use a nifty image carousel plugin called OwlCarousel.

To configure OwlCarousel, refer to their documentation and available options from their API.

The basic setup requires us to use their CSS, JS and jQuery:

1
2
<link rel="stylesheet" href="owlcarousel/owl.carousel.min.css">
<script src="owlcarousel/owl.carousel.min.js"></script>

Looking back at our HTML example in the beginning of this tutorial, you’ll notice that these files are already included.

We already have a container for owlCarousel to inject the content, so all we need to do is invoke the plugin:

1
$(".owl-carousel").owlCarousel();

Utilizing a few of the OwlCarousel API options, the implementation looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(".owl-carousel").owlCarousel({
	loop: true,
	touchDrag: true,
	nav: true,
	navText: ["<i class='arrow left'></i>", "<i class='arrow right'></i>"],
	dots: false,
	navSpeed: 150,
	responsive: {
		0: {
			items:2,
		},
		767: {
			items: 3
		},
	}
});

This will display a carousel that allows for navigating between pages of content.

Adding a lightbox

Now that we have our carousel working, we may want to add a lightbox to allow users to view expanded UGC. As mentioned, we’ve chosen Featherlight as our lightbox solution. After including the required JavaScript and CSS files into our template, we can then trigger the lightbox by adding data-featherlight attributes that define the lightbox presentation, for example:

1
2
3
<a href="https://z2photorankmedia-a.akamaihd.net/media/n/n/e/nne3vt4/normal.jpg" data-featherlight="image" class="item olapic-image">
	<img src="https://z3photorankmedia-a.akamaihd.net/media/n/n/e/nne3vt4/mobile.jpg">
</a>

The data-featherlight option indicates that when the UGC thumbnail is clicked, its original-sized image should be opened (referenced in the href) should open in a lightbox.

Most JavaScript lightboxes will come with a similar level of configuration.

Handling video

Olapic recently made fetching video UGC via the API possible, though including it in your carousel will likely require some changes to handle this content type, which you can see below.

Thumbnails

media.images will still return images of varying sizes. These are the thumbnails of the video.

Video source

video.source is the hosted video URL. In the case of YouTube videos, the URL will be the YouTube video link rather than the embed link.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var featherlightAttrs = ' data-featherlight="image" ';

if(mediaItem.type == 'video') {

	// add a play button to indicate this UGC is a video
	mediaEl += '<span class="play-button"></span>';

	// In case of a YouTube video, we may need to edit the URL to allow for embeds
	mediaUrl = mediaItem.video_url.replace('watch?v=', 'embed/');

	// And some featherlight attributes for displaying a video as an iframe
	featherlightAttrs = ' data-featherlight="iframe" data-featherlight-iframe-width="640" data-featherlight-iframe-height="480" data-featherlight-iframe-frameborder="0" data-featherlight-iframe-allow="autoplay; encrypted-media" data-featherlight-iframe-allowfullscreen="true" ';
}

$(".owl-carousel").append('<a href="' + mediaUrl + '" ' + featherlightAttrs + ' class="item olapic-image">' + mediaEl + "</a>");

Final code

Your final code should look like:

js/main.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
$(document).ready(function() {

  /******** Homepage Carousel - All Photos *********/
  var olapicEndpoint = "https://photorankapi-a.akamaihd.net/customers/215757/media/recent?rights_given=0&include_tagged_galleries=0&auth_token=0a40a13fd9d531110b4d6515ef0d6c529acdb59e81194132356a1b8903790c18&version=v2.2";

  $.ajax({
    dataType: "json",
    url: olapicEndpoint,
    type: "GET",
    data: {
      format: "json"
    },
 	  success: function(data) {
      // if the call is successful, get the returned UGC

      var mediaArray = data.data._embedded.media;

      // Loop through the mediaArray

      for (x=0; x < mediaArray.length; x++) {
        var mediaItem = mediaArray[x];

        // Create the UGC preview using the smallest image
        var mediaEl = '<img src="' + mediaItem.images.mobile + '" />';

        // Define a larger image resource for use in the lightbox
        var mediaUrl = mediaItem.images.normal;

        // Our default featherlight setting will be for images
        var featherlightAttrs = ' data-featherlight="image" ';

        // if the UGC is a video, we need to be overwrite some defaults...

        if(mediaItem.type == 'video') {

          // add a play button to indicate this UGC is a video
          mediaEl += '<span class="play-button"></span>';

          // In case of a YouTube video, we may need to edit the URL to allow for embeds
          mediaUrl = mediaItem.video_url.replace('watch?v=', 'embed/');

          // And some featherlight attributes for displaying a video as an iframe
          featherlightAttrs = ' data-featherlight="iframe" data-featherlight-iframe-width="640" data-featherlight-iframe-height="480" data-featherlight-iframe-frameborder="0" data-featherlight-iframe-allow="autoplay; encrypted-media" data-featherlight-iframe-allowfullscreen="true" ';
        }

        // Append the generated UGC item to the carousel
        $(".owl-carousel").append('<a href="' + mediaUrl + '" ' + featherlightAttrs + ' class="item olapic-image">' + mediaEl + "</a>");

      };

      // Set up Owl Carousel
      $(".owl-carousel").owlCarousel({
        loop: true,
        touchDrag: true,
        nav: true,
        navText: ["<i class='arrow left'></i>", "<i class='arrow right'></i>"],
        dots: false,
        navSpeed: 150,
        responsive: {
          0: {
            items:2,
          },
          767: {
            items: 3
          },
        }
      });
    },
    error: function(error){
      console.log(error);
    }
  });
});

Further reading

And that’s it! You now have a working UGC carousel.

Finished Carousel

With some additional CSS, you can style the carousel as you please to match your brand design guidelines.

Analytics API

It’s important to note that with an API-built Olapic implementation, analytics calls must be implemented separately. You’ll be able to capture all relevant UGC interactions using the Analytics API documentation