Search code examples
javascriptpolymercustom-elementpolymer-elementshtml5-template

Disqus comments don't work in a polymer custom element


I don't know how to make a disqus comments code to work inside of my custom elements.

Structure of my site:

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

I need to put disqus comments inside my-testView1.html and my-testView2.html

Structure of index.html:

 <body>
   <my-app>
      <div class="disqusClass1" id="disqus_thread"></div>
      <div class="disqusClass2" id="disqus_thread"></div>
   <my-app>
</body>

Structure of my-app.html:

 <iron-pages>
      <my-testView1 name="testView"><content select=".disqusClass1"></content></my-testView1>
      <my-testView2 name="testView2"><content select=".disqusClass2"></content></div></my-testView2>
    </iron-page‌​s>

Structure of my-testView1.html :

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

Structure of my-testView2.html :

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

The disqus div

I put the div of the disqus comments inside <my-app> on the index.html so that chrome could find it. It can't find it if I put it inside <my-testView1> like that:

page my-app.html

<iron-pages>
  <my-testView1 name="testView"><div id="disqus_thread"></div></my-testView1>
  <my-testView2 name="testView2"><div id="disqus_thread"></div></my-testView2>
</iron-page‌​s>

because the my-app.html is a custom element itself and it won't let chrome to find it. So I had to put it outside of the shadow dom (the index.html page)

Javacript code on the pages my-testView1.html and my-testView2.htmllook like this:

<dom-module id="my-testView1">
  <template>
   ...
        <content></content>
   ...
 </template>

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

      ready: function () 
          {    
             // DEFAULT DISQUS CODE (I changed real URLs though):        
             var disqus_config = function () {
             this.page.url = 'https://www.example.com/testView1'; // Replace PAGE_URL with your page's canonical URL variable
             this.page.identifier = '/testView1'; 
             // this.page.title = 'Test View';
             };

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

Result

Comments appears only on one of these my-testView1.html my-testView2.html at the time. I need 1 disqus thread on my-testView1.html and another disqus thread on my-testView2.html

Maybe it's because of routing. Disqus console message says that I need to use ajax method https://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites Unfortunately I could not make it work when I replaced the javascript code above with the code from the example:

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

      ready: function () 
          {    
                 var disqus_shortname = 'myDisqusChannelId';
                 var disqus_identifier = '/testView1';
                 var disqus_url = 'http://example.com/testView1';
                 var 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);
                 })();

                 var reset = function (newIdentifier, newUrl) {
                     DISQUS.reset({
                         reload: true,
                         config: function () {
                             this.page.identifier = newIdentifier;
                             this.page.url = newUrl;
                         }
                     });
                 };
        }
     });
  </script>
</dom-module>

inside both custom elements (changing disqus_identifier and disqus_url correspondingly for each of them)


Solution

  • The error is due to the fact that the disqus library can't find the <div id="disqus_thread"> element.

    It's because this element is inside a Shadow DOM (and that's why it works fine in Firefox which doesn't implement real Shadow DOM).

    3 possible solutions:

    1. Don't use Shadow DOM with your Polymer elements.
    2. Don't put the #disqus_thread element in a Polymer element (insert it in the normal DOM).
    3. Use <content> in your <template>, and the #disqus_thread element inside the polymer tag to make it availabe to the library:

    In the custom elements:

    <template>
       //HTML code here
       <content></content>
    </template>
    

    In the HTML page where you insert the custom element:

    <my-app>
       <my-testView>
          <div id="disqus_thread"></div>
       </my-testView>
    </my-app>
    

    The <div> will be revealed at the place where the (nested) <content> tags are placed.