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 = // required: replace example with your forum shortname
var disqus_identifier = var disqus_url = $( var disqus_developer = 1;
/* * * DON (function () {
var dsq = document.createElement( dsq.src = (document.getElementsByTagName( document.getElementsByTagName( })();
</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..." .
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:
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, using
s etc., I have declared the four variables just like we declared in the earlier example.
<script type="text/javascript">
var disqus_shortname = '@ApplicationConfiguration.DisqusShortName';
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 "Next" 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):
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.