Fixing some quirks with Disqus comments in WordPress

So recently I’ve relaunched my blog, with that came A LOT of offline time (busy with irl etc etc). I develop various projects on localhost environments but one thing that doesn’t play nice with localhost is Disqus comments. This is because it requires a live top level domain with the correct permalinks to each post (or discussion in this case), so of course while my blog was under development this got quite badly out of sync and started to slowly break. Putting my blog back online and chaos ensued on the comments front, its getting back to normal now, but I had quite an adventure solving some interesting quirks.
Note: Before I start I’d like to mention I also did a domain migration during this process hence why my experience might be a tad crazy, but hopefully for generic issues this helps you as well. I use the WordPress Disqus plugin for Disqus functionality. These guidance notes/tips generally only apply to WordPress when using the official Disqus plugin
Comment count shows a different value before Disqus loads
This was the first issue I noticed after putting my blog online again. To understand this issue you need to remember Disqus comments actually loads on top of WordPress and its built in comments system. If you’ve checked out the plugin source code, you’ll find Disqus loads itself via JavaScript. In my case, it seems there were quite a lot of discrepancies in the comment counts. WP comments would hold a value different to Disqus, causing a different number to appear before Disqus loaded.
Solving this one was a bit hackish, but was done in my theme template:
// WP comments and Disqus may have a different counts, hence blank the WP comment values // Prevents a inaccurate number flashing before Disqus has fully loaded. if(function_exists(dsq_is_installed) && !is_preview()) { // Blank the WP comments values to avoid the above comments_popup_link('', '', '', 'comments-link', '0'); } else { // In case the plugin is borked or disabled comments_popup_link('0', '1', '%', 'comments-link', '0'); }
What we have here are two comments_popup_link references, however a conditional is used depending on the situation. The conditional is basically logic to check if Disqus is enabled, using a function that will equal true when the plugin is active and is likely to be at least configured to a functioning state. The is_preview() function is actually a WordPress function. When using the preview post system, Disqus comments are not loaded, adding the !is_preview() means the else block further down will at least display a comment count, its more of a aesthetic really. You’ll notice the first instance of comments_popup_link blanks the first 3 values, this resolves the comment count showing to different values is WP comments and Disqus disagree on the amount of comments.
Fixing rel validation issues when using HTML5
Like valid HTML code? So do I, so imagine my displeasure when I found out Disqus was putting invalid code in my blog with invalid rel usage!
You may have discovered this error in W3C validation when using Disqus comments:
Attribute rel not allowed on element span at this point.
To fix this required a direct plugin edit, in the snippets below the exact line number is referenced with the modified code. You’ll need to make these edits in the disqus.php file found within /wp-content/plugins/disqus-comments-system
return '<span class="dsq-postid" data-comm="'.htmlspecialchars(dsq_identifier_for_post($post)).'">'.$comment_text.'</span>';
nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('data-comm'));
nodes[i].parentNode.setAttribute('data-disqus-identifier', nodes[i].getAttribute('data-comm'));
Be careful not to change any other rel attribute instances, otherwise you’ll break the plugin, only the modify the lines above. Doing this will fix the invalid rel instances.
API errors?
Looks like in the most recent version Disqus made some changes to their API functions within the WordPress plugins, problem is if your on some shared hosting that is very restrictive in terms of outbound connections you may find you receive this error:
Unable to connect to the Disqus API servers
Ouch. In order to explain this one, check out url.php located within /wp-content/plugins/disqus-comment-system/lib/api/disqus/. Scroll down to line 260
// Try curl, fsockopen, fopen + stream (PHP5 only), exec wget if(function_exists('curl_init')) { if (!function_exists('curl_setopt_array')) { function curl_setopt_array(&$ch, $curl_options) { foreach ($curl_options as $option => $value) { if (!curl_setopt($ch, $option, $value)) { return false; } } return true; } } _dsq_curl_urlopen($url, $postdata, $response, $file_name, $file_field); } else if(ini_get('allow_url_fopen') && function_exists('stream_get_contents')) { _dsq_fopen_urlopen($url, $postdata, $response, $file_name, $file_field); } else { // TODO: Find the failure condition for fsockopen() (sockets?) _dsq_fsockopen_urlopen($url, $postdata, $response, $file_name, $file_field); }
Basically the plugin will attempt to connect to the Disqus API via a variety of methods, if for whatever reason they all fail, you are pooched (well not quite). The fallback method _dsq_fsockopen_urlopen will be available to you. Why are the other methods blocked? Well that’s really down to your server configuration, if your on shared hosting, its likely there is nothing you can do. Shared hosting configurations will be generally locked down (well good ones will) disabling the above methods. If your on a VPS or have root access to the webserver, you can either install and configure curl with php, or modifying your php.ini to enable allow_url_fopen requests, though that is pretty dangerous. Another dirty hack is to change the block of code to this:
// /* // Try curl, fsockopen, fopen + stream (PHP5 only), exec wget if(function_exists('curl_init')) { if (!function_exists('curl_setopt_array')) { function curl_setopt_array(&$ch, $curl_options) { foreach ($curl_options as $option => $value) { if (!curl_setopt($ch, $option, $value)) { return false; } } return true; } } _dsq_curl_urlopen($url, $postdata, $response, $file_name, $file_field); } else if(ini_get('allow_url_fopen') && function_exists('stream_get_contents')) { _dsq_fopen_urlopen($url, $postdata, $response, $file_name, $file_field); } else { // TODO: Find the failure condition for fsockopen() (sockets?) _dsq_fsockopen_urlopen($url, $postdata, $response, $file_name, $file_field); } */ // My host doesn't work with the above, please let me connect to the API *sadface* _dsq_fsockopen_urlopen($url, $postdata, $response, $file_name, $file_field); }
Leave everything else in tact, and this should sort your API issues. There are better ways of doing this, but hey, I warned you, dirty hacks.
That pretty much concludes my Disqus adventure, hopefully it can help you solve some of the quirks with Disqus on WordPress!