Skip to content

Localize version 0.50.0

Choose a tag to compare

@kipcole9 kipcole9 released this 22 Jul 09:47
· 327 commits to main since this release

[0.50.0] — July 15th, 2026

Added

  • Localize.LanguageTag.remove_likely_subtags/2 and !/2 accept favor: :script | :region to select the TR35 removal variant (zh-Hant-TW minimizes to "zh-Hant" or "zh-TW"), verified against the full CLDR likely-subtags test data.

  • The MessageFormat working group's :test:function, :test:format and :test:select registry functions are implemented, so the WG conformance suite's selection-mechanics and fallback cases now run.

  • The MF2 numeric functions accept the signDisplay option (auto, always, exceptZero, negative, never), with the plus sign taken from the locale's number symbols.

  • An MF2 pattern expression that re-annotates a declared variable operates on the declaration's original value, and numeric functions inherit unset options from a numeric declaration — .local $x = {41 :integer signDisplay=always} rendered with {$x :offset add=1} produces "+42".

  • The locale download base URL can be overridden with config :localize, locale_base_url: "..." for deployments mirroring the locale files; downloads are verified against the bundled hash manifest regardless of source.

Changed

  • An unannotated MF2 placeholder with a numeric operand formats with the locale-aware :number default ({$pi} renders "3.142" in en and "3,142" in fr), matching the MF2 implicit formatting rules; previously the value was stringified verbatim.

  • MessageFormat 2 follows the specification's error semantics: unknown functions are an error (Localize.FormatError reason :unknown_function) instead of formatting the operand, and data-model validation rejects duplicate declarations, duplicate option names, and duplicate variants (NFC-normalized keys) with dedicated error reasons.

  • MessageFormat 2 function validation is strict per TR35: the select option must be a literal set directly on the selector expression, digit-size options must be non-negative integers, string operands of numeric functions must match the number-literal production, and :currency, :unit, :date, :time and :datetime are rejected as selectors.

  • Localize.Number.Format.Options is documented again: validate_options/2 is the supported way to pre-resolve formatting options for hot loops (as the Performance guide describes), so the module is part of the public API.

  • The TR35 conformance guide documents the MessageFormat 2 working-group suite exclusions precisely: unknown-function fallback, duplicate declaration/option validation, select and digit-size option validation, u:dir/u:id expression options, and the :isolate bidi strategy deviation.

Deprecated

  • Localize.Currency.currencies_for_locale/2,3, currencies_for_locale!/2,3, currency_strings/2,3 and currency_strings!/2,3 take the include/exclude filters as :only and :except options instead of positional arguments. The positional forms still work but are deprecated and will be removed by Localize 1.0 and no later than December 2026.

Fixed

  • Calendar- and provider-module probes in date/datetime formatting (era year, day of era, ISO week and day of year, day of week, CLDR calendar type) and Localize.Locale.Provider.allow_download?/1 ensure the module is loaded before function_exported?/3, so a cold module no longer silently takes the gregorian or default fallback branch.

Security

  • Localize.Locale.Provider.locale_file_name/1 rejects locale identifiers that do not have the shape of a CLDR locale id, as defense in depth for the cache-path and download-URL interpolations.