开发者

Several disqus-threads on one page

开发者 https://www.devze.com 2023-02-10 07:37 出处:网络
开发者_StackOverflow社区we have a website where we have list a lot of events, and would like to add discussions to each of the events.

开发者_StackOverflow社区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


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.


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/


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


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);
        })();
    }-*/;
}


Tente isso:

<div class="showDisqus" data-title="MyTitle" data-id="1" data-url="mysite.com/mypost">Show Comments</div>

$('.showDisqus').on('click', function(){   // click event of the show comments button
    var this_ = $(this);
        disqus_shortname = 'your_shortname',
        title = $(this).attr('data-title'),
        identifier = parseFloat($(this).attr('data-id')),
        url = $(this).attr('data-url');

    if (window.DISQUS) {

        DISQUS.reset({ // Remove the old call
          reload: false,
          config: function () {
          this.page.identifier = window.old_identifier;
          this.page.url = window.old_url;
          this.page.title = window.old_title;
          }
        });
        $('.showDisqus').show();
        $('#disqus_thread').remove();

        $('<div id="disqus_thread"></div>').insertAfter(this_);

        setTimeout( function() { // Creates a new call DISQUS, with the new ID
            DISQUS.reset({
              reload: true,
              config: function () {
              this.page.identifier = identifier;
              this.page.url = url;
              this.page.title = title;
              }
            });
            window.old_identifier = identifier;
            window.old_url = url;
            window.old_title = title;
        });

    } else {

        var disqus_identifier = parseFloat(identifier),
            disqus_title = title,
            disqus_url = url;

        $('<div id="disqus_thread"></div>').insertAfter(this_);

        (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);
        })();

        setTimeout( function() { // Sorry, there must be a better way to force the ID called correctly
            DISQUS.reset({
              reload: true,
              config: function () {
              this.page.identifier = identifier;
              this.page.url = url;
              this.page.title = title;
              }
            });
        },500);

        window.old_identifier = identifier;
        window.old_url = url;
        window.old_title = title;

    }
    $(this).fadeOut();  // remove the show comments button
});


I iterated through the solutions above, and none worked out of the box. Checking through source, I cobbled this, which works. It's not far off, but makes all the difference it seems.

<script type="text/javascript">
var disqus_shortname  = 'superchocolate',
    disqus_identifier = 'default',
    disqus_title      = 'I Heart Chocoloate',
    disqus_config     = function(){
        this.language = 'en';
    };


(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);
})();



function loadDisqus( identifier, url, title )
{
    DISQUS.reset({
        reload: true,
        config: function ()
        {
            this.page.identifier = identifier;
            this.page.url        = url;
            this.page.title      = title;
            this.language        = 'en';
        }
    });
}
</script>

In your markup, put the standard:

<div id="disqus_thread"></div>

And then in your click actions, it's pretty simple. I had a member called 'data' that I was getting back from an AJAX call.

loadDisqus( 'ugc-' + data.id,  location.protocol+'//'+location.hostname + "/ugc-submission-" + data.id + "/", data.title );

This worked for me, solving a problem in the code above that had similar comments being passed between several threads.

I'm showing my Disqus thread in a Bootstrap modal, I call loadDisqus before the call to $(el).moda('show') and it is seamless.


I know this question is very old but as I have faced the same issue I found a work around that worked pretty good for me.

I currently have a page - lets call it Album - that lists a series of images belonging to that album.

Clicking on an image will pop up a lightbox with the current image and a special sidebar that fetches via ajax current image information such as title, date, author, comments etc.. (Very similar to facebook image viewer/sidebar comments)

I wanted users to be able to comment on the main album page but also on the specific image they are viewing inside the lightbox sidebar.

Thanks to some callback functions that belong to the lightbox, one was run whenever lightbox was opened, which I have used to rename temporarly the div 'disqus_thread' in the main album page to something else.

Another callback was run whenever you changed images inside the lightbox - which allowed me to reload the sidebar information regarding the image where I have included a new disqus_thread div and a javascript forcing a disqus_reset.

And the other callback runs when the lightbox closes which allows me to rename the album comment div back to disqus_thread and force another reset.

So to summarize, the main page contains the comments for the album, when you click on an image I rename the original div to something else. Then some information is fetched via AJAX which contains a new disqus_thread div. I use DISQUS.reset and the comments load on the lightbox. When I close the lightbox I rename the original div back to disqus_thread and force another reset.

I hope it helps someone!


You could load each instance in through an iframe. You might have to have in-page scroll bars though... yuck.

0

精彩评论

暂无评论...
验证码 换一张
取 消