24

我正在尝试弄清楚如何创建一个基于 Compojure 且支持多语言的网站。有没有像 i18n 之类的解决方案?

4

4 回答 4

18

最简单的方法是用如下函数调用替换所有本地化字符串:

(i18n lang "help")

并实现该函数以从由参数.properties确定的文件中读取本地化字符串。lang

为此,您不需要任何库。这是一个简单的功能。

为了避免一直读取文件,您可以在应用程序期间从内存中读取它们,从def名为loaded-property-fileswhere 的映射开始,lang是键,值是消息键和适当本地化消息的映射。

这可以这样做:

(defn load-property-files [langs]
  (let [default (into {} (read-properties "locale.properties"))]
      (apply merge 
       (for [lang langs] 
        (assoc {} lang
         (merge default 
          (into {} (read-properties (str "locale_" lang ".properties")))))))))

(def loaded-property-files 
      (load-property-files ["en" "es" "de"]))

如果文件加载性能不是问题,但您希望能够在运行时更轻松地更改文件,只需将 更改def为函数即可。

该函数read-properties(最初来自 old clojure.contrib)如下所示:

(defn read-properties
  "Read properties from file-able."
  ([fileable]
   (into {} (map #(vector (keyword (key %)) (val %))
    (try
      (with-open [f (java.io.FileInputStream. (new java.io.File fileable))]
        (doto (new java.util.Properties)
          (.load f)))
    (catch java.io.FileNotFoundException e {})))))
  ([fileable defaults] (merge (read-properties fileable) defaults)))

每当在指定的地图中找不到该键时,将使用文件中的本地化字符串default,即刚刚添加的新字符串,并且还没有人将其翻译成西班牙语,默认情况下将以语言显示locale.properties

然后你的i18n函数看起来像这样:

(defn i18n [lang code]
  ((loaded-property-files lang) code))
于 2010-12-18T16:45:41.437 回答
7

有一个新的 i18n 库:https ://github.com/ptaoussanis/tower有这个理由:

Tower 试图为 Clojure 呈现一个简单、惯用的国际化和本地化故事。它尽可能地包装了标准的 Java 功能,但是当有充分的理由时,它并不害怕脱离 Java 约定。

于 2013-04-12T08:40:50.130 回答
5

我为此创建了clji18n,但在完成之前我必须切换到其他项目。它“几乎”可用,您可以尝试一下。

于 2010-12-18T16:57:12.870 回答
4

kotarak 的 j18n(请注意,还有另一个用于 Java 的 j18n 库,但它们是不同的)看起来不错。

https://bitbucket.org/kotarak/j18n

于 2011-12-06T23:13:02.867 回答