Implementing a simple comments system

Following my aspirations for simplicity, I decided to implement the comment system for my blog in the absolute simplest way I could think of. It does not rely on any javascript anywhere, it does not even communicate with a backend. However, I’m still able to populate a sqlite database with whatever comments readers would like to send on any of my articles and then statically render them afterwards. This way, you don’t even need to wait for comments to be fetched while you are reading an article, they are present just like any other content.

The way this works is creating a HTML form on each article:

generate_footer () {
        local pagename="$1"
        echo """
    <footer>
    <div class="commentbox">
    <form action="https://bladh.ninja/comment.html" method="post">
    <input type="hidden" name="article" value="$pagename">
    <label for="name">Your name</label>
    <input id="name" type="text" name="name" required />
    <br />
    <label for="email">Your email (optional)</label>
    <input id="email" type="email" name="email" />
    <br />
    <label for="comment">Comment</label>
    <textarea id="comment" class="fill-width" name="comment" rows="4" minlength="12" required></textarea>
    <br />
    <input type="submit" value="Submit">
    </form>
    </div>
    </footer>""" > $FOOTER
}

This is the part of my page rendering code that adds a form. It does this by accepting the article name as a parameter and inserting this into a hidden input field - which turned out to be the simplest way of adding it to the POST request. The POST request itself does not go anywhere important, it simply points to a dummy HTML page. The actual form data goes somewhere different - to an access log. The relevant part of that in my nginx configuration is as follows:

location /comment.html {
    echo_read_request_body;
    try_files $uri $uri/ =404;
    access_log /var/log/nginx/postdata.log postdata;
    default_type text/html;
    echo "Thank you for your comment";
}

The log format itself is defined in the nginx.conf as follows:

log_format postdata '$time_iso8601 | $remote_addr | $request_body';

which means any comments sent to my dummy HTML page is logged as cleartext, containing the article, time of posting the comment and in case I’d ever get hit by spambots, it contains the IP address of the commenter as well. Writing a python script that then tails this log file is a trivial task, which in turn saves them into a database, runs the render script for the appropriate article to include the new comment and then publish it. Rendering an article causes it to fetch all relevant comments and compile them together at the bottom of the page, and the access log itself is regularly cleared.


Comments