Rendering SEO Friendly Disqus Comments Into Your Umbraco View

|

Before I go on, I have to give a tip of the hat to Matt @ The Outfield for their original post about doing this using XSLT. I don’t use or like XSLT, so had to update it to use C# and to use it with Umbraco MVC.

As Matt explains in his post, the problem with Disqus comments is that it’s JavaScript driven. So, to the search engines not of those comments exist on your blog post. So, if you have a great blog post, with some amazing in-depth replies on a specific topic.

You will get no organic benefit from them, which (If the topic has some good and technical replies) is a real shame because you are not benefiting fully from your post. I’m not going to go into detail about setting up Disqus, you can either read Mats post above or go to the Disqus site for that. This post assumes you already have Disqus comments on your blog.

One thing you need to add to make this work is the disqus_identifier variable where your Disqus JavaScript code below, and pass in the current page node Id – This is what we’ll use with the Disqus API to tie the comments to the post (See example below)

<script type="text/javascript">
var disqus_shortname = 'YOURSHORTNAMEHERE';
var disqus_identifier = '@Model.Id';
(function () {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; 
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

Once you have done this, you need to go and register on the Disqus API to get a Secret Key which is needed to get the comments. Go to

http://disqus.com/api/applications/register/

You have to register, even though we are not really using the API properly. Just put in what you want, and click register. Once you have registered, you need to go to the settings

settings

Important: make sure you add in the domains you are going to use this on, if you don’t then you’ll get 400 and 403 errors when trying to call the comments url from the method below. Once you have done this, go to the details tab and make note of your Secret Key.

secret

Now you have this, you need to create the Model we’ll use to get the comments. Create the following class below

public class DisqusComment
{
//dc:creator
public string CommenterName { get; set; }




//content:encoded
public string Comment { get; set; }
}

Now add the following method to your site, we have a BlogRepository and it lives in there

public IList<DisqusComment> GetDisqusComments(string shortName, string pageId, string secretKey)
{
var commentList = new List<DisqusComment>();




const string disqusUrl = "https://disqus.com/api/3.0/threads/listPosts.rss?forum={0}&thread:ident={1}&limit=100&api_secret={2}";




var request = (HttpWebRequest)WebRequest.Create(string.Format(disqusUrl, shortName, pageId, secretKey));
var response = (HttpWebResponse)request.GetResponse();




using (var receiveStream = response.GetResponseStream())
{
var rssFeed = new XmlDocument();
if (receiveStream != null)
{
rssFeed.Load(receiveStream);
var nodes = rssFeed.GetElementsByTagName("item");
foreach (XmlNode node in nodes)
{
var comment = new DisqusComment
{
Comment = node["content:encoded"].InnerText,
CommenterName = node["dc:creator"].InnerText
};
commentList.Add(comment);
}
}
}
return commentList;
}

As you can see this method takes in three parameters

  1. shortName = The short name you get from Disqus, this is the value in the disqus_shortname variable in your original Javascript.
  2. pageId = This is the node id of the page you are on.
  3. secretKey = This is the secret key you got from the Disqus API page.

We have this in an Action in our BlogSurfaceController

[ChildActionOnly]
public ActionResult GetDisqusComments()
{
return View(_blogRepository.GetDisqusComments(AppConstants.DisqusShortName, CurrentPage.Id.ToString(), AppConstants.DisqusSecretKey).ToList());
}

and just pass the results directly to a partial, like so

@model List<DisqusComment>
@foreach (var comment in Model)
{
<p><strong>@comment.CommenterName</strong></p>
@Html.Raw(comment.Comment)
}

The last thing to do is put this on the page

<div id="disqus_cache">
@Html.Action("GetDisqusComments", "BlogSurface")
</div>

And in your style sheet set #disqus_cache to display:none;  - Now, when the page loads the javascript comments will load, but also the comments in your page but they are hidden from view.

Afterthought

We were getting odd intermittent 403 errors when trying to request the Disqus Url, and for us it turned out that we got these when a blog post didn't have any comments. So, for a down and dirty fix we wrapped the call to the URL in a try catch statement which solves the problem.

from the blog Adding Responsive Client Side Images To Umbraco

Full Article