Comments and previews in Ghost

Published on 19 February 2016

If you just want to see how to disable comments on preview-linked posts in Ghost, jump to the second section.

Some history

In the past I've had many sites and blogs. I've built my own systems and I've also powered sites using feature-rich software like WordPress. With my own systems, I found myself too busy building and designing to actually get the energy to write and publishing anything meaningful. With WordPress I discovered that I was never able to find a theme or set of features that I felt comfortable with — that's not to mention trying to build my own theme from scratch that could support what was possible with WordPress.

Now we enter Ghost. Ghost is an open source blogging platform powered by Node.js. It's simple and focused on publishing — a perfect candidate for powering websites exactly like this one. Despite its relatively early days, I found Ghost to be very powerful software. And even better, the themes were very easy to build using the Handlebars templating language. So around a year ago, I started building the theme you see on this blog today.

After the popularity of my first post about Ubuntu Phone, I decided to add the Disqus commenting system to the site. Because Ghost does not have any built-in support for comments, a system like Disqus was necessary to have the functionality. In a recent release of Ghost, the ability to create a preview link made it possible to share drafts with friends before publishing. (Awesome!)

The problem

Unfortunately, sharing a draft had the side effect of "creating" a new discussion on Disqus that was tied to the preview URL. This same URL gets used by the comment widget when promoting other discussion topics (posts) on the site. In practice, this is not a problem given that once a post is published, the preview URL automatically redirects to the published post. However, this left open the possibility that an unpublished post was a) commented on by a friend and b) becoming promoted in the widget before being published. Additionally, the wrong URL would then appear in the Disqus discussions list.

After checking the GitHub issue for the preview feature, I could not find any information related to determining within the template whether or not a post was being rendered as a preview. I did, however, find a comment from a fellow user who was experiencing a similar problem. Further exploration of the issues list and Google left me with no hints so I went to the theme docs for the post context.

With some experimentation, I figured out that using the {{#if}} helper in combination with the published_at attribute is effective in detecting the published state of a post.

{{#post}}
{{!-- render post up here using title and content helpers --}}
{{#if published_at}}
{{> comments}}
{{else}}
<div class="comments-disabled">  
    <p>This post is a work in progress.</p> 
    <p>Comments are not available until this post is published.</p>
</div>  
{{/if}}
{{/post}}

In this example post.hbs, if published_at has a value, I use a "Partial Expression" to include my comments.hbs partial template from my theme's /partials/ directory. Otherwise ({{else}}), I drop in some HTML with a message explaining the absence of the comment box.

Now if I shoot drafts over to my friends or colleagues for review, Disqus will not have any unpublished discussions created. Likewise, if I had a script to create a topic on some other discussion forum (Facebook, Discourse, et cetera), it would not be rendered into the page and would be unable to run or cause any damage.

Caveats

When editing unpublished posts in Ghost, expanding the Post Settings popover (cogwheel) will display a Publish Date. This date is set to the date and time you began editing the unpublished post, but it does not save unless you edit it. If you edit this time and save your draft, your post will have a published_at date and the above template logic will fail. You can erase a published date by focusing the Publish Date field and pressing backspace or delete.

Conclusion

While the problem above is a minor annoyance for me, it can be particularly troublesome for those implementing other solutions. I certainly hope this helps — and hope you haven’t gone so far as to hack at the source just yet.