Following my previous entry on static commenting, this article serves as a step-by-step guide to implementing the “emailed comments” approach in Wintersmith and subsequently, Jade templating.
Note: I’ve generalised and packaged a variant of this project as wintersmith-static-comments on GitHub.
Comments will be sent via email, so first decide on an address to use. A likely
candidate is comment@your-domain.com
, but any address will do fine.
Next, add it as a variable that can be later accessed in a view/template. Here
we’ll be using Wintersmith’s config.json
but it could quite happily be set as
an environment variable (a la The Twelve-Factor App).
Add a new key — comment_email
— within the locals section:
{
"locals": {
...
"comment_email": "comment@example.com"
}
}
An overarching goal of static commenting is freedom. Here, we’ll be storing
comments as plain-text (Markdown formatted) files in a git
repository.
Create a new repository within Wintersmith’s contents directory. Files placed
here will later be accessible within the global ContentTree
object.
cd public/contents
git init comments
The directory structure here should take the form:
.
|-- [post-url]
| `-- 00.mkd
`-- [post2-url]
|-- 00.mkd
|-- 01.mkd
|-- 02.mkd
`-- 03.mkd
… where 00.mkd
, 01.mkd
, etc. are comments in chronological order
containing Markdown and some leading metadata (a la Wintersmith’s page
plugin):
name: Paul Graham
date: 2011-04-07T19:18:06
url: http://paulgraham.com
An insightful comment.
The only mandatory metadata keys are name
and date
; arbitrary keys can
later be accessed in the view.
If you’re migrating away from Disqus (or just want a backup), try my disqus2yaml script. Give it an API key and your website’s short url (Disqus ID) and it’ll spit out a directory tree like the one explained above.
With the data source set up, we’ll now create a template to present the comments.
- var url = page.url.substring(page.url.indexOf('/') + 1).replace(/\//g, '-');
- var email = locals.comment_email.split('@');
- var mailto = email[0] + '+' + url + '@' + email[1];
section#comments
h2 Comments
if _.has(contents.comments, url)
- var index = 1;
for comment in _.keys(contents.comments[url]).sort()
- comment = contents.comments[url][comment]
include comment
- index++;
p
| Have something to add? Leave a
a(href='mailto:'+mailto+'?subject='+page.title, target='_blank') comment
| .
In short, this simply loops through comment directories that match a normalised
version of the current url and passes their contents to comment.jade
.
The mailto
link is constructed in the following form:
[mailbox]+[normalised-post-url]@[domain]?subject=[post title]
- var permalink = 'comment' + index;
blockquote(id=permalink,
class="#{comment._metadata.reply ? 'comment reply' : 'comment'}")
- var content = marked(comment._content)
| !{content}
p
small
if comment._metadata.url
a(href=comment._metadata.url)=comment._metadata.name
else)
=comment._metadata.name
| ,
a(href='\##{permalink}')=comment._metadata.date
Each comment is then wrapped in a blockquote
, given a class for styling and
anchored with a permalink. Simple.
As an embellishment to the generalised version,
comment are also parsed as Markdown by exposing marked
in Wintersmith’s page
plugin. You’ll need to use the exposed-marked branch of my
fork of Wintersmith if you want to try this.
Lastly, integrate comments into your main template using an include
statement:
article
header
h1=page.title
section#contents
| !{page.html}
include comments
You should now see a new comment section like the one below. See my Vim XDG post for an example of how comments themselves are rendered.
When you receive a comment, it’s a simple case of saving it in the comments repository and rebuilding the site. If the repository is hosted publicly (as is the case with mine), commenters could even add their comment via a pull-request or use GitHub’s create file feature directly.