, 4 min read

HashOver Comment System with Hiawatha

1. Problem statement. When you have a blog you might want to engage with your readers by allowing them to comment on your posts. WordPress allows this out of the box. But when using a static site generator then having a commenting system is a bit more difficult. Many have resorted to Disqus. But Disqus has a number of drawbacks:

  1. It requires quite some bandwidth as its JavaScript libraries are large.
  2. Your data is now under control of a separate company.

There are a number of Disqus alternatives, see Top 7: Best Open Source Self-Hosted Comment System Alternatives to Disqus. The system HashOver is one of them. It was written by Jacob Barkdull, also see Impersonal Introduction. It is written in PHP and JavaScript. From its website:

HashOver is a self-hosted system. Comments can be stored in either flat-file formats (like XML or JSON) or SQL databases.

Out of the box it contains some spam protection via Stop Forum Spam. You can also filter specific IP ranges.

HashOver is quite a hefty piece of software.

Type Lines of code #files
PHP 20,654 97
JavaScript 4,533 77
HTML (including documentation) 4,073 24

For comparison, below are the numbers for WordPress version 6.4.2:

Type Lines of code #files
PHP 528,634 1,124
JavaScript 628,393 559
HTML (including documentation) 950 9

2. Installation. The installation is documented in Setup. The most important steps are:

  1. Download the zip file from GitHub and unpack it somewhere under the webserver root, e.g., /srv/http/hashover
  2. Edit .../hashover/backend/classes/secrets.php
  3. See Use: Add JavaScript to your <body>, and place <div id="hashover"></div> where you want the comments to appear
  4. Make metadata and threads directory writable by the web-server user, in my case it is http:
.../hashover/comments: chown -R http:http metadata threads

3. Hiawatha specific problems. Installing HashOver in Hiawatha unfortunately is not without its problems. Out of the box it does not work with Hiawatha. Once I knew it worked with

php -S 0:8000 -t /srv/http

then I concluded it has something to do with the handling of index.php.

HashOver should start as below for .../hashover/admin/login/:

Once logged in, settings-dialog looks like this:

Comments on your website look like this:

Back to the index.php problem: From PHP: Built-in web server:

If a URI request does not specify a file, then either index.php or index.html in the given directory are returned. If neither file exists, the lookup for index.php and index.html will be continued in the parent directory and so on until one is found or the document root has been reached.

There are two possibilities to solve it in Hiawatha:

  1. Using StartFile=index.php
  2. Using a special UrlToolkit rule
UrlToolkit {
    ToolkitID = HashOver
    RequestURI isfile Return
    Match ^/hashover/(.+)/+$ Rewrite /hashover/$1/index.php
}

I also needed to change 5 files and add index.php before the question mark (?). Below are the files with their changes:

admin/url-queries/index.php
62:        redirect ('./index.php?status=success');
67:  redirect ('./index.php?status=failure');

admin/settings/index.php
734:        redirect ('./index.php?status=success');
739:  redirect ('./index.php?status=failure');

admin/blocklist/index.php
50:        redirect ('./index.php?status=success');
55:  redirect ('./index.php?status=failure');

admin/admin.html
42:     <a class="right" href="{admin}/login/index.php?logout=true">{logout}</a>

admin/view-setup.php
127:    redirect ('../login/index.php?redirect=' . urlencode ($uri));

The first option is not possible for my blog, as I need StartFile=index.html so that end-users can drop the index.html on their URL. Therefore I must use the 2nd option.

Ideally Hiawatha should allow a list of filenames for StartFile, e.g.,

StartFile = index.html, index.php

Unfortunately, Hiawatha does not allow this.

4. NGINX configuration. Similar to Hiawatha the NGINX web-server also needs some rewrite-rules for server listening on ports 80 and 443:

    rewrite "^/.../hashover/(.+)/+$"  "/.../hashover/$1/index.php" last;

This rewrite-rule adds index.php after plain /.

5. JavaScript size considerations. I am still hesitating whether I should include HashOver or not. Looking at the required bandwidth:

One sees that HashOver needs ca. 75kB: first 54kB for comments.php (which generates JavaScript on the fly), and second 20kB for comments-ajax.php. Compare this to the actual content of index.html which is only 1.7kB.