GitHub comments - Part 4 - Integrating comments into Jekyll blog

comments

GitHub Octocat Logo

Almost one year with hand-made comments system based on github issues passed. Now I can sum this experience up and provide some details how I simply integrated it into my Jekyll-based blog.

Other posts in the series

  1. Creating reusable components with Vue.js - Part 1 - Tooling overview
  2. Creating reusable components with Vue.js - Part 2 - Viewing GitHub Issue Comments
  3. GitHub comments - Part 3 - Overcoming GitHub REST API v3 restrictions
  4. GitHub comments - Part 4 - Integrating comments into Jekyll blog This post

Table of contents

Inserting the comments to posts

config.yml

I've added following settings section into my _config.yml:

# GitHub Comments
github_comments: true
github_comments_owner: halex2005
github_comments_repository: codeofclimber-discussions
github_comments_api_root: /api
github_comments_authToken: <auth-token-here>
github_comments_client_id: <client-id-here>

You can receive github_comments_authToken and github_comments_client_id values in github's developer settings page. Just generate new personal access token and create new OAuth App.

post front matter

When I'll write new post, I'll add custom variables comments: true and github_issue_id: <issue_id> to post's Front Matter.

liquid layouts

With this variables in place, I've put following github_comments.html into _include folder:

<script src="/vendor/js/github-comments.js"></script>
<script type="text/javascript">
  window.addEventListener('load', function() {
    var apiRoot = '/api';
    var clientId = 'ba94aae109fbd9e8329a';
    var githubComments = new window.GitHubComments(apiRoot, clientId)

    githubComments.renderPageComments(
        document.getElementById('comments'),
        document.getElementsByName('comments-count')[0],
        '38',
        '#comments');

    githubComments.renderAuthentication(document.getElementById("authentication"));
  });
</script>

and include it into my default layout in _layout with line:

{% include github_comments.html %}

I've also include github_comments.css into _include/head.html with line:

<link rel="stylesheet" href="/vendor/css/github-comments.css" />

In the post's layout, just after article body and related posts, I've include:

{% capture page_comments_enabled %}{{ page.comments }}{{ post.comments }}{% endcapture %}
{% capture github_issue_id %}{{ page.github_issue_id }}{{ post.github_issue_id }}{% endcapture %}
{% capture github_issue_link %}https://github.com/{{ site.github_comments_owner }}/{{ site.github_comments_repository }}/issues/{{ page.github_issue_id }}{% endcapture %}
{% if site.github_comments and page_comments_enabled == 'true' and github_issue_id != '' %}
<div class="comments-container">
  <h2>Comments</h2>
  <div id="comments">
    <noscript>
      <p>
        Please enable JavaScript to view the <a href="{{ github_issue_link }}" target="_blank" rel="nofollow noopener noreferrer">comments powered by GitHub.</a>
      </p>
      <p>
        You can view and post comment for this post
        <a href="{{ github_issue_link }}" target="_blank" rel="nofollow noopener noreferrer">directly on github <i class="fa fa-github"></i></a>
      </p>
    </noscript>
  </div>
</div>
{% endif %}

For places where I need to show comments count, I have _includes/post/comments_link.html:

{% capture post_url %}{{ page.url }}{{ post.url }}{% endcapture %}
{% capture github_issue_id %}{{ page.github_issue_id }}{{ post.github_issue_id }}{% endcapture %}
{% if github_issue_id != '' %}
<a href="{{post_url | replace_first: '//','/' }}#comments" class="comments"><span data-name="comments-count" data-issue-number="{{ github_issue_id }}"></span> comments</a>
{% endif %}

I've included it in _includes/post/meta.html by:

{% if site.github_comments == true %}
    {% include post/comments_link.html %}
{% endif %}

scripts and styles

If you don't want to build github_comments scripts and styles yourself (see github-comments repository), you can download github_comments.js and github_comments.css right from my site and put them into /vendor/js and /vendor/css directories on your site. This js and css are self-containing and contain all vendor dependencies (react and mobx for example).

Automating creation of issues on github

I've wrote node.js script to patch Jekyll posts with GitHub issue numbers. The script uses async/await on promises, therefore we need babel-core/register package to be registered upon execution (see scripts in package.json below).

I've used gray-matter package to work with post's Front Matter. It can read Front Matter and post's content from string, and write them back to string easily.

Script executes following tasks:

  • prompt user credentials, owner and repository first (see GetCredentials())
  • extract post's Front Matter
  • posts having github_issue_id in Front Matter should be filtered out, no changes needed here
  • there are two cases when post doesn't have github_issue_id
    • if issue already exists, just add github_issue_id to it's Front Matter
    • otherwise we should create new issue
  • new issue requirements:
    • first issue comment should contains link to original post
    • I'd like to close created issue right after it's creation. This doesn't prevent commenting on issue and makes issues list more clean: we can create and process general site issues here too
    • I'd like to fill issue labels from blog post's tags
  • in the end, I writing blog post's Front Matter and content to disk if Front Matter has been changed

The code seems to be self-explanatory, here is the gist:

Conclusion

Now, when github comments back-end is done and front-end scripts are plugged in, I can add comments to post with following workflow:

  • write blog post
  • in front matter add comments: true custom variable
  • create github issue for post with npm run patch-posts

Happy commenting!


liberapay link If you like this post, consider supporting me on liberapay

Comments