Getting Started
Why use Lens?
Lens was conceived due to various problems within crystal's internationalization ecosystem. As such, Lens aspires to overcome those issues. With lens:
- Support of multiple different formats
- Constant development of new features
- And soon, actual full number and time localization through CLDR
In short, Lens is packed full of features and designed for internationalizing.
Installation
Lens is written in pure crystal and without any external dependencies besides Crystal itself. Thus, installing is as simple as appending Lens to your shard.yml
!
dependencies:
lens:
github: syeopite/lens
version: ~> 0.1.0
After which, you just run shards install
and Lens would be installed.
Usage
First let's import Lens into our program
require "lens"
Now we'll select a format!
Format | Backend | Documentation |
---|---|---|
GNU Gettext PO | Gettext::POBackend |
Here |
GNU Gettext MO | Gettext::MOBackend |
Here |
Ruby YAML | CrystalI18n::I18n 1 |
Here |
For this simple illustration lets use Gettext::MOBackend
.
To get started we just simply initialize it with the locale directory:
Gettext::MOBackend.new("locales")
And then call #create
catalogue_hash = Gettext::MOBackend.create()
catalogue_hash # => Hash(String, Catalogue) or LanguageCode | Filename => Catalogue
catalogue = catalogue_hash["en_US"]
Danger
The API and behaviors for each backend are different! This is to preserve how the format typically handles stuff.
API differences:
# The Gettext backends requires a #create method. This returns an Hash of
# language code (or file name when the corresponding header isn't defined)
# to Catalogue objects
gettext_catalogue_hash = Gettext::MOBackend.new("locales").create
gettext_catalogue = gettext_catalogue["en_US"]
# The backend for ruby-yaml on the other hand is directly the catalogue.
# No need for an additional #create. And naturally, it's also not a hash.
yaml_catalogue = CrystalI18n::I18n.new("locales")
# Gettext
gettext_catalogue.gettext("A message") # => "Translated message"
gettext_catalogue.ngettext("I have %d apple", "I have %d apples", 50) # => "Translated I have %d apples"
# Ruby YAML
yaml_catalogue.translate("en", "translation") # => "Translated Message"
catalogue.translate("en", "possessions.fruits.apples", 50) # => "I have 50 apples"
Behavior differences:
yaml_catalogue.translate("en", "I don't exist") # => raises LensExceptions::MissingTranslation
gettext_catalogue.gettext( "I don't exist") # => "I don't exist"
In the future there would be a chain
backend, and a configuration option will be provided to migrate behavior differences. However, the API for individual backends would always be different.
Keep all of this in mind using Lens!
After which, we're able to freely translate!
# Basic
catalogue.gettext("A message") # => "Translated message"
# Plurals
catalogue.ngettext("I have %d apple", "I have %d apples", 1) # => "Translated I have %d apples"
# Context
catalogue.pgettext("CopyPasteMenu", "copy") # => "Translated copy"
# Context w/ Plurals
catalogue.npgettext("CopyPasteMenu", "Export %d file", "Export %d files", 1) # => "Translated message with plural-form 0"
-
Ruby YAML is the typical format seen in Crystal's internationalization ecosystem. However, each implementation often comes with minor adjustments tailored to their own APIs. Lens' version personally leans more towards the original RubyI18n version. ↩