Самый простой способ - заменить все ваши локализованные строки вызовами функций, такими как:
(i18n lang "help")
И реализовать эту функцию для чтения локализованной строки из файла .properties
, определенного параметром lang
.
Для этого вам не нужны никакие библиотеки. Это простая функция.
Чтобы не читать файлы постоянно, вы можете читать их в памяти во время ваших приложений, начните с def
в карту с именем loaded-property-files
, где 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
(изначально из старого 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))