CLIM mail archive


Re: Multilingual (French, English...) applications - any hints?

  From: Schneider Daniel <>
  I wonder whether somebody has been confronted with writing
  multi-lingual applications using CL and CLIM. There are three
  different kinds of strategies as far as I can see:
First a question:
How do you store "French strings" with the accents etc.
using CLIM?

We have some related experience with need for multiple
languages. If your application is small and the string
used for each format or query statement has no more than
one or two lines of text, your LL solution is fine and manageable.

However, including text in multiple languages in the
middle of your code (as the LL solution) becomes rapidly
unbearable. I strongly advise against it except for toy
problems. Instead I suggest using symbolic names for all
multilingual references and doing an initialization-time

One approach is to have separate association lists or tables
mapping symbolic names to corresponding expanded string
in each language [one mapping table per language].
This helps you (or the translator) establish consistency of all
sentences used in a given language. This may also help with the translation
process to other languages later. It is possible
to dynamically switch between languages with no overhead
if the interface definitions in each languages are pre-loaded
(updating already instantiated CLIM displays to a new language
is an exercise left to the reader).

Finally an approach could be inspired from the condition
handling style of CL. The function ERROR has been extended
to handle not only strings but CONDITION objects or condition
types (symbolic name of a condition). Maybe one would want
to extend the functionality of FORMAT, Y-OR-N-P and the more
interactive CLIM style functions (e.g. NOTIFY-USER) to specialize
on SENTENCE or SENTENCE types. A question remains: how to you further
extend ERROR to support CONDITIONS AND multiple languages?

Olivier Clarisse
;;; create a sentence object and store it in a mapping table

(defsentence SYSTEM-WORKING :english (sys) "Is the system ~a working well?")

(defsentence SYSTEM-WORKING :french (sys) "Est-ce que le system ~a marche bien?")

;;; build a table for an :english version of your system interface

(defsentences :english
  SYSTEM-OK (sys) "System ~a is humming along..."
  SYSTEM-DOWN (sys) "System ~a is coming down now!"

;;; dynamically use the appropriate sentence object
;;; based on the current language on the *features* list

(format t 'system-working "MultiLingual")

;;; You can start with something like this:
;;; (where *ll-table* is bound to the current language table.)

(defmacro format-ll (stream sentence &rest args)
  `(apply #'format ',stream (gethash *ll-table* ',sentence)

;;; Also notice that to treat multilingual problems properly you
;;; may have to swap arguments to the formatting string in function
;;; of the language. Possibly by extending DEFSENTENCE to support
;;; keyword arguments and massaging them before applying FORMAT,
;;; or using powerful ~ directives in your formatting strings.

Main Index | Thread Index