Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An Introduction to Disqus (Pluggable Commenting System) with ASP.NET MVC 3

0.00/5 (No votes)
31 Jul 2013 1  
This article discusses ways by which you could utilize Disqus in your web applications.

Sample Image - maximum width is 600 pixels

Introduction

How many times have you found yourself designing a commenting system? Several times, right? This is exactly true in my case working with a number of projects! For a number of applications I have worked on, I designed the entire commenting module myself, starting from the tables to the code. But for my most recent project, I wanted to step aside from this method of handling comments. In this article I am going to introduce you all to Disqus, which is a pluggable commenting system that could be used across various applications with very little amount of code! This article uses ASP.NET MVC 3, but this example could be pretty much used anywhere. As a side note, I am in no way related to Disqus as a company. I was impressed by the simplicity of using this and hence I wrote this article. More details follow in the subsequent sections. This article covers two topics. To begin with, I introduce how Disqus could be used in a simple ASP.NET MVC 3 application. Then I discuss a method by which Disqus can be "ajaxified".

Background

Earlier I specified how I go about designing commenting systems in a few words. It does not just end with a simple table and a few lines of code to insert/ delete comments. There is much more to designing a commenting system. A few things to consider while designing a full-fledged commenting system are - whether to allow a thread based commenting system or a flat commenting system, provide the ability to block spam, whether users have to sign up, or can just post as a guest, and so on and so forth. In order to free ourselves from all of these hassles, we can use a pluggable commenting system like Disqus which provides all of these features in-built. Using Disqus in your website is as simple as registering for a disqus shortname and adding a few lines of JavaScript and HTML! Let us get straight in to the article!

Basic Disqus Functionality 

In this section I am going to discuss how basic Disqus commenting can be introduced to a page in our application. The first step is to register for a Disqus short name by going to this address - https://disqus.com/admin/signup/. Site Shortname is the most important attribute you need to remember, because you have to use this shortname for Disqus to identify your site. Once you are done with this step, you are already ready to use Disqus in your site.

Getting Started with the Sample Project

Before getting to the actual fun part, let me talk a bit about the sample application. The sample project provided along with this article is pretty simple and straightforward. It contains two pages - one for the basic functionality and one for AJAX based implementation. To get started, download the project's zip file and extract it. Now open the project with Visual Studio and open the web.config file. The <appSettings /> section contains a key called DisqusShortName which initially does not contain anything. You will have this ready at this point if you had followed the steps in the earlier section. Enter your application's Disqus short name. Now hit Ctrl + F5. You are all set to use the sample application now!

Back to the Basics!

Time for some code at last. Let me get to the first approach of using Disqus! Given below is the complete listing of a page that implements basic Disqus functionality.

@using DisqusTutorial.Infrastructure
@{
    ViewBag.Title = "Disqus Default Behavior";
}

<h2>Disqus Default Behavior</h2>

<div>
    <input type="hidden" id="rootUrl" value="@string.Format("{0}://{1}{2}", 
            Request.Url.Scheme, Request.Url.Authority, Url.Content("~"))"/>
    <div id="disqus_thread"></div>
    <script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = '@ApplicationConfiguration.DisqusShortName';
        // required: replace example with your forum shortname

        var disqus_identifier = 'hello-world';
        var disqus_url = $('#rootUrl').val() + disqus_identifier;
        var disqus_developer = 1;

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function () {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || 
               document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script>
    <noscript>Please enable JavaScript to view the 
      <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
    <a href="http://disqus.com" class="dsq-brlink">comments powered 
      by <span class="logo-disqus">Disqus</span></a>        
</div>

It cannot get any simpler than this! At this point, I guess it's important to discuss the above code listing line by line! I am going to ignore lines 1 to 8 as there  is nothing important there and is just the usual stuff. Line 9 is just a hidden field that supplies the root URL of this website. This is just a basic example and so I did not want to complicate this sample by using view models in order to bind the root URL and various other things you are going to see in the subsequent lines of code. I wanted to say this before you start shouting "this is not clean, it could have been done better..." Smile | <img src=. The root URL is very important to implement Disqus since Disqus differentiates between two comment threads using the following three properties, for which the root URL is used:

  • Disqus short name - explained earlier.
  • Disqus identifier - as the name implies, a string of characters that uniquely identifies a comment thread. It is important that you come up with unique values so that there is no conflict within your application itself.
  • Disqus URL - a combination of the root URL of the site combined with the Disqus identifier so that you could access the discussions for a thread any time. Note that this should be a complete URL and not just a relative URL.

Getting back to the discussion, line 10 defines a div within which all of the comments and the text box for users to enter new comments will be rendered by Disqus. Note the ID, which is disqus_thread as Disqus expects the ID to be exactly this in order to load the comments. Lines 13 - 15 represent properties required by Disqus to uniquely identify a thread as explained earlier. Line 16 is very important. While you are developing your application, your root URL (for example) will be http://localhost:8080. Disqus cannot resolve this URL for obvious reasons. In order to inform Disqus that the application is now running in Developer mode, we have to set the disqus_developer variable in line 16 to 1. Without this, Disqus comments won't load.

Lines 19 - 21 do the actual job of loading the required scripts for Disqus to work. In line 19, a script element is created followed by setting the type attribute. Then the async property is set to true implying this script will be loaded asynchronously. Thus any activity to be performed has to wait until the script is fully loaded. Once the src attribute is specified (in the next line), loading of the script begins. Note the format of the JavaScript file loaded. When you signed up, Disqus also created a site for you (<shortname>.disqus.com) which contains an embed.js script. Then in line 21, the script element created is appended to the head element.

Once the script is loaded, Disqus uses the three properties listed above to load the discussion corresponding to the unique identifier. The result is something similar to this:

Sample Image - maximum width is 600 pixels

AJAXifying Disqus

Now let's get to the most exciting part of this article! Disqus already has enough information to get started with it in order to use the default behavior. But there isn't enough information on how to get Disqus to work on a page that works fully on AJAX. I am working in a project where I need such a functionality. In the case of my project, the page's URL won't change and thus there is no full refresh at all in the page unless the user navigates to some other page by clicking on the top level navigation. Every possible interaction with the server is done through AJAX, and so it was required to reload the Disqus comments depending on the identifier returned by the server as and when a new section is loaded.

Disqus provides a method by which we could "reload" comments using the required parameters (specified earlier). This ability is used to "load" the comments depending on the information from the server. To keep it simple, in this section I am going to explain this method with just three Disqus comment threads. The layout of this page is simple - it contains three links, one each for the three possible comment threads. Then as before, there is a div element with the ID disqus_thread where Disqus will load the comments asynchronously.

After the usual titles, usings etc., I have declared the four variables just like we declared in the earlier example.

<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = '@ApplicationConfiguration.DisqusShortName';
    // required: replace example with your forum shortname

    var disqus_identifier = '';
    var disqus_url = '';
    var disqus_developer = 1;
</script>

Here is the plain HTML required for this page. It contains a link each for loading three different comment threads, a hidden field for the root URL, an element for the comments itself, and some generic links for Disqus.

<div id="controls">
    <div style="float: left">
        <a id="btnPrevious" href="javascript:void(0)"><< Previous</a>
    </div>
    <div style="text-align: center">
        <a id="btnInit" href="javascript:void(0)">First</a>
    </div>
    <div style="float: right">
        <a id="btnNext" href="javascript:void(0)">Next >></a>
    </div>
</div>
<br/><br/>
<input type="hidden" id="rootUrl" value="@string.Format("{0}://{1}{2}", 
   Request.Url.Scheme, Request.Url.Authority, Url.Content("~"))"/>
<div id="disqus_thread"></div>
<noscript>Please enable JavaScript to view the 
  <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments 
  powered by <span class="logo-disqus">Disqus</span></a>

As explained in the previous section, there is a hidden field which contains the root URL of the application. Now let me get to the most important aspect that makes all of this work - jQuery/JavaScript. The amount of JavaScript/jQuery required is surprisingly less! Before getting into the initializeDisqus method call in the first line, let me explain the rest. Immediately next to the initialize call, I have declared the 'click' event handlers for the three links in the page. Every event specifies a unique Disqus ID and then calls the reset method by passing the ID specified in the first step.

$(document).ready(function () {
    initializeDisqus();

    $('#btnNext').click(function () {
        var disqusId = 'another-page';
        reset(disqusId);
    });

    $('#btnPrevious').click(function () {
        var disqusId = 'yet-another-page';
        reset(disqusId);
    });

    $('#btnInit').click(function () {
        var disqusId = 'hello-world';
        reset(disqusId);
    });
});

Before getting to the reset method, let me introduce you to the initializeDisqus method, which I never did earlier! At this point, I would like to remind you all about something I said earlier - the script required for Disqus is loaded asynchronously! Given below is the listing for the initializeDisqus function:

function initializeDisqus() {
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';

    dsq.onload = function () {
        var disqusId = 'hello-world';
        reset(disqusId);
    };

    (document.getElementsByTagName('head')[0] || 
        document.getElementsByTagName('body')[0]).appendChild(dsq);
}

In this case, the first two lines do the same activity as explained before. But now, before attempting to load the comments for hello-world, I need to make sure that the scripts required by Disqus are loaded. To do the same, I use the onload event of the script object created earlier. This event is raised when the script is fully loaded. I verified that this method works in Internet Explorer, Chrome, and Firefox. Once the script is fully loaded, I call the reset function by passing in the required Disqus identifier. Now let's get to the reset method.

function reset(disqusId) {
    DISQUS.reset({
        reload: true,
        config: function () {
            this.page.identifier = disqusId;
            this.page.url = $('#rootUrl').val() + disqusId;
        }
    });
}

The Disqus API provides a reset method which is called within this function. At a bare minimum, it requires two properties - the first property reload indicates whether or not the comments should be reloaded, in this case it is set to true. The second property is a function call that sets two properties, the Disqus id (this.page.identifier) and the page's URL (this.page.url). Note that this uses the hidden field that contains the site's root URL. When this method completes, the div is reloaded with the comments for the thread identified by the Disqus identifier!

Given below are screenshots of what happens when every possible link is clicked. Disqus itself contains a loading indicator. So it's not required to add your own version of loading indicators!

After "First" link is clicked:

After First link is clicked

After "Next" link is clicked:

After Next link is clicked

After "Previous" link is clicked:

After Previous link is clicked

Disqus Discovery Options

While testing my application's feature which is purely based on AJAX, I faced an issue. The issue was that, whenever the comments for a certain section is loaded there was a section that displayed the recent comments for the Disqus site. The issue is that the URL specified is kind of a pseudo URL. By this, a separate page does not exist, however the URL has to be unique and thus it is, as shown in the above snippets. But when a user clicks something on the recent comments section, it tries to redirect to the page it identified while logging the comment for some reason and so it would fail. In simple words, if the AJAX comments are loaded in the page with URL http://localhost:8080/home/disqusajax with Disqus id hello-world and disqus URL http://localhost:8080/hello-world, instead of redirecting recent comment clicks to http://localhost:8080/hello-world, it would redirect the user to http://localhost:8080/home/disqusajax. In order to avoid recent comments from being shown, the discovery option has to be turned off as shown below under Settings // Discovery (this may not be required if you are not going to use AJAX to load a comment thread, as turning this off would mean lost traffic and/or revenue):

Disqus - turning off discovery

Points of Interest

There are a lot more avenues to explore with respect to Disqus and I am checking them out. While experimenting with Disqus for sBlog.Net (article) blogging engine's commenting system, I noticed that there is nothing with respect to Disqus in CodeProject and that made me write this article. There are also a few alternatives available that are similar to Disqus. Some of them are intense debate, Facebook comment box, coComment, and many more!

To update those interested, I was looking for a way to get the recent comments from Disqus without the use of the API and found it! It's quite simple! You just have to go to your Disqus site's RSS feed. If your short name is "example", you just have to go to http://example.disqus.com/latest.rss to get a list of the most recent comments, obviously ordered by date/time with the latest ones being first!

Remember, when you push your application that uses Disqus, you will have to remove the disqus_developer variable, so that Disqus does not identify your live application environment to be a development environment.

History

  • Initial version released.
  • Updated the Points of Interest section.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here