Update: Interestingly, the first comment I've received via Disqus was from Tomash and he correctly pointed out while this was a nice 'exercise' in the use of concerns, as far as the model is concerned, this HTML-and-javascript monster has no place in there at all! Ah yes, pun intended as well :)
So, how do we go about this the correct way? How about a PORO presenter?
class PostPresenter < Struct.new(:component)
def post
component
end
def disqus_id
"post-#{post.id}"
end
def disqus_thread
if self.respond_to?(:disqus_id)
return <<-CODE
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'mwdesilva'; // required: replace example with your forum shortname
var disqus_identifier = "#{self.disqus_id}";
/* var disqus_developer = 1; */
/* * * 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);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
CODE
end
end
end
...and the beautiful part is that in my view it simply changes to <%= raw PostPresenter.new(@post).disqus_thread %>
.
Do share your thoughts, oh, and Tomash, let me know what you think as well please!
I've just upgraded the comments system to use Disqus instead of my hand-baked comments system that used the Ancestry gem inspired from RailsCasts.
Much of the hard work in this simple change is tackled via a concern that I only need to include within my Post
model
require 'active_support/concern'
module Disqusable
extend ActiveSupport::Concern
# NOTE Also need to implement disqus_id in the including class.
def disqus_thread
if self.respond_to?(:disqus_id)
return <<-CODE
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'mwdesilva'; // required: replace example with your forum shortname
var disqus_identifier = "#{self.disqus_id}";
/* var disqus_developer = 1; */
/* * * 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);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
CODE
end
end
end
Similar to to_param
I'm also adding a method disqus_id
to my Post
model and this simply defines a unique id for each post for Disqus. In the view for posts#show
I'm simply calling (and this is erb
) <%= raw @post.disqus_thread %>
.
A potential downside to this approach is that I'm escaping the javascript that I'm fetching from Disqus as 'raw' and this could potentially be a malicious script. I'm giving them the benefit of the doubt in this case of course.