I am running ember-1.0.0-rc.5 and created a view for disqus comments which i'm passing the article ID.
My Problem is that disqus does not know when i switch from one page to another.
This is the view code:
App.DisqusView = Ember.View.extend({
tagName: 'div',
elementId: 'disqus_thread',
didInsertElement: function(){
var root_url = "http://my-root-url.herokuapp.com"
var page_id = this.get('identifier');
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_identifier = "item-" + page_id;
console.log(disqus_identifier);
/ this outputs the correct id/
var disqus_title = "the song title" ;
console.log(disqus_title);
/ this outputs the correct title/
var disqus_url = root_url + '/#/song/' + page_id;
console.log(disqus_url);
/ this outputs the correct url for the page/
var disqus_shortname = 'example';
/* * * DON'T EDIT BELOW THIS LINE * * */
(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);
})();
}
});
and this is in my handlebar template:
{{view App.DisqusView identifierBinding="id"}}
So, the comments are rendering on all pages, but one comment persists to all pages, as though disqus thinks they're all the same page.
I am logging the page_id and url to make sure that i'm giving disqus the correct url.
also when I click from one page to another when both have disqus, the console spits out a bunch of disqus errors:
DISQUS assertion failed: Unsafe attempt to redefine existing module: stringify [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: parse [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: domready [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: on [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: once [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: off [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: trigger [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: stopListening [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: listenTo [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: listenToOnce [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: bind [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: unbind [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getShortnameFromUrl [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getForum [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: isSSL [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: guessThreadTitle [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getContrastYIQ [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: colorToHex [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getElementStyle [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getAnchorColor [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: normalizeFontValue [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: isSerif [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getBrowserSupport [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: getPermalink [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: expose [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: BaseApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: WindowedApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: ThreadBoundApp [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: PublicInterfaceMixin [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Switches [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Profile [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: BackplaneIntegration [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Lounge [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: Ignition [VM] embed.js (16737):1
DISQUS assertion failed: Unsafe attempt to redefine existing module: HostConfig
Update - there is now an Ember Addon here.
I just finished integrating async Disqus on an ember blogging framework (see source here) and this is how I did it:
First, set the options as an object (easily accessible to all components):
App.DisqusOptions = Em.Object.create({
shortname: 'example', // Set this to your Disqus account's shortname
});
Next, load disqus once and only once using the code they give you. I did this in the component:
App.DisqusCommentsComponent = Em.Component.extend({
setupDisqus: function() {
if (!window.DISQUS) {
var disqusShortname = App.DisqusOptions.get('shortname');
window.disqus_shortname = disqusShortname; // Mimic behaviour as if we're setting variable in a script tag
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqusShortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
}
}.on('didInsertElement'),
});
You could also do this by setting a disqusLoaded
property on the options object to true after running the setupDisqus()
method and checking against that.
Also, you could do this in your application template using script
tags but this would bring about an error if you're loading the script on a page that doesn't have and element with an id
of #disqus_thread
.
Next, use the Em.View
or Em.Component
that you will place on each page where you want the comments to appear. Let's call it App.DisqusCommentsComponent
. This component will have no layout (template). Since this component will load everytime we change routes/posts it's the perfect place to call DISQUS.reset()
.
App.DisqusCommentsComponent = Em.Component.extend({
elementId: 'disqus_thread', // ID is used by Disqus to know where to load the comments
timer: null,
setupDisqus: function() {
// setupDisqus() code left out for purposes of not repeating myself
}.on('didInsertElement'),
loadNewPostComments: function() {
if (window.DISQUS) {
this.reset();
} else {
// If DISQUS hasn't finished async loading yet, check again in 100 ms. Once it's loaded, the above this.reset() will be called.
this.set('timer', Em.run.debounce(this, this.loadNewPostComments, 100));
}
},
reset: function() {
var controller = this.get('parentView.controller');
var postIdentifier = controller.get('urlString');
var postUrl = window.location.href;
// Since this view has the elementId Disqus targets, we need to wait until after the view has finished rendering to call the reset function, which searches for #disqus_thread
Em.run.scheduleOnce('afterRender', function() {
window.DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = postIdentifier;
this.page.url = postUrl;
}
});
});
},
});
N.B. The variable postIdentifier
is a property set on the controller for each blog post, loaded as the controller's model. You will need a similar way of identifying each route for keeping track of comments.
Et, voila! Your async call will be made every time the user changes routes to one that has the comments component in it's template. For example:
// Some random hbs here for your blog post
{{disqus-comments}}
Whenever you set a configuration variable like these, you'll want to set them a a property on the window. For example:
var disqusShortname = App.DisqusOptions.get('shortname');
window.disqus_shortname = disqusShortname;
// Do stuff with disqusShortname here
If you want to use Disqus' comment count feature, you can take a similar approach to the above. However, you will also need to reopen the view the {{link-to}}
helper calls with something like the following:
Em.LinkView.reopen({
addDisqusTag: function() {
var commentCount = this.get('commentCount');
if (commentCount) {
var isLinkToPost = this.get('isLinkToPost');
var href = this.get('href');
var disqusTag = '#disqus_thread';
this.set('href', href + disqusTag);
}
}.on('willInsertElement'),
});
Now if you do the following in your template it will return a commentCount:
{{#link-to 'post' this.urlString commentCount='true'}}{{/link-to}}
Hope that helps. Let me know if you have any questions!
I've created a working jsbin, have a look.
As to what I've changed, this line was wrong slightly wrong
this.get('element').id = 'disqus_thread';
but can also be omitted by defining the elementId on the view itself with
App.DisqusView = Ember.View.extend({
tagName: 'div',
elementId: 'disqus_thread',
...
And then retrieved with
var page_id = this.get('elementId');
To test that it's working I've put in the jsbin at the top a link to a pseudo about page, in the about page you will find a link back to the index page, switching back and forth I don't see any problems, Disqus is loading every time as expected though the errors still appear. This might be related to how Disqus is injected into the DOM. Please have a look and let me know if it's working for you.
Hope it helps.
According to the Disqus docs you can reset the active thread like this:
DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = "newidentifier";
this.page.url = "http://example.com/#!newthread";
}
});
(From http://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites)
Use:
The component
App.CDisqusComponent = Em.Component.extend({
didInsertElement: function () {
var page_id = window.location.href,
disqus_identifier = page_id,
disqus_url = page_id,
disqus_title = Em.$('title').text(),
disqus_shortname = 'disqus shortname', // CHANGE, USE YOURS
el_id = disqus_shortname + Date.now();
this.set('page_id', el_id);
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
dsq.id = el_id;
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(dsq);
},
willDestroyElement: function () {
Em.$('#' + this.get('page_id')).remove();
}
})
The component template
<div id="disqus_thread"></div>
Now you can add disqus in any template with:
{{c-disqus}}
fork it: https://gist.github.com/givanse/a3b945a47438d7119989
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With