External comments for static HTML pages, a lightweight self-hosted disqus alternative.
MIT License
This is an open source commenting system, allowing you to include comments on your static website(s) without the privacy concerns of using an external system such as disqus.
Embedding comments is as simple as including a couple of small javascript files, along with a CSS file for styling.
Features:
viagra
, and any remote IPs which have been locally blacklisted.Anti-features:
Run-time (client-side) dependencies:
This server was originally written for a server optimization guide but since it seemed like a generally-useful piece of code it was moved into its own repository.
The comment server exports a public API allowing the javascript on your (static) pages to add comments, and retrieve those comments which already exist. It is written in Ruby using the sinatra, framework.
There are two choices for storing the actual comment data:
Adding new backends should be straight-forward, and pull-requests are welcome for MySQL, CouchDB, etc.
The server implements the following two API methods:
GET /comments/ID
author
, body
& ip
.POST /comments/ID
author
and body
.email
.
parent
field.
These dependencies were tested on a Debian GNU/Linux stable machine, but are a good starting point for other distributions:
apt-get install ruby ruby-json ruby-sinatra ruby-redcarpet ruby-uuidtools ruby-rack-test
For storage you get to choose between one of these two alternatives:
apt-get install libsqlite3-ruby
Or
apt-get install ruby-redis
Deploying the server involves two steps:
To launch the comment server you'll run one of these two commands, depending on which storage back-end you prefer to use:
$ ./server/comments.rb --storage=redis --storage-args=127.0.0.1
$ ./server/comments.rb --storage=sqlite --storage-args=/tmp/foo.db
The server will bind to 127.0.0.1:9393
by default, so you'll
need to setup a virtual host in nginx/apache which will forward
connections to that instance.
For nginx this would look something like this:
server {
listen 80;
server_name comments.example.com;
location / {
proxy_pass http://127.0.0.1:9393;
proxy_redirect off;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
To allow comments upon your static site you must update your page(s) to include the appropriate javascript libraries, and the CSS.
For basic usage you'll be adding this to the <head>
of your HTML:
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="/js/mustache.js" type="text/javascript"></script>
<script src="/js/e-comments.js" type="text/javascript"></script>
<script type="text/javascript">
$( document ).ready(function() {
discussion( "http://server.name/comments/COMMENT_ID" );
});
</script>
At the place you wish your comments to be displayed you'll add:
<div id="comments"></div>
The example above configured the display of comments with the defaults,
but the discussion()
method actually accepts two arguments:
The discussion will require a unique key, which will be specified as an URL. For example your home-page might include this:
discussion( "http://comments.example.com/comments/home" );
Your about page this:
discussion( "http://comments.example.com/comments/about" );
This will ensure that each page will have a distinct discussion-thread upon it.
The second parameter, which is optional, allows things to be customized. Valid options for this hash include:
comments
<div>
in which comments will be inserted.comments
, as documented above.max_depth
0
, which allows an unlimited thread-depth.threading
true
.comment_template
reply_template
If you wished to disable threading, allowing only a flat discussion hierarchy, you'd use this:
discussion( "http://comments.example.com/comments/about",
{ threading: false });
If you wished to allow comments, but stop arbitrary nesting:
discussion( "http://comments.example.com/comments/about",
{ threading: true, max_depth: 2 });
You could customize the formatting of comments, and the comment-submission form via CSS, however you might prefer to replace the presentation with something entirely different.
To allow this we use mustache.js templates for:
You can hide templates for both of these things inside your static HTML-files and cause them to be used by specifing their IDs like so:
discussion( "http://localhost:9393/comments/id",
{ comment_template: '#comment_template',
reply_template: '#reply_form'} );
This would require your HTML-page to contain something like this:
<script id="comment_template" type="x-tmpl-mustache">
<div class="comment">
<div class="link"><a href="#comment_{{ id }}">#{{ id }}</a></div>
..
</script>
NOTE: You can find the default templates which are used inside the
e-comments.js
file.
Replacing the template entirely allows you to display different data, for example you might wish to show the thread-level of each comment. This could be achived by adding the following to the comment-template:
Depth:{{#depth}}{{ uuid }}{{/depth}}
I'm open to pull-requests adding more formatting options, if you have something you think would be useful. (Similarly any improvements to the presentation of comments by default would be appreciated.)
Providing you have the dependencies installed you can run the same demo locally:
./server/comments.rb --storage=sqlite --storage-args=/tmp/foo.db
/tmp/foo.db
will be created, and used to store your comments.cd client ; python -m SimpleHTTPServer
This local demo works because the demo.html
file is configured to access
comments at http://localhost:9393/
. In a real deployment you'd hide
the comment-server behind a reverse proxy and access it via a public
name such as comments.example.com
.