Next: , Previous: API, Up: Top



4 I18N

4.1 Internationalisation

CL-L10N supports internationalised strings through the use of bundles. The process is currently extremely basic, and is bound to change in the future, but is flexible and does what is expected of it.

First you define a bundle using make-instance.

     (defvar *my-bundle* (make-instance 'bundle))

Then you add resources to your bundle using either add-resource or add-resources.

(add-resources (bundle "af_")
  "showtime" "Dankie, die tyd is ~:@/cl-l10n:format-time/~%")

;; an empty string as the locale matcher becomes the default
(add-resources (bundle "") 
  "showtime" "Thanks, the time is ~:@/cl-l10n:format-time/~%")

Then by using gettext you can lookup locale specific strings.

     (defun timey () (format t (gettext "showtime" bundle) 3310880446))
     (timey) ;; with locale en_ZA
      prints `Thanks, the time is Wed 01 Dec 2004 11:00:46 +0200`
     
     (let ((*locale* (locale "af_ZA")))
       (timey))
      prints `Dankie, di tyd is Wo 01 Des 2004 11:00:46 +0200`

A useful trick is to define either a macro or reader macro wrapping gettext for your specific bundle eg.

     (set-dispatch-macro-character
      #\# #\"
      #'(lambda (s c1 c2)
          (declare (ignore c2))
          (unread-char c1 s)
          `(cl-l10n:gettext ,(read s) bundle)))
     
     ;; or this
     
     (defmacro _ (text)
       `(cl-l10n:gettext ,text bundle))
     

which would change the timey function to

     (defun timey () (format t #"showtime" 3310880446))
     ;; or
     (defun timey () (format t (_ "showtime") 3310880446))
     

4.2 API

— Generic: add-resource bundle from to locale-name

Adds an entry to bundle for locale-name mapping from to to. The locale-name does not have to be a full name like “en_US” but can be a partial match like “en_”. Adding mappings for these two locale-names will result in the mapping for “en_US” being used when the locale is “en_US” and the mapping for “en_” being used when using any other english locale. Adding a mapping for an empty locale-name will become the default.

          ;; Add mapping for welcome for Afrikaans languages.
          (add-resource *my-bundle* "welcome" "welkom" "af_")
     

— Macro: add-resources (bundle locale-name) &rest entries

Utility macro to group large amounts of entries into a single logical block for a locale.

          (add-resources (bundle "af_")
            "hello" "hallo"
            "goodbye" "totsiens"
            "yes" "ja"
            "no "nee")
          
          ==
          
          (add-resource bundle "hello" "hallo" "af_")
          (add-resource bundle "goodbye" "totsiens" "af_")
          (add-resource bundle "yes" "ja" "af_")
          (add-resource bundle "no" "nee" "af_")
          
     

— Function: gettext name bundle &optional (*locale* *locale* )

Looks for a mapping for name in bundle. If no mapping is found returns name.