Recently, I came around a problem with the Disqus comment system while fixing a random WordPress theme. The theme had individual blog posts where the Disqus module loaded as intended, but the top level blog listing (blog homepage so to say), which pulled 3 full posts per page, seemed to load only the default WordPress comments.
I took a nosedive at the issue (read: visited Stack Overflow and queried Google) and realized it’s a relatively known problem, but the prime solution on collaborable.com that everyone was pointing to was gone (no web archive, no google cache, thing just went poof). So I fired off some tribal hipsterstep and entered the DOM swamp.
First of all, let’s say why multiple modules on a page are a deal breaker. Disqus uses global variables for itself and it’s configuration (window.DISQUS, disqus_identifier, disqus_url, disqus_shortname,…) and plants itself into a unique id “disqus_thread” element. That’s not an entirely kosher situation in regard to the intention of loading multiple at the same time. The problem at hand is therefore loading the Disqus module with the unique page identifier and not loading more than one on a single page at a time as the DOM would implode. I realized a solution can be achieved in 2 ways with different results:
- Load the Disqus threads in iframes under each post and somehow control the iframe height so it matches the Disqus height, including a height refresh on certain events (like new comment). This would practically enable multiple threads on one page visible at a time thanks to the iframes. I chose not to pursue this solution however as it feels problematic, but there are people who did. http://blog.devinterface.com/2012/01/how-to-insert-more-disqus-box-in-single-page/
- Create some sort of “show comments” control under each post that would load the relevant module and display it. Once a different control was clicked, the HTML would move to the new location and DISQUS would be reloaded with new parameters. This article will further expand on this idea.
Important: This is not possible to do in a clean way using the 2012 version of Disqus, as it misses the DISQUS.reset() method as of the time of writing this article. You must switch to the old version to use the reset() method or rewrite your script in a different way (cleaning the DOM/HTML of Disqus manually).
Let’s start with the control set for loading the Disqus module in a form of a “show comments” link below each individual post that would point to some function outside and pass all the necessary attributes for loading Disqus for the first time or resetting it with new parameters if it was already loaded. Mind me using jQuery for some simplified DOM manipulation and more importantly, mind the post id and guid used as the identifier (WordPress stored the original page url in case it changes for various reasons and Disqus uses it to identify the original content it belongs to) – the following code will therefore only work if you’re using the Disqus WordPress plugin as it will use the internal guid, not pretty permalinks. You can of course manually adjust the parameters if you’re using a different system or static pages. With regards to your specific blog template listing loop, something like this will do.
<div class="this-is-single-post-wrapper"> <!-- this part will likely contain individual post data --> <a onclick="loadDisqus(jQuery(this), '<?= $id ?> <?= $post->guid ?>', '<? the_permalink() ?>');"> Show comments </a> </div>
Armed with the controls, let’s create a generic outside function that seals the deal. Put that in a file somewhere, in the page header or anywhere you like.
That’s pretty much it.