Try our conversational search powered by Generative AI!

Carlos Colon
Mar 3, 2017
  2557
(8 votes)

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/ 

[2] Full tutorial code:

Block: https://github.com/episerver/SocialAlloy/tree/master/src/EPiServer.SocialAlloy.Web/Social/Blocks/Ratings/LikeButtonBlock.cs

Controller: https://github.com/episerver/SocialAlloy/tree/master/src/EPiServer.SocialAlloy.Web/Social/Controllers/LikeButtonBlockController.cs

Model: https://github.com/episerver/SocialAlloy/tree/master/src/EPiServer.SocialAlloy.Web/Social/Models/Ratings/LikeButtonBlockViewModel.cs

[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

Mar 03, 2017

Comments

Please login to comment.
Latest blogs
Optimizely and the never-ending story of the missing globe!

I've worked with Optimizely CMS for 14 years, and there are two things I'm obsessed with: Link validation and the globe that keeps disappearing on...

Tomas Hensrud Gulla | Apr 18, 2024 | Syndicated blog

Visitor Groups Usage Report For Optimizely CMS 12

This add-on offers detailed information on how visitor groups are used and how effective they are within Optimizely CMS. Editors can monitor and...

Adnan Zameer | Apr 18, 2024 | Syndicated blog

Azure AI Language – Abstractive Summarisation in Optimizely CMS

In this article, I show how the abstraction summarisation feature provided by the Azure AI Language platform, can be used within Optimizely CMS to...

Anil Patel | Apr 18, 2024 | Syndicated blog

Fix your Search & Navigation (Find) indexing job, please

Once upon a time, a colleague asked me to look into a customer database with weird spikes in database log usage. (You might start to wonder why I a...

Quan Mai | Apr 17, 2024 | Syndicated blog

The A/A Test: What You Need to Know

Sure, we all know what an A/B test can do. But what is an A/A test? How is it different? With an A/B test, we know that we can take a webpage (our...

Lindsey Rogers | Apr 15, 2024

.Net Core Timezone ID's Windows vs Linux

Hey all, First post here and I would like to talk about Timezone ID's and How Windows and Linux systems use different IDs. We currently run a .NET...

sheider | Apr 15, 2024