wingosoft

tekuti

Tekuti means "I'm telling you" in Oshiwambo. It is weblog software written in Scheme, using Git as its persistent store.

Why

Tekuti hacks the web as it is meant to be hacked.

Tekuti uses tags, not categories. Put however many labels you like on your posts, the more the merrier: with each tag you add meaning to your tag cloud, related posts, and related tags.

Tekuti uses Git as its backing store. The data model scales, and you get hot backups and rollback for free.

All operations on the data store are revertable. Try it: make a post, add some comments, revert some comments, revert the reversions...

Tekuti is secure. There is one entry point, and the entirety of the program is written in the functional style. It does not perform any destructive modifications to data. It is very easy to audit its code.

Tekuti respects the meaning of the web's GET and POST operators. Clicking on a link will not modify the data store.

There is a strict separation in types between XML and strings.You won't see malformed XHTML come out of Tekuti, much less an XSS vulnerability.

Output transformation and templating is easy and built-in to the language via the powerful pre-post-order operator.

And, most importantly, it's written in Scheme, so it's fun to hack!

How

Installing prerequisites

  1. Build and install Guile 1.9.14 or newer. (Or if you are reading this before 1.9.14 is out, build Guile from git.)

  2. Install git. Any modern git will work.

Get and build tekuti

git clone git://gitorious.org/tekuti/tekuti.git
cd tekuti; autoreconf -vif; ./configure && make

Run it!

./env src/tekuti

Now navigate to http://localhost:8080/ in your browser. Does it work? Sweet!

To add posts, visit the admin interface at e.g. http://localhost/blog/admin. The default user is admin and the password is admin.

Serving tekuti behind apache

I hear the kids are all running nginx or mongrel2 or whatever, but I haven't caught up yet. So a2enmod mod_proxy, mod_rewrite,and mod_proxy_http, then add this to an appropriate .htaccess file:

RewriteEngine On
RewriteBase /
RewriteRule ^archives/?(.*)$ http://localhost:8080/archives/$1 [P,QSA]
RewriteRule ^feed(/.*)?$ http://localhost:8080/feed/$1 [QSA,P]
RewriteRule ^search/?$ http://localhost:8080/search [QSA,P]
RewriteRule ^tags/?(.*)?$ http://localhost:8080/tags/$1 [QSA,P]
RewriteRule ^debug/*$ http://localhost:8080/debug [QSA,P]
RewriteRule ^admin/?(.*)$ http://localhost:8080/admin/$1 [QSA,NE,P]

You might need to set this somewhere else in your config:

AllowEncodedSlashes On

In any case, you'll have to restart apache.

Migrating from wordpress

Tekuti includes a script to import posts from wordpress into a suitably-laid-out directory. Run it as:

python ./wordpress-to-dir.py HOST USER PASSWORD DBNAME

Then in the directory that the script makes, run:

git init
git add .
git commit -m 'initial import from wordpress'

Then replace ~/blog.git with the .git subdirectory.

Tekuti's URL structure is almost the same as Wordpress' so the only other thing you might want to do would be to redirect category links to tag links, and the rss2 feed to the atom feed:

RewriteRule ^archives/category/(.*)$ /tags/$1 [R=permanent]
RewriteRule ^feed/rss2$ /feed/atom [R=permanent]

Tekuti will emit valid XML. It will complain if the wordpress posts are not valid. Common errors would be using <br> instead of <br />, and ampersands in URLs. Running xmllint on all files named "content" in the directory might be useful.

The XML code doesn't understand all character entities, either -- see config.scm's *character-entities* to add more.

Hacking tekuti

Run Tekuti with the --listen option. Then telnet to port 37146 on localhost, and voila, a REPL!

For me, the best way to hack in the repl is to enter "inside" other modules. For example, to change the admin password, I would:

 ;; enter in the already-defined (tekuti config) module
 (define-module (tekuti config))
 ;; replace the *admin-pass* definition
 (define *admin-pass* "foo")

Of course the best way is to do all this from within Emacs. Just install Geiser, then M-x geiser-connect to the running REPL. Open tekuti/config.scm in Emacs, change the admin password, and press C-x C-e after the closing parenthesis. Then go to your admin page and see if the password changed. Nifty, eh?

Deploying

For deployment-specific variables like the CSS files and the paths and such, you can run tekuti with the -c argument and pass it a config file, which will be evaluated inside the (tekuti config) module. For example, one of mine looks like this:

;; -*- scheme -*-
 (set! *navbar-links*
       '(("about" . "/about/")
         ("software" . "/software/")
         ("writings" . "/writings/")
         ("photos" . "/photos/")))
 (set! *navbar-infix* " | ")

I suggest taking the CSS file from my blog and customizing it for your usage. Please make it look different. If you come up with something that I should include as a default, I'd be interested in seeing it.

I deploy tekuti in a screen session. Run screen, then run tekuti. Then press C-a d to detach from the session. Then when you come back to your server you run screen -r to jump back into that tekuti session.

Feedback

Send me an email at wingo at pobox.com.