1
votes

I'm using polymer starter kit 2.0

Structure of nested custom elements:

(meaning that <my-app></my-app> is inside index.html etc.):

| index.html
--------\ my-app.html (custom element)
----------------\ my-testView1.html (custom element)
----------------\ my-testView2.html (custom element)

I need to put disqus comments on my-testView1.html and my-testView2.html pages (separate thread for each one)

I was trying to make it work and at one point chrome's console message told me that I have to use ajax method (since both my-testView1.html and my-testView2.html are inside <iron-pages> so there's routing going on, I guess that's why) and it also gave me this link https://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites

Structure of my-testView1.html:

(I changed example.com and myChannelID to real names)

       ...
         <content select=".disqus1"></content>
      </template>

      <script>
        Polymer({
          is: 'my-testView1',

      )};
    </script>

    <script>
      var disqus_config = function () {
        this.page.url = 'https://www.example.com/testView1'; 
        this.page.identifier = '/testView1'; 
        this.page.title = 'Test View1';
        };


     (function() { 
        var d = document, s = d.createElement('script');
        s.src = 'https://MyChannelId.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
        })();

      DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = "/testView1";
            this.page.url = "https://www.example.com/#!testView1";
        }
        });
    </script>
</dom-module>

Structure of my-testView2.html (same as the first one):

   ...
      <content select=".disqus2"></content>
  </template>

  <script>
    Polymer({
      is: 'my-testView2',

    });
  </script>
  <script>
     var disqus_config = function () {
        this.page.url = 'https://www.example.com/testView2'; 
        this.page.identifier = '/testView2'; 
        this.page.title = 'Test View2';
        };


     (function() { 
        var d = document, s = d.createElement('script');
        s.src = 'https://MyChannelId.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
        })();

      DISQUS.reset({
          reload: true,
          config: function () {
            this.page.identifier = "/testView2";
            this.page.url = "https://www.example.com/#!testView2";
        }
        });
    </script>

The question that brought me to this point has been asked earlier here: Disqus comments don't work in a polymer custom element
With some help and instructions there I managed to get to this point. But I still can't make it work with ajax so that it would load separate disqus thread to each page.

Maybe it has something to do with #! or maybe I have to insert it inside ready: function() {} but if I do so, it just breaks the layout so I put it in a separate tag and now it says DISQUS is not defined. I have no idea what I'm missing there.

I have only 50 reputation bounty to share, but If you know how to make it work could you please explain me how to fix it.

2

2 Answers

2
votes

The <div id="disqus_thread"> element must be unique in the page, because it is where the disqus library will inster the downloaded thread. So you should add it after the <iron-pages> tag.

<div>
  <iron-pages>
    <view-1></view-1>
    <view-2></view-2>
  </iron-page‌​s>
</div>
<div id="disqus_thread"></div>

Then you have to call DISQUS.reset() every time a subpage is shown. You can know it because a class iron-selected is added to the selected element. So you can listen for the attributeChange() callback of the Polymer element, and check if it contains the iron-selected class. If it's true you can call DISQUS.reset() with the identifiers of the thread you want to load.

Polymer( {
    is: 'view-1',
    attributeChanged: function ( name, old, value )
    {
        if ( name == 'class' && this.classList.contains( 'iron-selected' ) )
        {   
            //call DISQUS.reset() here
            DISQUS.reset( {
                reload: true,
                config: function () 
                {
                    this.page.identifier = "/testView1"
                    this.page.url = "https://www.example.com/testView1"
                }
            } )
        }
    }
} ) 

Also, since you use DISQUS.reset(), you can remove var disqus_config = ...


To address the problem of uniqueness of the <div id=disqus_thread> element:

if you want to insert it in the right page inside , you can the use appendChild() to move it before calling DISQUS.reset(). Put it for example in a <div id='container'> element.

Inside attributeChange() method:

this.$.container.appendChild( document.getElementById( 'disqus_thread' ) )

Inside the view-1 <template>:

<template>
  //Page content
  <div id=container></div>
  //Page footer
</template>
1
votes

Another possible solution is:

Create an html file and put disqus code in there:

<div id="disqus_thread"></div>
<script>
    var disqus_shortname = 'YourDisqusId';
    var disqus_identifier = '/view1';
    var disqus_url = 'https://example.com/view1/';
    var disqus_config = function () {

    };
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
     })();

</script>

Then add an iframe to the custom element page linking that code

 <iframe src="../src/page1_disqus.html" style="width:100%; min-height:400px; border:0 none;"></iframe>

If it's just shows you your app inside this iframe maybe it's a good idea to put this html file not in your src directory but on a separate server and use the share link instead of local storage ../src/

If you need to put disqus on more than one page, just create another html file and then link it to the page where it needs to be using iframe the same way