Lightweight i18n using re-frame modified

A lightweight i18n solution for use with re-frame. It's inspired by Tower, a Clojure/Script i18n & L10n library.

Update: later found the Tongue library (by Nikita Prokopov).

i18n code

 1(ns examplens.i18n
 2  (:require [examplens.translations :refer [translations]]))
 3
 4(def i18n-not-found-key "*I18N-KEY*")
 5(def i18n-not-found-fallback-lc "*I18N-FB-LC*")
 6
 7(defn- _t
 8 "Returns translation for key based on supplied locale."
 9 [lc key]
10 {:pre [(not (nil? key))]
11 :post [(not (nil? %))]}
12
13 (let [fb-lc (:fallback-lc translations)
14       td (:dictionary translations)
15       tdk (get td key)]
16   (if (nil? tdk)
17      i18n-not-found-key
18      (if (and (not (nil? lc)) (contains? tdk lc))
19        (get tdk lc)
20        (if (contains? tdk fb-lc)
21          (get tdk fb-lc)
22          i18n-not-found-fallback-lc)))))
23
24(def t
25  "Returns memoized translation for key (based on supplied locale)."
26  (memoize _t))

Example translations code

 1(ns examplens.translations)
 2
 3(def translations
 4  "Table with translations per locale."
 5  {:fallback-lc :en-US
 6   :dictionary
 7   {:home-title {:en-US "Welcome"
 8                  :nl-NL "Welkom"}
 9    :home-subtitle {:en-US "Time to start building the site."
10                     :nl-NL "Tijd om de site te maken."}
11    :home-content {:en-US "The content for the home page."
12                    :nl-NL "De inhoud voor de home pagina."}}})

The re-frame related code

 1;; In the re-frame database a :lc field is
 2;; defined (with an initial value).
 3... {:lc :nl-NL} ...
 4
 5;; Handler.
 6(f/register-handler
 7  :set-lc
 8  (fn [db [lc]]
 9    (assoc db :lc lc)))
10
11;; A subscription handler is set up.
12(f/register-sub
13  :lc
14  (fn [db _]
15    (reaction (:lc @db))))
16
17;; Consumption in a re-frame component (when the locale
18;; changes the view is automatically updated).
19(defn home []
20  (let [lc (f/subscribe [:lc])]
21    (fn []
22       [:div
23        [:div
24         [:h1 (i18n/t @lc :home-title)]]
25        [:div
26         [:h3 (i18n/t @lc :home-subtitle)]]
27        [:div
28         [:p (i18n/t @lc :home-content)]]])))

Posts in this Series