Skip to content

TiLogic/gettext-clj

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gettext-clj

gettext-clj ( gtclj ) is a library that allows developers quickly and easily internationalize their Clojure, ClojureScript and ClojureDart projects.

Using standard GNU gettext utilities gtclj extracts translatable strings from .clj , .cljc , .cljx , .cljs and .cljd files into Portable Object ( po , pot ) files. The po file format is widely supported by translation software, and many programming languages. Translated po files are parsed by gtclj into compact, Clojure friendly JSON.

Features

  • pure Clojure (no external dependencies)
  • simple map data format
  • plural support for 121 languages (derrived from Unicode CLDR data)
  • context support to allow for multiple translations of the same message (ui elements, homonyms, gender etc.)
    • e.g.{{"Queue" "File d'attente"} "tab" {"Queue" "File"}}
  • fallback to a language other than english with a simple merge
    • e.g.(merge (json/read-str (slurp "be-nl.json")) (json/read-str (slurp "be-fr.json")))

Requirements

po file creation

gettext

bash

JSON file creation

bash

gettext-clj library

None. gtclj is a pure Clojure project, with no external dependencies.

Quick Start

git clone https://github.com/TiLogic/gettext-clj
cd gettext-clj

extract

# Extract po files (locales are optional)
bash cli/gtclj -p -s path/to/clj/project/dir -o path/to/output/dir fr_CA fr_FR de_DE

parse

# Parse to JSON
bash cli/gtclj -j -s path/to/po/files -o path/to/output/dir

clojure

;; deps.edn
{:paths ["src"]
 :deps {,,,
        tilogic/gettext-clj
        {:git/url "https://github.com/TiLogic/gettext-clj.git"
         :sha "fcf8f3b8b2937e8a93576041ef98b623bf3de96d"}}}
(ns my.namespace
  (:require
   [clojure.data.json :as json]
   [tilogic.gettext-clj :as gt]))

(def data (atom nil))
(def fr-ca {"Hello, world!" "Salut, monde!"
            "What a beautiful cat!" ["Quel beau chat!"  "Quels beaux chats!"]
            "Duck!" "Baisser la tête!"
            "She found a bat in her basement." ["Elle a trouvé un bâton de baseball dans son sous-sol." "Elle a trouvé des bâtons de baseball dans son sous-sol."]
            "bird" {"Duck!" "Canard!"}
            "mammal" {"She found a bat in her basement." ["Elle a trouvé une chauve-souris dans son sous-sol." "Elle a trouvé %s chauves-souris dans son sous-sol."]}})

(gt/add-locale data :jp (json/read-str (slurp "assets/jp.json")))
(gt/add-locale data :fr-ca fr-ca)
(gt/set-locale data :fr-ca)

(def gettext (gt/gettext-fn data))
(def ngettext (gt/gettext-fn data))
(def pgettext (gt/gettext-fn data))
(def npgettext (gt/gettext-fn data))

(gettext "Hello, world!") ;; => "Salut, monde!"

(ngettext "What a beautiful cat!" "What beautiful cats!" 17) ;; => "Quels beaux chats!"

(pgettext "bird" "Duck!") ;; => "Canard!"

(format (npgettext "mammal"
                    "She found a bat in her basement."
                    "She found %s bats in her basement."
                    2) 2) ;; => "Elle a trouvé 2 chauves-souris dans son sous-sol."

(pgettext "bird" "Duck!" :jp) ;; => "鴨!"

JSON file / Clojure map format

{"msgid" "msgstr"
 "a message" "a translated message"
 "msgid (plural)" ["msgstr[0]" "msgstr[1]" "msgstr[n]"]
 "a plural message" ["plural translation 0" "plural translation 1" "plural translation n"]
 "context" {"message" "translated message"}}

FAQ

Does Clojure really need another translation library?

No (and yes!). There are many fine internationalization libraries1, but (currently) none of them work with ClojureDart — hence, the existence of gettext-clj.

Why gettext?

gettext's .po file format is widely used by translation software, and can be easily converted to other formats if required.

Do I have to use po and JSON files with gtclj?

No. The gtclj library uses a Clojure map as as its data format. String extraction and po file parsing are optional.

Why JSON instead of edn?

ClojureDart does not currently support edn.

Development

Running Tests

Clojure

clj -X:test

ClojureScript

clj -M:test-cljs

ClojureDart

sh test/cljd/run.sh

cli

bash test/cli/run.sh

Footnotes

  1. Tempura, Tongue and Pottery to name a few.