<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1639164799743833&amp;ev=PageView&amp;noscript=1">
Diagram Views

Tutorial Time: Building a Featured Videos Block in Episerver

John McKillip
#Episerver, #Tutorials
Published on May 22, 2019
warren-wong-323107-unsplash-1

In our latest tutorial, we look at how to build a "featured videos" block in Episerver using the YouTube Data API v3.

Being a developer here at Diagram, I get the chance to work on enterprise-level projects and build cool stuff every day. I wanted to share something that I built recently for a client project, because it combines two of my favorite things: working with Episerver and RESTfull API's.

Let's say you have a client that wants a section on their homepage that features the four latest videos from their sweet YouTube channel. Luckily for you, Episerver's content blocks functionality and some free NuGet packages make this a pretty easy task. Here is what you will need to get started:

  1. If you don't have one already, you will need to register for a free Google Developer account. Once you are signed up, browse to your Credentials page and create an API key. One caveat to consider for this is that if this functionality is for a client site, you will eventually want them to use their own account for the API key.
  2. In your Visual Studio project, you will need to install the RestSharp nuget package (Install-Package RestSharp) and the the Json.NET package (Install-Package Newtonsoft.Json).

The rest is all classes and views in Episerver. The gist of the functionality is that we will have a block model, a view model, a YouTube service class, and a view to render it all out. We will use a Settings block to store the API key and YouTube channel ID. The YouTube service will grab the 4 most recent videos from the channel and cache them. The view will pull the video data from that cache so that we aren't making an API call every time it renders. I have added comments to the code snippets below so you can get a good idea of what is going on.

Now, let's write some code!

Block Model:

using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer;

namespace Awesome.Models.Blocks
{
    [ContentType(DisplayName = "Featured Videos", 
        GUID = "67c6c6a6-9e74-4e4f-8533-3f1dc40a736e", 
        Description = "Sweet block to feature my YouTube videos")]
    public class FeaturedVideosBlock : BlockData
    {
        [CultureSpecific]
        [Display(
          Name = "Featured Videos Header",
          Description = "The header of this sweet block",
          GroupName = SystemTabNames.Content,
          Order = 1)]
        public virtual string VideoHeader { get; set; }

        [CultureSpecific]
        [Display(
          Name = "View All Videos Link",
          Description = "Want to see all of my sweet videos?",
          GroupName = SystemTabNames.Content,
          Order = 1)]
        public virtual Url VideosLink { get; set; }
    }
}
	

Video Data View Model:

namespace Awesome.Models.ViewModels
{
    public class YouTubeVideo
    {
        public string Title { get; set; }

        public string ID { get; set; }

        public string Image { get; set; }
    }
}

YouTube Service:

using Awesome.Models.ViewModels;
using System.Collections.Generic;
using RestSharp;
using Newtonsoft.Json.Linq;
using EPiServer.Logging;
using System.Web;
using System;

namespace Awesome.Services
{
    public class YouTubeService
    {
        // Needed to make calls to the YouTube API
        private static string ApiKey = Site.SiteSettings.YouTubeApiKey;
        private static string PlayList = Site.SiteSettings.YouTubePlaylistId;

        // To log those exceptions, son.
        private static readonly ILogger Logger = LogManager.GetLogger();

        /// 
        /// Returns a list of the latest 4 videos in a selected YouTube playlist from cache.
        /// List is cached for 12 hours.
        /// 
        public static List<YouTubeVideo> GetVideos()
        {
            string Key = "FeaturedVideos";

            List<YouTubeVideo> videos = new List<YouTubeVideo>();

            // Create the url for the request
            string url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=4&playlistId=" + PlayList + "&key=" + ApiKey;

            try
            {
                if(HttpContext.Current.Cache[Key] == null)
                {
                    RestClient restClient = new RestClient(url);
                    var request = new RestRequest(Method.GET);

                    // Execute the request
                    IRestResponse response = restClient.Execute(request);

                    // Get the response from the server
                    var content = response.Content;

                    // Let's parse that response and create our view models
                    JObject jObject = JObject.Parse(content);
                    JToken results = jObject["items"];

                    foreach (var result in results)
                    {
                        YouTubeVideo video = new YouTubeVideo();
                        // Get the title
                        JToken snippet = result["snippet"];
                        video.Title = (string)snippet["title"];
                        // Get the Video ID
                        JToken id = snippet["resourceId"];
                        video.ID = (string)id["videoId"];
                        //Get the thumbnail
                        JToken images = snippet["thumbnails"];
                        JToken image = images["medium"];
                        video.Image = (string)image["url"];

                        videos.Add(video);
                    }
                    // Insert into cache
                    HttpContext.Current.Cache.Insert(Key, videos, null, DateTime.Now.AddMinutes(720), TimeSpan.Zero);
                }
                // Pull those vids from cache
                var vids = HttpContext.Current.Cache[Key] as List<YouTubeVideo>
                return vids;
            }
            catch(Exception ex)
            {
                Logger.Debug("Something happened when trying to grab data from YouTube for the Homepage partial view.", ex.ToString());
                // Empty list so we don't crash
                return videos;
            }          
        }
    }
}

Now, all that is left is to build out your view. All you need to do is set a a razor variable like so:

 
List<YouTubeVideo> videos = new List<YouTubeVideo>(); videos = YouTubeService.GetVideos();

Once you have that, just loop through the results in your videos variable and display the data. That's it! The great thing about the latest YouTube Data API is that if you are pulling data fom a public channel, you don't need to worry about dealing with oAuth authorization. The only difficult part that I ran into was finding the actual  ID for the channel I wanted to pull data from. You would think that the ID would be in the URL of the channel, but it's not. I ended up having to play around with API Explorer to get the actual ID before I could successfully pull the data I wanted. 

As you can see, it's pretty easy to set up a re-usable block in Episerver to display data from other sources. As of the date of this blog post, I am using Episerver v9.7.3. This code should be backwards-compatible to all earlier versions of Episerver that support blocks. If you want to do something like this in a version that doesn't support blocks, just use an MVC partial view to display everything.

If you have any questions about what I've discussed here, please feel free to leave a comment below. If you're interested in finding out more about how to utilize the Episerver platform to meet the needs of your organization, please contact us, and we'll work with you to help you find success in your digital strategy.