taoensso / tower

i18n & L10n library for Clojure/Script
https://www.taoensso.com/tower
Eclipse Public License 1.0
278 stars 24 forks source link

Scoping keys #29

Closed asmala closed 10 years ago

asmala commented 11 years ago

This ticket is related to #27, which would see us moving to a closure based implementation rather than bindings. According to that proposal we would create a translation closure t based on a dictionary, locale, and eventual config arguments. Since we would no longer use bindings, with-scope would no longer work and we'd need another solution.

Some options are:

Not much to be said about this one. If (t :a.namespaced/key) is tolerable, then we're good.

Option 2: Clojure namespaced keywords

Since (t ::key) is equivalent to (t :my.namespace/key), this would lead to concise calls to t, but with the obvious minus that translation structure would be tied to structure of source code files. On the other hand, it would align the use of keywords with idiomatic Clojure, since namespacing of keywords is really meant for Clojure namespaces, not translation "namespaces".

Option 3: Closure for scopes

This seems a bit hacky but the syntax is concise enough:

; The following are equivalent
(t [:my.namespace/key])
(let [t (scope-t :my.namespace)]
  (t :key))

Option 4: Separate string interpolation from translation

If the dictionary is a simple map and t doesn't need to handle string interpolation or anything else except for lookups, then we can treat t as simple submap. This leads to some nice, idiomatic Clojure:

(def dict (load-dict))

(let [t (-> dict :en :front-page)]
  [:div.content
   [:h1 (t :title)]
   (let [t (t :content)]
    [:p.welcome (-> t :welcome :sub-heading)])])

The obvious issue is that string interpolation gets verbose, e.g. (loc-fmt locale (t :hello) "Peter") instead of just (t :hello "Peter").