Tutorial Time: Building a Featured Videos Block in Episerver
John McKillip#Episerver, #Tutorials
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:
- 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.
- 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.
Related Posts
Custom Fields and ElasticSearch
Diagram's Ryan Duffing offers a tutorial on indexing and retrieving custom fields with Epinova.Elasticsearch for Optimizely (formerly Episerver).
7-Step Guide to Effective Social Media Ads
We share how to plan a successful paid social media campaign in 7 easy steps.
Results Matter.
We design creative digital solutions that grow your business, strengthen your brand and engage your audience. Our team blends creativity with insights, analytics and technology to deliver beauty, function, accessibility and most of all, ROI. Do you have a project you want to discuss?
Like what you read?
Subscribe to our blog "Diagram Views" for the latest trends in web design, inbound marketing and mobile strategy.