Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
R18n is an i18n tool to translate your Ruby application into several languages.
You can use wrapper plugins
like r18n-rails
or sinatra-r18n
to localize web applications
and r18n-desktop
to localize desktop application.
See full features in main README.
To add i18n support to your app, we suggest you to use
the particular plugin for your environment,
for example r18n-rails
, sinatra-r18n
or r18n-desktop
.
If you develop you own plugin or want to use only core gem, you will need to set default translation places and current locale:
R18n.default_places = 'path/to/translations'
R18n.set('en')
You can use R18n.t
to get translations and R18n.l
to localize times and
numbers. But more useful is to add helpers to fast access the R18n:
include R18n::Helpers
t.yes #=> "Yes"
l Time.now, :human #=> "now"
r18n.locale.code #=> "en"
To set locale only for current thread use R18n.thread_set
.
Translation files are in YAML format by default and have names like
en.yml
(English) or en-us.yml
(USA English dialect) with
language/country code (RFC 3066). Upcased region (en-US
) and
.yaml
file extension are also allowed.
In your translation files you can use:
Strings
robot: This is a robot
percent: "Percent sign (%)"
Numbers
number: 123
float: 12.45
Pluralizable messages
robots: !!pl
0: No robots
1: One robot
n: '%1 robots'
Filters
filtered: !!custom_type
This content will be processed by a filter
To get the translated string use a method with the key name or square brackets
[] for keys, which is the same with Object methods (class
, inspect
, etc):
t.robot #=> "This is a robot"
t[:robot] #=> "This is a robot"
Translation may be hierarchical:
t.post.add #=> "Add post"
t[:post][:add] #=> "Add post"
If the locale isn't found in the user's requested locale, R18n will search for it in sublocales or in another locale, which the user also can accept:
t.not.in.english #=> "В английском нет"
The translated string has a locale
method for determining its locale (Locale
instance or code string if locale is't supported in R18n):
i18n.not.in.english.locale #=> Locale ru (Русский)
You can include parameters in the translated string by specifying arguments:
name: My name is %1
t.name('John') #=> "My name is John"
Pluralizable messages get their item count from the first argument:
t.robots(0) #=> "No robots"
t.robots(1) #=> "One robot"
t.robots(50) #=> "50 robots"
If there isn't a pluralization for a particular number, translation will be use
n
. If there isn't a locale file for translation, it will use the English
pluralization rule (0
, 1
and n
).
You can check if the key has a translation:
t.post.add.translated? #=> true
t.not.exists.translated? #=> false
You can set a default value for untranslated strings:
t.not.exists | 'default' #=> "default"
You can query the translation keys:
t.counties.translation_keys.each do |county|
puts t.counties[county]
end
R18n already has translations for common words for most built in locales.
See base/
the source.
t.yes #=> "Yes"
t.cancel #=> "Cancel"
t.delete #=> "Delete"
You can also add you own filters for translations: escape HTML entities, convert from Markdown syntax, etc. Filters can be passive, only being processed when loaded.
friendship: !!gender
f: She adds a friend
m: He adds a friend
R18n::Filters.add('gender', :user_gender) do |content, config, user|
if user.female?
content['f']
else
content['m']
end
end
t.friendship(anne) #=> "She adds a friend"
To create a filter you pass the following to R18n::Filters.add
:
!!type
), String
for all translations of
R18n::Untranslated
for missing translations.R18n::Filters.off
, R18n::Filters.on
and
R18n::Filters.delete
.Hash
with options:
passive: true
to filter translations only on load;:position
within the list of current filters of this type
(by default a new filter will be inserted into last position).The filter will receive at least two arguments:
Hash
with translation locale
and path
.In Rails application put your filters to app/i18n/filters.rb
, it will be
automatically reloaded in development.
R18n contains 2 filters to escape HTML entities: by YAML type and global. If you
need to escape HTML in some translations, just set !!escape
YAML type:
greater: !!escape
1 < 2 is true
t.greater #=> "1 < 2 is true"
If you develop web application and want to escape HTML in all translations, just activate the global escape filter:
R18n::Filters.on(:global_escape_html)
If you enable global HTML escape, you may still use !!html
YAML type to
disable escaping on some values:
warning: !!html
<b>Warning</b>
R18n::Filters.on(:global_escape_html)
t.warning #=> "<b>Warning</b>"
To use Markdown in your translations you must install the Kramdown gem:
hi: !!markdown
**Hi**, people!
t.hi #=> "<p><strong>Hi</strong>, people!</p>"
If you can't use Kramdown you can redefine Markdown filter to use your own parser:
# Disable standard Markdown filter
Filters.off(:kramdown)
# Add new filter for !!markdown YAML type
Filters.add('markdown', passive: true) do |content, config|
require 'redcarpet'
markdown = ::Redcarpet::Markdown.new(Redcarpet::Render::HTML)
markdown.render(content)
end
To use Textile in your translations you must install the RedCloth
gem:
alarm: !!textile
It will delete _all_ users!
t.alarm #=> "<p>It will delete <em>all</em> users!</p>"
After enabling built-in named_variables
filter, you can use named variables
in all translations:
greeting: "Hi, %{name}"
users: !!pl
1: One user
n: {{count}} users
Filters.on(:named_variables)
t.greeting(name: 'John') #=> "Hi, John"
t.users(count: 5) #=> "5 users"
You can print numbers and floats according to the rules of the user locale:
l -12000.5 #=> "−12,000.5"
Number and float formatters will also put real typographic minus and put non-breakable thin spaces (for locale, which use it as digit separator).
You can translate months and week day names in Time
, Date
and DateTime
by the strftime
method:
l Time.now, '%B' #=> "September"
R18n has some built-in time formats for locales: :human
, :full
and
:standard
(the default):
l Time.now, :human #=> "now"
l Time.now, :full #=> "August 9th, 2009 21:47"
l Time.now #=> "2009-08-09 21:41"
l Time.now.to_date #=> "2009-08-09"
You can add i18n support to any classes, including ORM models (ActiveRecord
,
Sequel
, DataMapper
, MongoMapper
, Mongoid
or others):
class Product
include DataMapper::Resource
property :title_ru, String
property :title_en, String
include R18n::Translated
translations :title
end
# For example, user only knows Russian
# Set English (default) title
product.title_en = "Anthrax"
product.title #=> "Anthrax"
# Set value for user locale (Russian)
product.title = "Сибирская язва"
product.title #=> "Сибирская язва"
product.title_en #=> "Anthrax"
product.title_ru #=> "Сибирская язва"
See R18n::Translated
for documentation.
All supported locales are stored in r18n-core
gem in locales/
directory.
If you want to add your locale, please see the "Add Locale"
section.
To get information about a locale create an R18n::Locale
instance:
locale = R18n.locale('en')
You can then get the following from the locale:
Locale title and RFC 3066 code:
locale.title #=> "English"
locale.code #=> "en"
Language direction (left to right, or right to left for Arabic and Hebrew):
locale.ltr? #=> true
Week start day (:monday
or :sunday
):
locale.week_start #=> :sunday
You can load translations from anywhere, not just from YAML files. To load translation you must create loader class with 2 methods:
available
– return array of locales of available translations;load(locale)
– return Hash
of translation.Pass its instance to R18n.default_places
or R18n.set(locales, loaders)
R18n.default_places = MyLoader.new(loader_param)
R18n.set('en')
You can set your default loader and pass it to R18n.set
as the only
constructor argument:
R18n.default_loader = MyLoader
R18n.default_places = loader_param
R18n.set('en')
R18n.set('en', different_loader_param)
If you want to load a translation with some type for filter, use
R18n::Typed
struct:
# Loader will return something like:
{ 'users' => R18n::Typed.new('pl', { 1 => '1 user', 'n' => '%1 users' }) }
# To use pluralization filter ("pl" type):
t.users(5) #=> "5 users"
You can also set several loaders to merge translations from different sources:
R18n.default_places = [MyLoader.new, DBLoader.new, 'path/to/yaml']
For r18n plugin you can add loaders with translations, which will be used with application translations. For example, DB plugin may place translations for error messages in extension directory. R18n contain translations for base words as extension directory too.
R18n.extension_places << R18n::Loader::YAML.new('./error_messages/')
If R18n has not got locale file for your language, please add it. It's very simple:
%{code}.rb
for your language and describe locale, then
require it in the project. Just copy from another locale and change the
values.
sublocales %w[%{another_locale} en]
.R18n::Locale
class methods.If you want to send a pull request:
%{code}.rb
file in the locales/
directory.%{code}.yml
file for your language in the base/
directory and
translate the base messages. Just copy file from language, which you know,
and rewrite values.%{code}
is RFC 3066 code for your language (for example, en
for English and
fr-CA
for Canadian French). Email me with any questions you may have, you will
find other contact addresses at sitnik.ru.
R18n is licensed under the GNU Lesser General Public License version 3. See the LICENSE file or www.gnu.org/licenses/lgpl-3.0.html.
Andrey “A.I.” Sitnik andrey@sitnik.ru
FAQs
Unknown package
We found that r18n-core demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.