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
- Create and set up the Gitlab bot account
- Deploy Staticman
- Create and modify the configurations file
- Modify the theme files
- Add the reCaptcha filter
- Add the Akismet filter
Create and set up the Gitlab bot account
- Create a new Gitlab account different from the one that host the static website.
- Create a personal access token for the new Gitlab account selecting
api
and read_repository
as scopes.
- Save the personal access token that will be used later.
- Login to the Gitlab account that host the static website.
- In the Gitlab project used to host the static website, go to Project Information > Members.
- Select Invite members
- Insert the Gitlab username created in step 1.
- Select Developer as role. Then press Invite.
Deploy Staticman
- Clone the Staticman repository
git clone https://github.com/eduardoboucas/staticman
- Create a
Procfile
file in the Staticman repository root. Then write web: npm start
inside the Procfile
.
- 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
}
|
- Open the .gitignore file and add the following line
!config.production.json
- 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
|
- 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.
- Sign in for a free allowances plan in fly.io and install flyctl.
- 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.
- 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
- 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
.
- 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
- Copy the
staticman.js
from here and save it in the \assets\js
theme folder.
- 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";
};
|
- Copy the
comment-replies.html
from here in the \layouts\partials
theme folder.
Add the reCaptcha filter
- Create and setup a reCaptcha account for your site domain from here.
- Set the Label field with the name you want.
- Select reCAPTCHA v2 and “I’m not a robot” Checkbox.
- 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.
- 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.
- 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]
|
- Modify your
config.toml
adding the following lines:
1
2
3
|
[params.page.reCaptcha]
siteKey = "[Your_reCaptcha_sitekey]"
secret = "[Your_reCaptcha_encrypted_secret]"
|
- Modify
comment.html
as shown here.
Add the Akismet filter
- 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/.
- 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.
- 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"
|
- 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
Paolo
Paolo
In reply to Paolo