One of my current projects involves setting up a website
that is translated to at least two languages. For various
reasons I wanted to use
IkiWiki as the backend, even
though the site is static, and does not need the wiki
functionality. IkiWiki is, in principle, a wiki engine, but
with a difference: it is run off-line, and creates a set of
static HTML pages, rather than running every time a page is
accessed. This makes it suitable for static websites.
For the translation, I wanted to have the following
setup: Each page is available in each language, so the pages
are named
foo.xx.html, with
xx being the
ISO language code. This also allows HTTP content negotiation
to work, if the client asks for the page without the
.html suffix.
IkiWiki itself does not currently have support for
translations. Doing translations by manually editing each
page in each language is tiresome and error prone. I wanted
to use the
gettext approach, where the translations
are maintained using
.po files. The
po4a tool makes this possible: it supports
many file formats.
English is declared as the original language for this
project: all other languages are generated via po4a from the
English ones. The page content gets put into
foo.xx.mdwn. po4a generates all other language
files than English, and these are then fed as input to
IkiWiki, which generates the HTML.
In summary and horrible ad hoc pseudo-notation:
- po4a: foo.en.mdwn -> foo.pot
- cp: foo.pot -> foo.xx.po
- $EDITOR: update translation in foo.xx.po
- po4a: foo.en.mdwn + foo.xx.po -> foo.xx.mdwn
- IkiWiki: foo.*.mdwn -> foo.*.html
This works pretty well, but only for the part of the page
that gets put into the content section in the IkiWiki page
template (<TMPL_VAR CONTENT>). The page design we have
calls for a couple of elements with translatable content
outside the content: a logo and a menu/navigation bar. To deal
with these, I made a little IkiWiki plugin.
The plugin sets a couple of Perl
HTML::Template variables,
LANG and
BASENAME, based on the input file name. If the
input name is
foo.en.mdwn, the variable get set to
en and
foo, respectively. The
IkiWiki page template then uses the variables to load the
right logo for the language of the page being generated.
The navigation bar needs further work. Unfortunately, the
po4a tools have trouble with the IkiWiki page templates, and
can't extract just the menu entries. I ended up doing the
navigation bar translation directly in the page template, since
it is only a few words anyway.
<li><a href="index.<TMPL_VAR LANG>.html">
<TMPL_IF EN>Home
<TMPL_ELSE FI>Etusivu
</TMPL_IF></a></li>
The "this page in other languages" part of the navigation
part looks like this:
<li><a href="<TMPL_VAR BASENAME>.fi.html">suomeksi</a></li>
I made the
plugin
(my first Perl ever!) available in case anyone else finds it
useful.
Note that the plugin isn't of much help if you want to
maintain a translated wiki, since this all need some
Makefile magic to make things smooth. I'm not sure the
Makefile is at all optimal, though.
We haven't yet gone public with the website, so this setup
of mine may well get improvements still.