1

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)

Un1
  • 3,874
  • 12
  • 37
  • 79
  • 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: http://jsbin.com/feqaqig/edit?html,js,output – Tomasz Pluskiewicz Sep 29 '16 at 07:28
  • 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 benefit – Tomasz Pluskiewicz Sep 29 '16 at 08:11
  • @Supersharp I put an **UPDATE #1** in the question, if you have a free minute could you please check it out? – Un1 Sep 29 '16 at 10:41
  • @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 documentation – Un1 Sep 29 '16 at 10:45
  • add the div twice and give them a different selection id – Supersharp Sep 29 '16 at 16:01
  • Like it is in the **Result** section of the question? I just tried and it doesn't work unfortunately. – Un1 Sep 29 '16 at 16:25
  • No. Like in this example: http://stackoverflow.com/a/39484400/4600982. But are you sure you can insert 2 disqus threads in one page? – Supersharp Sep 29 '16 at 17:19
  • Well I'm not sure if I can insert 2 disqus threads but since each custom element is placed in its own .html page I thought that would work. There's routing involved but..I don't know. Well I saw a console warning saying I have to put it as ajax and it gave me this link [link](https://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites) so I clicked **example DISQUS.reset recipe** there and replaced the current javascript code with that example presented there on each of the custom element pages and now I see **We were unable to load Disqus** on the place of the comments – Un1 Sep 29 '16 at 17:39
  • Okay, so I need to add `select=""`? As it shown in the **Result** section I have these ids there `disqus_thread` and `disqus_thread2` Do I need to make look like this: in one custom element `` and `` in another for both custom element pages and the page in between (my-app.html)? – Un1 Sep 29 '16 at 17:49
  • Your div must have the name disqus_thread (exactly) to work. So you can only have one in your page. Pût it one level higher in your hierachy and follow the advice of the link you provided – Supersharp Sep 29 '16 at 17:51
  • Thanks to you it looks like the only problem left there is the javascript of the disqus itself. I'm trying to transform that javascript in a way that disqus example suggest, but so far no luck though. Ehhh..web dev is hard, man – Un1 Sep 29 '16 at 22:55
  • 1
    the DISQUS.resest() method should be called every time the view (either 1 or 2) is displayed – Supersharp Oct 01 '16 at 15:16

2 Answers2

1

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.

Supersharp
  • 29,002
  • 9
  • 92
  • 134
  • Thanks for the answer. I have this structure `index.html --/ my-app.html (custom element) --/ my-testView.html (custom element)`. So it's custom element inside of custom element. So do I have to put `
    ` inside index.html `` basically? I just did that and I also put `` to the place it needs to be on the page of my `my-testView.html` custom element. And I can see disqus now on all the pages fixed on top of the page. But It didn't go to the `` tag. Oh man, it's really suck to be a newbie in web development..
    – Un1 Sep 29 '16 at 13:57
  • if you have nested custom elements, you have to add content elements in all the custom element templates. Don't apply 2 differents solutions in the same time. – Supersharp Sep 29 '16 at 14:15
  • okay. What I did now is I just put `
    ` inside `body` tag on **index.html** and I added inside `` to the custom element **my-app.html** and I also added to the custom element **my-testView.html** on the place it needs to be there, but I just don't understand how it knows that `
    ` inside `body` on the **index.html** need to go to the `` on **my-testView.html** What am I doing wrong here?
    – Un1 Sep 29 '16 at 14:26
  • the `div` should be inside your custom element and the `content` inside the `template`! as in the example above – Supersharp Sep 29 '16 at 14:38
  • It won't find it then, because the `my-app.html` itself if the custom element. I rewrote my question and updated it so it would be easier to see what is nested and what isn't, showing how it looks. I understand you probably sick of this question already but If you happen to know the answer I'll appreciate if you add something to it, thanks a lot – Un1 Sep 29 '16 at 15:31
  • actually your rewritten question is a new one – Supersharp Sep 29 '16 at 15:59
0

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.

dlaub3
  • 1,107
  • 9
  • 20