Building a Like button with Episerver Social Ratings
Overview
In this tutorial, we are going to show how to build a Like button with the Episerver Social Ratings service API [1]. A Like button has a few simple requirements:
- Track the total number of times the Like button was clicked.
- Determine if a user with a known identity has already Liked the page.
For the purposes of this tutorial and to keep the implementation simple, the tutorial code will let anonymous users rate as many times as they choose. The full source code for the tutorial is available in our SocialAlloy github.com repo [2].
Prerequisites
To use the Social Ratings service API, install the EPiServer.Social.Ratings NuGet package, available in the Episerver NuGet feed [4], to your project or solution. If using the Social Ratings service API in an Episerver site, you should also install the EPiServer.Social.Ratings.Site package to leverage Episerver’s ServiceLocator container to create the Social Ratings service instance. The SocialAlloy repo [2] already has these packages installed and will be restored when the solution is built.
Building the Like button
Keep in mind that the full source in the SocialAlloy repo [2] is for educational purposes and is not production quality. As implemented, the Like button has the following components:
1. An Episerver Block
A block is used to add a Like button to any page in the SocialAlloy site.
2. A Like button controller
The Like button controller is the business logic implementation of the Like button functionality. The controller has three public methods:
- Constructor method – In the constructor, global resources needed by other public methods are allocated. The controller needs an instance of the ratings service to be able to retrieve and save Like ratings. Installing the EPiServer.Social.Ratings.Site package enables the use of Episerver’s ServiceLocator to allocate that instance.
this.ratingService = ServiceLocator.Current.GetInstance<IRatingService>();
- Index method – This method contains the business logic that renders the block’s front end view in whatever page the block is currently executing on. As for the ratings API usage, the critical parts of this method are:
- Get the rating for a user with an identity (does not apply to anonymous users). The rating filter is supplied with a user rater and page target references. Since a count of only one item is expected to match the criteria, we specify a PageSize of one.
var ratingPage = ratingService.Get(
new Criteria<RatingFilter>
{
Filter = new RatingFilter
{
Rater = raterUserRef,
Targets = new List<Reference>
{
targetPageRef
}
},
PageInfo = new PageInfo
{
PageSize = 1
}
}
);
- Get Like statistics for the current page. We are interested in the total number of Likes the current page has received across all users.
var ratingStatisticsPage = ratingService.Get(
new Criteria<RatingStatisticsFilter>
{
Filter = new RatingStatisticsFilter
{
Targets = new List<Reference>
{
targetPageRef
}
},
PageInfo = new PageInfo
{
PageSize = 1
}
}
);
- Submit method – This method contains the business logic that handles a user clicking the Like button in the block’s front end view in whatever page the block is currently executing. As for the rating API usage, the critical functionality of this method is to use the rating service Add API to save the Like for the user (rater) and the current page (target). Because Like is a very simple rating, we store the rating as Liked_Rating = 1.
var addedRating = ratingService.Add(
new Rating(
raterUserRef,
targetPageRef,
new RatingValue(Liked_Rating)
)
)
3. A Like button block front end view model
The controller needs to provide data to the Like button view. We need a model to store that data, so the view can access it while it is rendered. The Like button block view model is implemented as follows:
public class LikeButtonBlockViewModel
{
public LikeButtonBlockViewModel(){}
public PageReference PageLink { get; set; }
public long TotalCount { get; set; }
public int? CurrentRating { get; set; }
}
The empty constructor is required by the CMS framework, since it needs to create the model when the block view form is submitted back to the server. We also need the reference to the current page for use by the Like button click handler on the server side. The TotalCount and the CurrentRating are rating specific properties.
- TotalCount stores the total count of clicks across all users.
- CurrentRating stores the Like rating (i.e., Liked_Rating) for the current user, if any.
4. A Like button view
The Like button block needs a view to render itself in the front end. That view is implemented as follows:
<div class="border">
<div style="margin-top:0.5em">
@if (Model.CurrentRating.HasValue)
{
<div> You have already <i class="icon-thumbs-up"></i> this page! </div>
}
else
{
using (Html.BeginForm("Submit", null))
{
@Html.HiddenFor(m => m.PageLink)
<div>
<button name="submitsocialrating" value="Submit" class="btn-primary"><i class="icon-thumbs-up"></i> Like </button>
</div>
}
}
<br/>
<div><strong>Likes: @Model.TotalCount</strong></div>
</div>
</div>
If there is a rating value for the current user, meaning the user has previously Liked the page, then the view reflects that. In that case, do not allow the current user to Like the page again by not displaying the Like button.
If there is no Like rating value for the current user, which is always the case for anonymous users, then display the Like button. Finally, the view shows the total count of Likes for the page across all users.
References
[1] Episerver Social Developer Guide -- http://world.episerver.com/documentation/developer-guides/social/
[3] Tutorial code views -- https://github.com/episerver/SocialAlloy/tree/master/src/EPiServer.SocialAlloy.Web/Views/Social
[4] Episerver NuGet feed -- http://nuget.episerver.com/feed/packages.svc
Comments