Git Product home page Git Product logo

nii's Introduction

Nii

Test

Nii is an internationalization (i18n) and localization (l10n) solution for Ruby. It is modular, comprehensive, fast, and built on top of modern standards and best practices.

With Nii, you can manage translations, localize any Ruby object, all with an easy to use, powerful configuration setup. It includes out of the box support for 233 languages, with 1531 language variants.

Translation Management

Nii manages your application's translated content. Similar solutions include Ruby I18n, R18n, gettext, and FastGettext.

Example

locales/en/example.ftl (localization for English, using Fluent):

hello-world = Hello World!

greeting =
  { NOW() -> 
    [morning]   Good morning, {$name}!
    [afternoon] Good afternoon, {$name}!
    [night]     Good night, {$name}!
   *[other]     Good day to you!
  }

example.rb:

# Load translations from "locales" directory
config = Nii["locales", namespace: :example]

# Create a new context for Englisch
context = Nii::Context.new(:en, config)
context.render "hello-world"                # => "Hello World!"
context.render :greeting, { name: "Maria" } # => "Good morning, Maria!" (depending on time of day)

Notable Features

  • Load translations from the local file system. Supports a range of directory structures and naming conventions.
  • Load translations from an inline definition.
  • Load translations from a database. A wide range of databases is supported. Nii can also reuse an existing Active Record or Sequel connection or connection pool.
  • Load translations from multiple sources.
  • Translations are grouped in namespaces for content isolation.
  • Support for reusable terms and translation attributes.
  • Load translations from a custom backend.
  • Support for a wide variety of file formats, including Fluent, Gettext, YAML, JSON, TOML, XLIFF, Java/Mozilla properties files and more.
  • Ability to convert between file formats. Useful if developers work with different formats than translators, or to import translations.
  • Automatically load new translations and reload updated translations in development mode. It will only reload updated files.
  • Advanced support for various grammatical rules, including plural categories (cardinal/ordinal/ranges, full support for all CLDR conditions), cases, genders, definiteness, T-V distinction (formal vs informal pronouns).
  • Directly load translations from Ruby I18n or R18n into Nii.
  • Use Nii as a backend for Ruby I18n.
  • Built-in support for HTML formatting, sanitizing, and escaping (compatible with Active Support).
  • Support for positional and named arguments, which can be provided ad hoc and/or predefined.
  • Comes with a library of template functions for more flexible translations.
  • Script and directionality aware string constructions, with automatic support for bidirectional text, with embedded UTF-8 markers or HTML tags.
  • Differentiates between language inheritance and fallbacks, to avoid mixed language content.

Object Localization

Nii converts various Ruby objects into human readable, well formatted, localized strings. Similar solutions include TwitterCldr and Active Support.

Example

# Create a context for English
nii = Nii::Context.new "en" # => #<Nii::Context:en-US>

# Formatting various objects
nii.format 9.99, style: :currency            # => "$9.99"
nii.format Nii::Territory["US"]              # => "United States"
nii.format ["de", "fr", "it"], as: :language # => "German, French, and Italian"

# Spelling out numbers (and other objects)
nii.spellout 2020                 # => "two thousand twenty"
nii.spellout 2020, rule: :year    # => "twenty twenty"
nii.spellout 115,  rule: :ordinal # => "one hundred fifteenth"

# Proper HTML interpolation
values = ["<foo>", "<bar>"]
result = nii.format(values) { nii.html "<b>?</b>", _1 }
result            # => "<b>&lt;foo&gt;</b> and <b>&lt;bar&gt;</b>"
result.html_safe? # => true

# Using RubyMoney
require "money"
price = Money.eur 15_00
nii.format   price # => "€15.00"
nii.spellout price # => "fifteen euros"

Notable Features

  • Format numeric values with smart defaults and a high level of customizability.
    • Localized symbols, delimiters, and separators.
    • Localized delimiter and separator position (numbers in Indian English and other languages are formatted correctly).
    • Fine-grained control over precision, rounding, sign display, etc.
    • Support for Unicode style decimal formatting patterns (subset of Excel/Google decimal patterns).
    • Support for Unicode Rule Based Number Formats (RBNF).
    • Support for multiple formatting styles (default, decimal, currency, precent, or unit).
    • ECMAScript API compatibility (you can use the same formatting rules server-side that you use in your client-side JavaScript code).
    • Support for various numbering systems, including decimal systems (Latin, Arab, etc), and non-decimal systems (like Traditional Chinese Numerals). You can directly specify a different numbering system, or have Nii pick the appropriate default, native, traditional, or financial numbering system for the given locale.
  • Format money objects, compatible with RubyMoney, shopify-money, custom Money classes, as well as directly from numeric values (if you provide a currency or style option).
    • Localized currency symbols and names (AS$ vs $).
    • Localized currency position and spacing rules.
    • Handles unknown currencies well (example: falls back to RubyMoney currency information for BTC, which is not included in the CLDR).
    • Ability to round to valid cash amount (for currencies that don't have a single cent/fraction coin or bill).
  • Format Arrays as lists.
    • Support different styles (and/or/unit, each also as short or narrow).
    • Provide formatting options applied to all elements.
    • Dynamically format elements in the list (useful for injecting markup).
    • Support complex localization rules (languages like Spanish, Hebrew, and Luxembourgish use different words or spellings for "and" depending on the list elements).
    • Properly handle bidirectional content (for example, Arabic words listed in English).
  • Format Hashes as localized key-value list.
  • Built-in formatters for popular gems.
    • Active Support: Duration, TimeZone, TimeWithZone.
    • Concurrent Ruby: Array, Hash, Map, Set, Tuple.
    • TZinfo: Timezone, Timestamp, Country.
    • Nii: Calendar, Date, DayPeriod, Locale, NumberingSystem, Territory, Timezone, Timezone::Meta, Units (as part of nii-units).
    • RubyMoney, shopify-money.
  • Format Date, Time, and DateTime.
    • Support alternative calendars (anything besides Gregorian requires nii-calendars gem).
    • Determine localized day period ("afternoon" has a different meaning based on language and location).
  • Format strings and symbols.
    • Turn identifiers into localized names for calendar systems, collation algorithms, currencies, day periods, keys, languages, measurement systems, countries and territories, scripts, units, and variants.
    • Format strings as if they were numbers.
  • Spell out numbers and money objects as words and phrases.
    • Supports multiple spelling rules per language to handle cardinal and ordinal numbers, as well as cases, genders and other grammatical aspects.
  • Partially format and re-format values (useful for setting default formatting rules for variable passed to dynamic translations).
  • Add custom formatters for your own Ruby objects.

Content Negotiation

todo

Example

todo

Notable Features

todo

Advanced Setups

todo

Example

todo

Notable Features

todo

Modern Internals

todo

License

Nii is licensed under an MIT License. It also includes modified versions of the CLDR data files, which are licensed under a Unicode license.

nii's People

Contributors

rkh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nii's Issues

Hover menu on website not working on iOS

The hover based drop down menu isn't working for me on iOS, same with the hover based info boxes on the feature comparison. It is unclear to me why, as I have successfully used this technique before, and it is a nice way to avoid using any JavaScript.

Fluent Support

  • Implement Parser
  • Implement Compiler
    • Message Definition
    • Attribute Definition
    • Term Definition
    • Function Call
    • Number Literals
    • String Literals
    • Variable References
    • Message References
    • Term References
    • Attribute References
    • Variant Selectors
    • Comments (comments are ignored right now, at minimum Nii should assign them to a message where appropriate)

Luxembourgish "and"

Luxembourgish needs more advanced logic for formatting a list (similar to Spanish/Hebrew).

Expected:

nii = Nii::Context.new :lb
nii.format [1, 2]         # => "1 an 2"
nii.format ["du", "ech"]  # => "du an ech"
nii.format ["hien", "si"] # => "hien a si"

Actual:

nii = Nii::Context.new :lb
nii.format [1, 2]         # => "1 a(n) 2"
nii.format ["du", "ech"]  # => "du a(n) ech"
nii.format ["hien", "si"] # => "hien a(n) si"

Rules: https://www.translating-it.eu/en/eifeler-regel-letzebuergesch

Object Formatting

Implement base formatters (used by Context#format/#localize):

  • Strings
    • HTML escaping and interpolation
    • BiDi support
    • as: :calendar
    • as: :collation
    • as: :currency
    • as: :key
    • as: :language
    • as: :measurement_system
    • as: :number
    • as: :numbering_sysmte
    • as: :timezone
    • as: :territory
    • as: :script
    • as: :unit
    • as: :variant
  • Numbers
    • Default Formatting
    • Formatting with decimal pattern
    • Formatting with non-decimal numbering systems
    • Formatting as currency
    • Formatting as unit
    • Formatting as percentage
    • Scientific formatting
    • Short & Long Formatting
    • Currency Spacing
    • Minimum Grouping Digits
    • Misc Patterns
    • Spelling out as word
  • Date formatting
  • Time formatting
  • List formatting (Array & similar)
    • Base Patterns (and/or)
    • Support for complex rules (Hebrew and Spanish, see icu4j)
  • Hash formatting
  • Money formatting (money/shopify-money compatible)
  • Formatting for Nii entities
    • Nii::Calendar
    • Nii::Timezone
    • Nii::Date
    • Nii::Locale
    • Nii::Localized
    • Nii::NumberingSystem
    • Nii::Territory
    • Nii::Timezone
    • Nii::Timezone::Meta

Support for the following gems:

  • TZInfo
  • ActiveSupport
  • nii-units
  • ruby-units (maybe)
  • measured (maybe)

CLI

I've been thinking about adding a CLI.

Features I can envision:

  • Sync messages between two locales (ie, copy all existing message keys with comments from English to another language).
  • Convert a file or directory to Fluent.
  • List translations, find missing translations, etc.
  • Import/Export XLIFF (which would make it easier to have an external agency do the translations). Possibly also to gettext/po, but I don't think that can be done without losing information.

Biggest challenge I see is loading the appropriate configuration (or maybe we don't want to do this, as that might lead down a rabbit whole where we might have to load the entire application).

YARD not happy

YARD doesn't like Ruby 3.0 one line method definitions.
This will impact what is shown on rubydoc.info.

See lsegal/yard#1376

Possible options:

  1. Fix lsegal/yard#1376
  2. Add parens to all method definitions without arguments.

Alternative Ruby Implementations

It would be great to support alternative Ruby implementations. But we're not compatible at the moment.

A couple of modern Ruby features we use:
• Better Unicode support (including relying on Ruby's Unicode normalization). This was introduced in Ruby 2.5, so it should work just fine. This could possibly also be backfilled.
• Pattern matching (experimental support was added in Ruby 2.7, official support in Ruby 3.0)
• Endless method definitions (these could be removed, but only if all other issues are addressed).
• Exception handling without begin (Ruby 2.6, these could also be removed, but only if all other issues are addressed).
• Assumes full separation of keyword and positional arguments (Ruby 2.7).
• Hash#slice (2.5?), Hash#except (3.0)
• Argument forwarding (2.7?), including leading arguments (3.0).
• Hash#transform_keys with hash argument (3.0, could be removed, but only if all other issues are addressed).
• NilClass#=~ (2.6)
• Endless (2.6) and beginless (2.7) range.
• Warning categories (3.0 – limited use, could be made conditional)
• Symbol#name (3.0)
• Numbered parameters (2.7)
• Enumerable#filter_map (2.7 – limited use, could be eliminated).

This list may be incomplete, as I'm only testing against Ruby 3.0.

Current Status

Compatiblity JRuby Truffle Ruby
Ruby 2.5 compatible compatible
Ruby 2.6 jruby/jruby#6161 compatible
Ruby 2.7 jruby/jruby#6464 oracle/truffleruby#2004
Ruby 3.0

nii-slim: Implicit Message translation

To reduce special character usage, it would be nice to have an opt-in mode which will cause nii-slim to attempt to translate any text content, not just the content prefixed with a dollar sign. This would also bring it more in line with what Slim::Translator does.

Database Lookup

Both i18n and fast_gettext implement support for a database backend.
Not sure which version we should target this for.

Ideally this would be independent of the ORM used.

HTTP Backend

It would be nice to support an HTTP lookup, ideally compatible with i18next.

nii-slim: inline translations

It would be nice if inline translations were supported as well:

.example ${first-message} &bull; ${second-message}

Collation

Nii should implement UCA with tailoring (and load rules from CLDR).
This will likely not make it into v0.1.

A secondary goal would be to be faster and more memory efficient than Twitter CLDR.

Specification (UTS 10)

nii-slim: Ability to opt out of automatic formatting

Right now the only way to not trigger automatic formatting is either by explicitly formatting the value (which might still insert BiDI Unicode markers, but that shouldn't be an issue), or by not using nii-slim at all. It would be nice to add a configuration option.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.