我正在尝试弄清楚如何创建一个基于 Compojure 且支持多语言的网站。有没有像 i18n 之类的解决方案?
4 回答
最简单的方法是用如下函数调用替换所有本地化字符串:
(i18n lang "help")
并实现该函数以从由参数.properties
确定的文件中读取本地化字符串。lang
为此,您不需要任何库。这是一个简单的功能。
为了避免一直读取文件,您可以在应用程序期间从内存中读取它们,从def
名为loaded-property-files
where 的映射开始,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))
有一个新的 i18n 库:https ://github.com/ptaoussanis/tower有这个理由:
Tower 试图为 Clojure 呈现一个简单、惯用的国际化和本地化故事。它尽可能地包装了标准的 Java 功能,但是当有充分的理由时,它并不害怕脱离 Java 约定。
我为此创建了clji18n,但在完成之前我必须切换到其他项目。它“几乎”可用,您可以尝试一下。
kotarak 的 j18n(请注意,还有另一个用于 Java 的 j18n 库,但它们是不同的)看起来不错。