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

Internationalization 如何在Clojure中编写多语言应用程序?,internationalization,clojure,multilingual,compojure,Internationalization,Clojure,Multilingual,Compojure,我正试图找出如何创建一个支持多语言的基于Compojure的网站。有没有像i18n之类的解决方案?最简单的方法是用如下函数调用替换所有本地化字符串: (i18n lang“帮助”) 并实现该函数以从由lang参数确定的.properties文件中读取本地化字符串 因此,您不需要任何库。这是一个简单的函数 为了避免一直读取文件,您可以在应用程序运行期间从def开始将文件读取到名为加载的属性文件的映射中,其中,lang是键,值是消息键和相应本地化消息的映射 可以这样做: (defn load-pro

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

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

(i18n lang“帮助”)

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

因此,您不需要任何库。这是一个简单的函数

为了避免一直读取文件,您可以在应用程序运行期间从
def
开始将文件读取到名为
加载的属性文件的映射中,其中,
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"]))
(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)))
(defn i18n [lang code]
  ((loaded-property-files lang) code))
如果文件加载性能不是问题,但您希望能够在运行时更轻松地更改文件,只需将
def
更改为函数即可

函数
readproperties
(源于旧的
clojure.contrib
)如下所示:

(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"]))
(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)))
(defn i18n [lang code]
  ((loaded-property-files lang) code))
只要在指定的映射中找不到该键,就会使用
default
文件中的本地化字符串,即刚刚添加的新字符串,并且还没有人将其翻译为西班牙语,将以默认
locale.properties中的语言显示

然后,您的
i18n
函数如下所示:

(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"]))
(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)))
(defn i18n [lang code]
  ((loaded-property-files lang) code))
我为此而创建,但在完成它之前,我必须切换到其他项目。它“几乎”可用,您可以尝试一下。

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


有一个新的i18n库:基于此原理:

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


在这个函数中重用现有的JVM资源包基础设施可能是合理的。这并不漂亮,但至少它定义了知名命名方案的机制,以及如何找到具有一系列回退选项的捆绑包,以便您可以优雅地降级并减少重叠。@Alex:我同意,但我不太熟悉直接使用内置捆绑包支持。大多数时候,我要么使用框架,要么自己解析文本文件,就像这里一样。