Search code examples
javascriptajaxpolymerdisquscustom-element

How to make a disqus comments javascript code to work in a polymer custom element


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.


Solution

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