jekyll-discuss

1.0.0 • Public • Published

Jekyll Discuss

A commenting system for Jekyll

Introduction

Jekyll is a powerful blog-aware static site generator. Due to the nature of static sites, including dynamic content — in particular, user-generated content — on a page can be quite challenging. A typical example of that is a blog's commenting system. How to serve that content with an application that consists of pure static HTML files?

As I described in this post and, more in depth, in this post, there are several options to address this limitation. Third-party commenting platforms like Disqus are quite popular and easy to implement.

However, as explained by Tom Preston-Werner in this talk, that comes with the huge caveat of not hosting the comments data, taking away one of the great selling points of Jekyll — the fact that the entire data is hosted together in a repository, not scattered through a myriad of databases and servers.

Other approaches include the actual comments with the rest of the data, but require either a manual build or a complex Continuous Integration process. That makes the integration with GitHub Pages much more difficult.

So what is this?

Jekyll Discuss is a Node.js server-side middleman that handles comments as POST requests from a form, creates data files with its contents and pushes them to a GitHub repository. When using GitHub Pages, that will automatically trigger a build and the new data files will be part of the generated site.

Jekyll Discuss diagram

There was a previous iteration of this project written in PHP, which I'll no longer maintain.

Disclaimer

This project is still pretty much at a point where it's made to solve my specific needs — a commenting system to use with Jekyll, GitHub Pages and Mailgun. I'm always happy to make it as generic and flexible as possible, so please feel free to change it in any way you see fit and submit a pull request.

Installation

  1. Install via NPM

    npm install jekyll-discuss
    cd jekyll-discuss
    
  2. Edit and rename template config file

    vi config.template
    mv config.template config
    
  3. Start server

    node app.js
    

Configuration

Jekyll Discuss consists essentially of an Express server that handles requests, and a Bash script that pushes files to GitHub. Both of these components read information from a shared config file, which contains the following entries.

Key Mandatory Description
SERVER_HTTP_PORT YES Port to be used by the HTTP version of the Express server
SERVER_HTTPS_PORT No Port to be used by the HTTPS version of the Express server
SERVER_HTTPS_KEY No Path to the certificate key to be used by the HTTPS server
SERVER_HTTPS_CRT No Path to the certificate file to be used by the HTTPS server
SERVER_HTTPS_PASSPHRASE No Passphrase to be used with the HTTPS certificate
COMMENTS_DIR_FORMAT YES Path and format of the comments directory (e.g. _data/comments/@post-slug)
COMMENTS_FILE_FORMAT YES Path and format of the comment files (e.g. @timestamp-@hash.yml)
GIT_USERNAME YES Username to use when pushing comments to GitHub
GIT_TOKEN YES GitHub personal access token (info)
GIT_USER YES GitHub user name
GIT_EMAIL YES GitHub user email
GIT_REPO YES Path to the local copy of the repository
GIT_REPO_REMOTE YES Repository URL (.git)
GIT_COMMIT_MESSAGE YES Message to be used on commits
SUBSCRIPTIONS_DATABASE No Path to the file-based database used to manage subscriptions
SUBSCRIPTIONS_NOTIFY_ALL No Email address to where notifications for all posts are sent
MAILGUN_DOMAIN No Mailgun domain from where to send subscription notifications
MAILGUN_KEY No Mailgun key
MAILGUN_FROM No Sender name and email address for subscription notifications

Usage

Submitting comments

Jekyll Discuss will be expecting POST requests containing the following fields:

Field Description
name Commenter's name
email Commenter's email address
url Commenter's URL (optional)
message Comment body
company Honeypot field for basic spam detection (info)
subscribe Whether to notify the commenter of future comments by email (must equal subscribe)
post-slug Post slug
post-title Post title
post-url Post URL

Displaying comments

On the Jekyll side, showing comments for a post can be done simply by iterating through a set of data files.

Example:

{% if site.data.comments[post_slug] %}
    {% assign comments = site.data.comments[post_slug] | sort %}
    
    {% for comment in comments %}
        <div class="comment">
          <h3 class="comment__author"><a href="{{ comment[1].url }}">{{ comment[1].name }}</a></h3
          <p class="comment__date">{{ comment[1].date }}</p>
          <img class="comment__avatar" src="https://www.gravatar.com/avatar/{{ comment[1].hash }}?d=mm&s=180">
          {{ comment[1].message }}
        </div>
    {% endfor %}
{% endif %}

Email notifications

Jekyll Discuss can be used with Mailgun to send email notifications, allowing commenters to subscribe to new comments on any post. To do this, fill in the Mailgun related fields in the configuration file and edit the email templates that ship with the repo.

Here's an example (email-templates/new-comment.template.html):

<!-- New comment on Eduardo saying things -->
Hi {{ subscriber }},<br><br>
 
{{ commenter }} just commented on the post titled "{{ title }}" you subscribed to on <a href="https://eduardoboucas.com/blog">Eduardo saying things</a>.<br><br>
 
Click <a href="https://eduardoboucas.com{{ link }}">here</a> to see the comment or <a href="https://aws.bouc.as/jekyll-discuss/unsubscribe/{{ unsubscribe }}">unsubscribe</a> from future notifications.<br><br>
 
Best,<br>
Eduardo

The first line of the file, wrapped inside HTML comments, will be used as the subject of the email messages that use this template. The {{ subscriber }}, {{ commenter }}, {{ link }} and {{ unsubscribe }} placeholders will be automatically replaced by the values passed by the subscriptions module:

var data = {
    title: parsedData['post-title'],
    slug: parsedData['post-slug'],
    link: parsedData['post-url'],
    subscriber: subscription.name,
    commenter: parsedData['name'],
    unsubscribe: subscription._id
};
 
mailman.send('new-comment', subscription.email, data, function (body, error) {
    if (error) {
        console.log('[!] Error sending email: ' + error);
    }
});

Readme

Keywords

none

Package Sidebar

Install

npm i jekyll-discuss

Weekly Downloads

1

Version

1.0.0

License

MIT

Last publish

Collaborators

  • eduardoboucas