Thursday, October 23, 2003
Localization through Internationalization (or l10n via i18n)
I just now cleaned up the last bit of code that required me to maintain multiple copies of mod_blog, depending upon the user. The problem revolved around the month of December and how I feel about it.
Last year around this time I added the following to mod_blog:
if (day.tm_mon == 11) { char dayname[BUFSIZ]; strftime(dayname,BUFSIZ,"%A",&day); fprintf( fpout, "%s, Debtember %02d, %d", dayname, day.tm_mday, day.tm_year + 1900 ); return; }
If you look closely, you'll notice that I render a date like “Wednesday, December 04, 2002” as “Wednesday, Debtember 04, 2002” as a personal protest to the extreme messages of mass consumerism consumption we are bombarded with during that month.
Although the other user (Hi, Mark!) didn't like that feature, so it was a simple matter of making that code conditional and I did it at compile time, not run time (as a matter of personal preference on my part) but in retrospect, it would have been easier to make it a runtime option, but one that I was relunctant to do since it was so specific.
But over the year it meant I had to compile the program twice—once for me, once for Mark (there was another aspect that was different between my version and Mark's that was amplified when Gregory decided to use mod_blog but that aspect as since been fixed) which gets to be a pain. And yet I still resisted making this a runtime decision.
I could have made this a general feature, the ability to specify
alternative names for months, but then why stop there? Why not the days
of the week? But what galls me is that adding such features mean I have
to forego using strftime()
to format the dates (well, not that
there aren't problems with the routines in time.h
already) and
duplicate pretty much what I'm already using.
It was today when I figured out a solution. It may not be the
best solution but it does mean I can rip out the above code,
meaning I only have to compile once, and I can still use
strftime()
to format the date, and I can have Debtember, and
Mark (and Gregory) can have December.
Locales.
Like I said, it may not be the best of solutions, but it does work.
ANSI-C has the concept of a “locale” which specifies such details of
output as the currency symbol, decimal point, number group separators as
well as the names of the weekdays and months. Usually this defaults to the
C or POSIX locale (which is another word for US hegemony on the computing world) but it can be changed
with setlocale()
—all that remains is to figure out how to
create a new locale for my own use.
There isn't much information about doing this, but I was able to munge my
way through. Under Linux (at least Gentoo and RedHat from what I can tell), it meant
creating a file under /usr/share/i18n/locales
(I created one
called en_SPC
for ENglish, SPC variant with “Debtember”) and
then doing localedef -i en_SPC en_SPC
to actually add it to the
system.
So I did have to add an option to the configuration file, but now it specifies the locale to use, which, generally speaking, is a better hack than what I had before.