Loading Disqus Threads Dynamically

Since many use the internet primarily for social media, there is an increasing need for a comment system on virtually every website. While Disqus provides an easy-to-use comment system, it is not immediately compatable with the other movement emerging in the world of web develoment: dynamic or ajax websites. Ajax, as demonstrated by this website, allows the site to be dynamically loaded and changed as the user interacts with the site. This site uses that technique to load new pages without actually changing the page in the browser, allowing for a more streamlined and immersive experience. An issue arises, however, when wedding ajax websites to the Disqus system. The Disqus system loads the Disqus Identifier only once, when the page is loaded. Since the page is never reloaded in ajax-based sites, there will be only one thread for every page. Disqus graciously provides a way to reload the Disqus thread via ajax, but the documentation is lacking in specifics. So I hope to use my experience to explain how to dynamically reload the Disqus thread.

Installation

For a basic installation Disqus gives the following code to copy and paste onto your page:

<div id="disqus_thread">&nbsp;</div>
<script type="text/javascript">// <![CDATA[
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'example'; // required: replace example with your forum shortname

    /* * * 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 class="dsq-brlink" href="http://disqus.com">blog comments powered by <span class="logo-disqus">Disqus</span></a>

For dynamically loading a Disqus thread, you initialize it the exact same way except you assign an ID to the script element that is dynamically loaded:

<div id="disqus_thread">&nbsp;</div>
<script type="text/javascript">// <![CDATA[
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'example'; // required: replace example with your forum shortname
  
    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.id = "dsq_js";
        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 class="dsq-brlink" href="http://disqus.com">blog comments powered by <span class="logo-disqus">Disqus</span></a>

HTML

Now we need to place the HTML so that our script knows where to place the comment thread when its reloaded.

<div class="disqus_placeholder" id="__disqus_identifier__"></div>

I use the class .disqus_placeholder to signify all place holders and use the ID to store the Disqus Identifier (here represented by __disqus_identifier), which for this site is the page ID give by my custom CMS.

Javascript

How exactly you call the following depends on what sort of solution you need. I will give you a basic function which you can call in various ways. For example, you could call the following function when a user clicks a link with a certain class, or you can call it when the history is changed.

$('#disqus_thread').appendTo('#'+hash+'_div .disqus_placeholder');
$('#disqus_thread').css('display','block');
disqus_identifier = $('#'+hash+'_div .disqus_placeholder').attr('id');
if (typeof DISQUS != 'undefined') {
        DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = disqus_identifier;
            this.page.url = "http://lejeunerenard.com/ljr_rev_2/hash_redirect.php?hash="+hash+'#!newthread';
          }
        });
} else {
        $('#dsq_js').live('load',function(){
                DISQUS.reset({
                  reload: true,
                  config: function () {
                    this.page.identifier = disqus_identifier;
                    this.page.url = "http://lejeunerenard.com/ljr_rev_2/hash_redirect.php?hash="+hash+'#!newthread';
                  }
                });
        });
}

First the Disqus thread div is appended to the Disqus placeholder div for that specific page div and then made visable. Then the disqus identifier is obtained by querying the ID of the placeholder div. Since we cannot be sure at this point that the Disqus script had been loaded, we now check to see if the DISQUS variable has been defined. If it is, then we use the reset function that Disqus provided, setting the identifier to what we previously extracted from the placeholder ID and setting the url to whatever url signifies the current ajax state. In this case, the current ajax state is represented by a php redirect script that is given the current history hash as a GET parameter. This php redirection will be explained below. If the DISQUS variable is not defined, we use the jQuery live function to set a callback function, which reloads the Disqus thread in the same fashion as previously mentioned, to be fired once the Disqus script is finished loading.

PHP Redirection Script

Now to explain why I set the url to a php script instead of the normal site url followed by a history hash. If you noticed, there is a hash bang, '#!newthread', at the end of the url. This hash bang is required by Disqus to process and reload the new thread. If we left our history hash on the url, Disqus gets confused and does not see the second hash, therefore breaking the reload.

To work around this, I created a redirect php script that takes the hash as a GET param and then sends a redirect back to the browser with the hash at the end of the site url. This way, the url given to Disqus is not confusing and when Disqus uses the url to redirect Disqus users, it will actually redirect them to the appropriate url.

Here is the PHP script:

<?php
header( 'Location: http://lejeunerenard.com/ljr_rev_2/#'.$_REQUEST['hash']  ) ;
?>

Conclusion

By using a placeholder that stores the identifier for the Disqus thread, we are able to move the Disqus thread to the proper location and then reload it giving it the appropriate settings. Now we have a dynamically loaded comment system for our ajax website.