Warning: Reason support is experimental. We are looking for beta-tester and contributors.

Code generator

The ocsigen-i18n command reads a TSV file and produces an OCaml source file containing the translations as OCaml functions.

Usage

ocsigen-i18n [options] [< input] [> output]

Options

--languagesComma-separated languages (e.g. en,fr). Must be ordered as in the TSV file.
--default-languageSet the default language (defaults to the first one in --languages).
--input-fileTSV file. If omitted or set to -, reads from stdin.
--output-fileOutput file. If omitted or set to -, writes to stdout.
--external-typeLanguage values come from a predefined type (do not generate the type).
--primaryGenerated file is secondary and depends on the given primary file.
--eliomGenerate code for a client-server Eliom app (implies --tyxml).
--tyxmlGenerate code for a Tyxml-based app.
--headerGenerate only the file header (types and utility functions, without translations).

Generation modes

Default mode (no flags)

Generates plain OCaml code:

  • A type t with one constructor per language
  • Functions string_of_language, language_of_string, and guess_language_of_string
  • A list languages of all variants
  • Language storage using a simple ref (get_language, set_language)
  • A module Tr containing string translation functions

--tyxml mode

Like the default mode, but additionally:

  • Opens Tyxml.Html
  • The Tr module generates HTML elements (using txt)
  • A Tr.S submodule provides string variants

--eliom mode

Generates Eliom client-server code:

  • Type and utility functions use let%shared
  • Language storage uses Eliom scoped references on the server and a simple ref on the client
  • The type t has [@@deriving json] for client-server communication
  • Translation modules are wrapped in [%%shared ...]

Example output (default mode)

$ ocsigen-i18n --languages en,fr < example.tsv
type t = En|Fr
exception Unknown_language of string
let string_of_language = function
| En -> "en"| Fr -> "fr"
let language_of_string = function
| "en" -> En| "fr" -> Fr| s -> raise (Unknown_language s)
...
module Tr = struct
let foo ?(lang = get_language ()) () () =
  match lang with
  | En -> "This is a simple key."
  | Fr -> "Ceci est une clé toute simple."
...
end

Dune integration

Use a dune rule to generate the OCaml file from your TSV file:

(rule
 (target example_i18n.ml)
 (deps example_i18n.tsv)
 (action
  (run %{bin:ocsigen-i18n} --languages en,fr --input-file %{deps}
    --output-file %{target})))

For an Eliom application, use --eliom to generate an .eliom file:

(rule
 (target example_i18n.eliom)
 (deps example_i18n.tsv)
 (action
  (run %{bin:ocsigen-i18n} --eliom --languages en,fr --input-file %{deps}
    --output-file %{target})))

Using multiple TSV files

Use --primary to generate a secondary file that depends on a primary one:

ocsigen-i18n --languages en,fr \
  --input-file main_i18n.tsv --output-file main_i18n.ml
ocsigen-i18n --languages en,fr \
  --primary main_i18n.ml \
  --input-file extra_i18n.tsv --output-file extra_i18n.ml

Header-only generation

Use --header to generate only the type definitions and utility functions, without parsing a TSV file. This is useful when you want to define the type in one file and the translations in another:

ocsigen-i18n --languages en,fr --header \
  --output-file i18n_type.ml

Backward compatibility

The command ocsigen-i18n-generator is provided as an alias for ocsigen-i18n --eliom. Existing build systems using the old command name will continue to work.