{"id":16014883,"url":"https://github.com/thheller/cljs-i18n-api","last_synced_at":"2025-04-05T02:43:16.297Z","repository":{"id":140236548,"uuid":"116948213","full_name":"thheller/cljs-i18n-api","owner":"thheller","description":"API proposal for compiler-aided i18n for CLJS (draft)","archived":false,"fork":false,"pushed_at":"2018-01-11T11:28:31.000Z","size":4,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-10T11:11:43.058Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thheller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-10T11:21:16.000Z","updated_at":"2018-01-10T11:35:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"1523eadc-4896-40b0-9f83-d09cd33c4e1e","html_url":"https://github.com/thheller/cljs-i18n-api","commit_stats":{"total_commits":2,"total_committers":1,"mean_commits":2.0,"dds":0.0,"last_synced_commit":"fcf2997360eaebd709740b84a62dc1e9ec9462ef"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fcljs-i18n-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fcljs-i18n-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fcljs-i18n-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thheller%2Fcljs-i18n-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thheller","download_url":"https://codeload.github.com/thheller/cljs-i18n-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280181,"owners_count":20912965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-08T15:05:25.608Z","updated_at":"2025-04-05T02:43:16.272Z","avatar_url":"https://github.com/thheller.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cljs.i18n - API proposal\n\nfulcro provides an i18n API which currently requires a separate CLJS build and involves a whole bunch of `gettext` related tooling to extract strings for translation. This is unreliable and breaks easily since it requires the code to be emitted in a certain way.\n\nThis could be significantly easier when using the `tr` macro itself to collect all relevant strings and being able to extract them on demand via the CLJS analyzer data.\n\n## User API\n\nThe user API is simple and relies on a single `tr` macro.\n\n```clojure\n(ns demo.i18n\n  (:require [cljs.i18n :refer (tr)]))\n\n;; simple translation\n(tr \"translate me plz\")\n\n;; translation with dynamic replacements, FormatJS?\n(tr \"foo {thing} bar\" :thing something-dynamic)\n(tr \"foo {thing} bar\" {:thing something-dynamic}\n(tr \"foo {thing} bar\" a-map)\n(tr \"...\" :one 1 {:two 2})\n(tr \"...\" :one 1 a-map\n\n;; translation with context\n;; when the same string is used in different contexts\n(tr \"foo?\" :cljs.i18n/context \"foo\" ...)\n(tr \"foo?\" :cljs.i18n/context \"bar\" ...)\n```\n\n## Providing Translations\n\nThe translations are provided via a simple protocol with no default implementation. Keeping track of the users locale and available translations is not part of the API.\n\n```clojure\n(ns demo.i18n)\n\n(defprotocol ITranslate\n  (-get-text [this context key args]))\n```\n\n- `context` is either `nil` or a `\"string\"`\n- `key` is the original text or key used in `tr`\n- `args` is expected to be a clojure map (not checked currently since the user can pass in anything)\n\nAt runtime the user (or build tool) can set the translation implementation. A toy implementation that just upper cases all strings could look like this.\n\n```clojure\n(cljs.i18n/set-translator!\n  (reify cljs.i18n/ITranslate\n    (-get-text [this context key args]\n      (clojure.string/upper-case key))))\n```\n\nLibraries can provide different `ITranslate` implementations that handle the actual loading/formatting of the translation strings.\n\n## Extracting Strings\n\nThe `cljs.i18n/tr` macro collects all used strings per namespace. It is added to the `cljs.env/*compiler*` atom on compile under the `[:cljs.analyzer/namespaces demo.i18n :cljs.i18n/strings]` key. It is a vector containing simple maps.\n\n```clojure\n[{:ns demo.i18n\n  :msg \"foo {thing} bar\"\n  :context nil\n  :line 5\n  :column 4\n  :args [:thing]}]\n```\n\nTools can extract this data and generate `.pot` files or any other translation format. The information is collected per namespace so it works properly with compiler caching enabled. It should be de-duped before passing it to other tools but only AFTER compilation finishes.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthheller%2Fcljs-i18n-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthheller%2Fcljs-i18n-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthheller%2Fcljs-i18n-api/lists"}