Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Several disqus-threads on one page

we have a website where we have list a lot of events, and would like to add discussions to each of the events.

So we wanted to use disqus, and checked it out. Turns out they use global variables to configure the instance.

like;

var disqus_shortname = '';

var disqus_identifier = '';

var disqus_url = '';

This poses a problem for us, when we don't want to use the same identifier, but rather a unique one per disqus instance. tried putting each instantiation + configuration in iframes, but that really screwed up ie8. is there a better way of doing it?

So, to sum it up; several instances of disqus on one page. how? has someone else done it?

Thanks

like image 784
Espen Schulstad Avatar asked Feb 10 '11 22:02

Espen Schulstad


4 Answers

We faced a similar issue and emailed Disqus about this. They confirmed that by default they only support one Disqus module per page.

When browsing the Disqus JS documentation, I did find a solution that might work for you by loading and unloading the Disqus modules as the user interacts with the site:

DISQUS.reset({
  reload: true,
  config: function () {  
    this.page.identifier = "newidentifier";  
    this.page.url = "http://example.com/#!newthread";
  }
});

http://docs.disqus.com/help/85/

The exact implementation would depend upon your site, but this should give you a building block to start from. For example, if the event information becomes available by expanding a content area, you could load the Disqus module whenever someone expands the event content.

like image 134
Julian Avatar answered Nov 15 '22 10:11

Julian


I wrote an article about this, find it here. http://mystrd.at/articles/multiple-disqus-threads-on-one-page/

In essence, if you're fine with displaying a single module at a time and using some sort of a "show comments" control, you could do it the following way (using Wordpress and jQuery as an example, but you can adjust the content identifiers based on your needs). In a post loop, insert an extra control for each:

<a onclick="loadDisqus(jQuery(this), '<?= $id ?> <?= $post->guid ?>', '<? the_permalink() ?>');">
   Show comments
</a>

Afterwards you need a generic function that will use those post parameters and reload Disqus on demand. Mind that the 2012 version of Disqus doesn't have the reset() method yet and therefore this will not work with it.

// global vars used by disqus
var disqus_shortname = 'yoursiteshortnameindisqus';
var disqus_identifier; // made of post id &nbsp; guid
var disqus_url; // post permalink

function loadDisqus(source, identifier, url) {
    if (window.DISQUS) {
        jQuery('#disqus_thread').appendTo(source.parent()); // append the HTML to the control parent

        // if Disqus exists, call it's reset method with new parameters
        DISQUS.reset({
            reload: true,
            config: function() {
                this.page.identifier = identifier;
                this.page.url = url;
            }
        });
    } else {
        //insert a wrapper in HTML after the relevant "show comments" link
        jQuery('<div id="disqus_thread"></div>').insertAfter(source);
        disqus_identifier = identifier; // set the identifier argument
        disqus_url = url; // set the permalink argument

        // append the Disqus embed script to HTML
        var dsq = document.createElement('script');
        dsq.type = 'text/javascript';
        dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        jQuery('head').appendChild(dsq);
    }
};

Other than this, I believe you would have to resort to using iframes. Such a solution with Ruby as an example is outlined here - http://blog.devinterface.com/2012/01/how-to-insert-more-disqus-box-in-single-page/

like image 20
mystrdat Avatar answered Nov 15 '22 10:11

mystrdat


Supposedly as of 17 July 2012, Disqus 2012 now supports "reset" again.

like image 3
V Hudson Avatar answered Nov 15 '22 08:11

V Hudson


I needed to use Disqus from a GWT app, so I needed to solve the problem of loading threads on demand as virtual pages in the app were changed.

A small amount of reverse engineering and experimentation led me to construct a utility class (below).

The main insights are:

  1. There is an undocumented global parameter called disqus_container_id which allows you to place the comments wherever you like. If that doesn't work in some future version, my fallback was going to be to temporarily set the id of the target element to disqus_thread, add the comments and then change it back to the original id.
  2. Since this was being developed for GWT using JSNI, I needed to set the global parameters in the original window context, accessible through $wnd. I changed the default Disqus embed code accordingly. I didn't realise before that all global variables are in the Window object, but I learned something new.
  3. You can re-use the same container, Disqus seems to clear the contents when you activate it.
  4. This leaves lots of copies of the script tag in the DOM. Maybe it would be a good idea to clean these up too once they've been used. Alternatively, I might do some more experiments using the DISQUS.reset method described in other answers.

Extracting just the crucial information for someone using JS on its own, this should allow you to stick a Disqus thread anywhere you like:

function loadComments(container_id, shortname, identifier, developer) {
    // CONFIGURATION VARIABLES
    window.disqus_container_id = container_id;
    window.disqus_developer = developer ? 1 : 0;
    window.disqus_shortname = shortname; // required
    if (identifier) window.disqus_identifier = identifier;

    // DON'T EDIT BELOW THIS LINE
    (function() {
       var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
       dsq.src = 'http://' + shortname + '.disqus.com/embed.js';
       (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
}

And here is the full GWT utility class. I've only implemented the parameters I needed so far.

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.Widget;

public class Disqus {

    public static boolean developer = false;
    public static String shortname;

    public static void showComments(Widget where, String identifier) {
        showComments(where.getElement(), identifier);
    }

    public static void showComments(Element where, String identifier) {
        if (shortname == null)
            throw new IllegalArgumentException(
                      "You must specify the disqus shortname before displaying comments");

        // Store the original id of the target element
        String id = where.getId();
        if (id == null) {
            id = "disqus-" + Integer.toHexString(Random.nextInt());
            where.setId(id);
        }

        // Update the id temporarily
        where.setId("disqus_thread");

        // Load the comments
        loadComments(id, shortname, identifier, developer);
    }

    private static native void loadComments(String container_id, String shortname, String identifier, boolean developer) /*-{
        // CONFIGURATION VARIABLES
        $wnd.disqus_container_id = container_id;
        $wnd.disqus_developer = developer ? 1 : 0;
        $wnd.disqus_shortname = shortname; // required
        if (identifier) $wnd.disqus_identifier = identifier;

        // TODO
        // disqus_url

        // disqus_title

        // disqus_category_id

        // DON'T EDIT BELOW THIS LINE (sorry, I've edited it anyway)
        (function() {
            var dsq = $doc.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = 'http://' + shortname + '.disqus.com/embed.js';
            ($doc.getElementsByTagName('head')[0] || $doc.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    }-*/;
}
like image 1
Kothar Avatar answered Nov 15 '22 09:11

Kothar