如何在Clojure中编写多语言应用程序?

jar*_*rik 23 multilingual clojure internationalization compojure

我正在试图找出如何创建一个具有多语言支持的基于Compojure的网站.有没有像i18n这样的解决方案?

Gor*_*vic 17

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

(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"]))
Run Code Online (Sandbox Code Playgroud)

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

该函数read-properties(最初来自旧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)))
Run Code Online (Sandbox Code Playgroud)

default只要在指定的地图中找不到该密钥,就会使用文件中的本地化字符串,即刚刚添加的新字符串,并且没有人用西班牙语翻译它,将以默认语言显示locale.properties

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

(defn i18n [lang code]
  ((loaded-property-files lang) code))
Run Code Online (Sandbox Code Playgroud)

  • 在此函数中重用现有JVM资源包基础结构可能是合理的.它并不漂亮,但至少它定义了众所周知的命名方案的机制,以及如何使用一系列后备选项查找包,这样您就可以优雅地降级并减少重叠. (5认同)

jne*_*ira 7

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

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


小智 5

我为此创建了clji18n,但在完成之前我不得不切换到其他项目.它"几乎"可用,你可以尝试一下.