1
votes

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)

2
You probably don't really have to put the Disqus script in main document. See how I placed it inside element's template and bind the channelName property: jsbin.com/feqaqig/edit?html,js,outputTomasz Pluskiewicz
Now that think of it, putting Disqus inside Polymer element is probably not a good idea at all. It will not work under Shadow DOM and I don't really see a benefitTomasz Pluskiewicz
@Supersharp I put an UPDATE #1 in the question, if you have a free minute could you please check it out?Un1
@TomaszPluskiewicz well, I have my site's pages as custom elements, and I wanted to put script of the disqus to some of those pages (custom elements). But as you said it won't work in shadow dom, and I'm a newbie so I don't really know how to implement it yet. Unfortunately there's no useful (for newbies) information about scripts inside of custom polymer elements in the polymer documentationUn1
the DISQUS.resest() method should be called every time the view (either 1 or 2) is displayedSupersharp

2 Answers

1
votes

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.

0
votes

I wanted to give another possible solution to using Disqus comments in Polymer. The main problem is the inability to use Disqus with elements in the shadow dom because they are hidden. So how can we make a shadow dom element visible? We can pass it down the component hierarchy from the index.html of the application.

To expose an element structure your html like this:

index.html
<polymer-app>
  <div id="disqus_thread">
</polymer-app>

In Polymer App:

<dom-module id="polymer-app">
  <template>
      <slot></slot>
  <template>
</dom-module>

Slot is where the #disqus_thread will show. And you can pass it further down to other components, inside polymer-app.

<dom-module id="polymer-app">
  <template>
    <my-page>
      <slot></slot>
    </my-page>
  <template>
</dom-module>

Note: This is code is just an example. Don't try to copy and paste, it won't run.