Contents

How to set up a static comments system with Staticman

I want to introduce a comments system to my digital garden to allow other people to contribute and question the topic I’m learning.

There are various ways to introduce comments in a static website like this one. My requirements for the comments system are:

  • no ads
  • the privacy of the users must be respected
  • it’s free
  • should not be required to the users to create 3rd party accounts.

After some research I have chosen to give a try to Staticman.

How Staticman works

  • When you submit a comment, Staticman sends the comment contents through a Gitlab or Github bot account to your Gitlab/Github site repository as a commit.
  • After the commit is merged to your site repo main branch, the comment is published in your blog.

Prerequisites

  • A static website managed with Gitlab or Github. The following procedure consider to work with Gitlab.

Main steps

  1. Create and set up the Gitlab bot account
  2. Deploy Staticman
  3. Create and modify the configurations file
  4. Modify the theme files
  5. Add the reCaptcha filter
  6. Add the Akismet filter

Create and set up the Gitlab bot account

  1. Create a new Gitlab account different from the one that host the static website.
  2. Create a personal access token for the new Gitlab account selecting api and read_repository as scopes.
  3. Save the personal access token that will be used later.
  4. Login to the Gitlab account that host the static website.
  5. In the Gitlab project used to host the static website, go to Project Information > Members.
  6. Select Invite members
  7. Insert the Gitlab username created in step 1.
  8. Select Developer as role. Then press Invite.

Deploy Staticman

  1. Clone the Staticman repository git clone https://github.com/eduardoboucas/staticman
  2. Create a Procfile file in the Staticman repository root. Then write web: npm start inside the Procfile.
  3. Create a file called config.production.json in the Staticman repository root. Then write the following in the file:
1
2
3
4
5
{
  "gitlabToken": process.env.GITLAB_TOKEN,
  "rsaPrivateKey": JSON.stringify(process.env.RSA_PRIVATE_KEY),
  "port": 8080
}
  1. Open the .gitignore file and add the following line !config.production.json
  2. Generate a RSA private key writing the following in the command prompt of the Staticman repository root:
1
openssl genpkey -out rsakey.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
1
openssl pkcs8 -in rsakey.pem -traditional -nocrypt -out key.pem
  1. Open the key.pem file with a editor like Notepad++ and modify the content so that the key remains in one single line.

Note: also the —–BEGIN RSA PRIVATE KEY—– and the —–END RSA PRIVATE KEY—– must remain in the single line.

  1. Sign in for a free allowances plan in fly.io and install flyctl.
  2. Set the following fly secrets in the command prompt of the Staticman repository root:
1
flyctl secrets set GITLAB_TOKEN=YOUR_PERSONAL_ACCESS_TOKEN
1
flyctl secrets set RSA_PRIVATE_KEY=YOUR_RSA_PRIVATE_KEY

Note: Replace YOUR_PERSONAL_ACCESS_TOKEN with the personal access token saved in step 3 and YOUR_RSA_PRIVATE_KEY with the RSA private key modified in the previous step.

  1. Create the fly app writing fly launch in the command prompt of the Staticman repository root and setting the configuration required. If the app is installed correctly and you open the YOUR_FLY_APP_NAME.fly.dev, then you should see the message Hello from Staticman version 3.0.0!

Note: If fly log returns errors, check the Dockerfile and the fly.toml files and in particular the port settings. My files are the followings:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Dockerfile
FROM node:8.11.3
# Create app directory
RUN mkdir -p /app
WORKDIR /app
# My addition, not sure if needed
ENV NODE_ENV production
# Install app dependencies
COPY package.json /app/
RUN npm install
# Bundle app source
COPY . /app
EXPOSE 8080
CMD [ "npm", "start" ]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# fly.toml file generated for staticman2023new2 on 2023-04-14T06:40:33+02:00
app = "staticman2023new2"
kill_signal = "SIGINT"
kill_timeout = 5
primary_region = "ams"
processes = []
[env]
[experimental]
  auto_rollback = true
[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"
  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80
  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443
  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s" 

Create and modify the configurations file

  1. Create a staticman.yml file in your blog repository root. See how my file looks like here. It already includes the support for comment replies, reCaptcha and Akismet spam filter.

Note: If you want do not want to check every message before publication, set moderation: false.

  1. Modify config.toml adding:
1
2
3
4
5
[params.page.staticman]
    endpoint = "https://[your_app_name].fly.dev/v3/entry/gitlab"
    username = "[username]"
    repository = "[repository]"
    branch = "[branch]"   

Note: Replace [your_app_name] with the name of the app assigned in fly.io. Replace [username] with the username of your blog repo. Replace [repository] with the repository name of your blog repo. Replace [branch] with the main branch name of your blog repo.

Modify the theme files

  1. Copy the staticman.js from here and save it in the \assets\js theme folder.
  2. Modify the theme.js file adding the following lines:
1
2
3
4
function changeValue(elementName, newValue){
 document.getElementsByName(elementName)[0].value=newValue;
 window.location.hash = "#comment-form";
};
  1. Copy the comment-replies.html from here in the \layouts\partials theme folder.

Add the reCaptcha filter

  1. Create and setup a reCaptcha account for your site domain from here.
  2. Set the Label field with the name you want.
  3. Select reCAPTCHA v2 and “I’m not a robot” Checkbox.
  4. Add the domain(s) of your blog site and press Save. Then you should get the reCAPTCHA site key and the secret key.

Note: Add also localhost to your domains to use the reCAPTCHA also during the testing.

  1. In your browser, write https://[your_app_name].fly.dev/v3/encrypt/[your_secret_key] to encrypt the secret key. You should see the encrypted secret key.
  2. Add the following lines to your staticman.yml file replacing your sitekey and encrypted secret.
1
2
3
4
 reCaptcha:
   enabled: true
   siteKey: [Your_reCaptcha_sitekey]
   secret: [Your_reCaptcha_encrypted_secret]
  1. Modify your config.toml adding the following lines:
1
2
3
 [params.page.reCaptcha]
   siteKey = "[Your_reCaptcha_sitekey]"
   secret = "[Your_reCaptcha_encrypted_secret]" 
  1. Modify comment.html as shown here.

Add the Akismet filter

  1. Sign in for a Personal plan of Akismet and add your site URL during sign in. You should get the Akismet key.

Note: write your site URL in the following format https://your_site.com/. In my case is https://www.mylearningnotes.org/.

  1. Set the following fly secrets in the command prompt of the Staticman repository root:
1
flyctl secrets set AKISMET_API_KEY=YOUR_AKISMET_KEY
1
flyctl secrets set AKISMET_SITE=YOUR_SITE_URL

Note: Replace YOUR_AKISMET_KEY with the Akismet key you get in the previous step and YOUR_SITE_URL with the site URL you inserted in the previous step.

  1. Add the following lines to your staticman.yml file.
1
2
3
4
5
6
  akismet:
    enabled: enable
    author: "name"
    authorEmail: "email"
    content: "message"
    type: "comment"
  1. Test the Akismet filter by entering the following info in the comment form:
    • Name: akismet-guaranteed-spam
    • Email: akismet-guaranteed-spam@example.com
    • Comment Body: akismet-guaranteed-spam You should see the message: {"success":false,"rawError":{"_smErrorCode":"IS_SPAM"},"errorCode":"IS_SPAM"}

Improvements

  • Improve the style of the comment form.
  • Introduce nested comments.

Credits

Comments

Paolo


This is a test.


Paolo
In reply to Paolo

This is a comment reply test.