一页上有多个Disqus话题讨论串

34

我们有一个网站,在其中列出了许多活动,并希望为每个活动添加讨论。

因此,我们想使用 Disqus 并对其进行了检查。结果发现他们使用全局变量配置实例。

如下所示;

var disqus_shortname = '';

var disqus_identifier = '';

var disqus_url = '';

这对我们来说带来了问题,当我们不想使用相同的标识符,而是每个 Disqus 实例都有一个唯一的标识符时。我试着在每个实例化+配置中放置 iframe,但这真的搞砸了 ie8。有更好的方法吗?

总之,如何在一个页面上使用多个 Disqus 实例?有其他人做过吗?

谢谢

8个回答

25

我们遇到了类似的问题,并向 Disqus 发送了电子邮件。他们确认默认情况下每个页面只支持一个 Disqus 模块。

当浏览 Disqus JS 文档时,我发现一种解决方案可能适用于您,即在用户与站点交互时加载和卸载 Disqus 模块:

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

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

具体实现取决于你的网站,但这应该为你提供了一个起点。例如,如果事件信息通过展开内容区域而变得可用,您可以在某人展开事件内容时加载Disqus模块。


我最近个人没有使用过它,但注意到人们最近仍在投票支持这个答案。所以我会认为它仍然对某些人有效? - Julian
[...] 使用2012版本无法以清晰的方式完成此操作[...]它缺少DISQUS.reset()方法[...]您必须切换到旧版本才能使用reset()方法[...] - http://mystrd.at/articles/multiple-disqus-threads-on-one-page/ - Matmarbon

17
我写了一篇关于这个问题的文章,在这里找到它。 http://mystrd.at/articles/multiple-disqus-threads-on-one-page/ 实际上,如果你只想显示一个模块并使用某种“显示评论”控件,你可以按照以下方式进行操作(以WordPress和jQuery为例,但您可以根据需要调整内容标识符)。在文章循环中,为每个插入额外的控件:
<a onclick="loadDisqus(jQuery(this), '<?= $id ?> <?= $post->guid ?>', '<? the_permalink() ?>');">
   Show comments
</a>

接下来,您需要一个通用函数,该函数将使用这些帖子参数,并根据需要重新加载Disqus。请注意,Disqus 2012版本尚未具有reset()方法,因此无法与其一起使用。

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

除此之外,我相信你只能使用iframe来解决。这样的解决方案以Ruby为例在这里概述 - http://blog.devinterface.com/2012/01/how-to-insert-more-disqus-box-in-single-page/


虽然这理论上回答了问题,但最好在此处包含答案的基本部分,并提供参考链接。 - Bill the Lizard
好的,我会尽力扩展回答。 - zrooda
3
感谢@mystrdat的回答,受到启发后,我创建了inlineDisqussions。希望它能对每个人都有所帮助。 - tsi
1
@mystrdat,受你的回答启发,我也做了一个小例子来展示我是如何实现它的。https://github.com/timothyshaw/jquery-disqus - timothyashaw

3
据说截至2012年7月17日,Disqus 2012现在又支持“重置”功能了。

1

我需要在GWT应用程序中使用Disqus,因此我需要解决按需加载线程的问题,因为应用程序中的虚拟页面正在更改。

进行了少量的逆向工程和实验后,我构建了一个实用类(如下所示)。

主要见解如下:

  1. 有一个未记录的全局参数叫做disqus_container_id,它允许您将评论放在任何您喜欢的地方。如果在将来的某个版本中无法使用,我的备选方案是暂时将目标元素的ID设置为disqus_thread,添加评论,然后将其改回原始ID。
  2. 由于这是使用JSNI开发GWT的,我需要在原始窗口上下文中设置全局参数,通过$wnd可访问。我相应地更改了默认的Disqus嵌入代码。我之前没有意识到所有全局变量都在Window对象中,但我学到了一些新东西。
  3. 您可以重复使用相同的容器,Disqus似乎会在激活时清除内容。
  4. 这会在DOM中留下许多脚本标记的副本。也许在使用后清理这些副本是个好主意。或者,我可能会进行更多实验,使用其他答案中描述的DISQUS.reset方法。

仅提取对于单独使用JS的人来说至关重要的信息,这应该允许您将Disqus线程粘贴到任何您喜欢的地方:

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

这里是完整的GWT实用类。到目前为止,我只实现了我需要的参数。

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

有没有办法我们可以加载表单和评论一起呈现? - Dinesh Patil
对我来说,评论表单至少是与评论一起嵌入的 - 上面的代码与原始的 Disqus 嵌入代码相同,但被多次调用以加载不同的评论集。 - Kothar

1

尝试这个:

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

5
请在回答问题时使用英语。 - mccainz

1

我遍历了上面的解决方案,但没有一个可以直接使用。查看源代码后,我拼凑出了这个解决方案,它有效了。虽然与之前的解决方案相差不大,但似乎有着显著的区别。

<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>

在您的标记中,放置标准:

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

然后在您的点击操作中,这非常简单。我有一个名为"data"的成员,我从AJAX调用中获取它。

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

这对我很有帮助,解决了以上代码中出现的几个线程之间传递相似评论的问题。
我在Bootstrap模态框中显示我的Disqus线程,在调用$(el).modal('show')之前调用loadDisqus函数,效果非常流畅。

有没有办法将表单与评论一起加载? - Dinesh Patil

0

我知道这个问题很老了,但是由于我也遇到了同样的问题,我找到了一个解决方法,对我来说效果非常好。

我目前有一个页面 - 让我们称之为相册 - 列出了属于该相册的一系列图像。

单击图像将弹出一个灯箱,其中包含当前图像和一个特殊的侧边栏,通过ajax获取当前图像信息,例如标题、日期、作者、评论等(非常类似于Facebook图像查看器/侧边栏评论)

我希望用户能够在主相册页面上发表评论,但也可以在他们在灯箱侧边栏中查看的特定图像上发表评论。

由于灯箱拥有一些回调函数,其中一个在打开灯箱时运行,我已经用它来临时重命名主相册页面中的div“disqus_thread”为其他名称。

另一个回调函数在你在灯箱内更改图像时运行 - 这使我能够重新加载有关图像的侧边栏信息,其中我包括了一个新的disqus_thread div和一个强制执行disqus_reset的javascript。

另一个回调函数在灯箱关闭时运行,这使我能够将相册评论div重新命名为disqus_thread并强制执行另一个重置。

总结一下,主页包含了相册的评论,在点击图片时,我将原始的div重命名为其他名称。然后通过AJAX获取一些信息,其中包含一个新的disqus_thread div。我使用DISQUS.reset方法,使评论加载到灯箱上。当我关闭灯箱时,我将原始的div重新命名为disqus_thread,并强制进行另一次重置。

希望对有所帮助!


-3
你可以通过 iframe 加载每个实例,但可能需要在页面上添加滚动条... 真难看。

如果你读了这篇文章,你会发现这是我们已经尝试过的事情。 - Espen Schulstad
无论如何,我们最终只是将它们放在不同的页面上。您可以在www.java.no上看到。 - Espen Schulstad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接