AttrEngine.Locale (attr_engine v0.3.0)

Copy Markdown View Source

Multilingual value resolution for attribute data.

AttrEngine stores localized values as JSONB maps keyed by locale:

%{"en" => "Welcome", "el" => "Καλωσήρθατε", "de" => "Willkommen"}

This module resolves those maps to a single value for the target locale, with configurable fallback behaviour.

Modes

  • :fallback (default) — tries target locale, then default locale, then first available
  • :strict — returns :__missing__ if target locale not found (for skip-block behaviour)

Deep resolution

resolve_deep/3 recursively walks JSONB trees, resolving all localized maps at any nesting depth. Correctly skips rich content maps (EditorJS, Lexical) that happen to have locale-like keys.

Usage

data = %{"title" => %{"en" => "Hello", "el" => "Γεια"}, "count" => 42}

AttrEngine.Locale.resolve_deep(data, "el", default_locale: "en")
#=> %{"title" => "Γεια", "count" => 42}

AttrEngine.Locale.resolve_deep(data, "de", default_locale: "en")
#=> %{"title" => "Hello", "count" => 42}

AttrEngine.Locale.resolve_deep(data, "de", mode: :strict)
#=> %{"title" => :__missing__, "count" => 42}

Summary

Functions

Returns true if any value in the context is :__missing__ (strict mode artifact). Used to decide whether to skip rendering a block.

Replaces all :__missing__ atoms with empty strings. For rendering contexts that should show partial content rather than skip.

Resolves a single potentially-localized value for the target locale.

Recursively resolves all localized maps in a JSONB tree.

Simplified deep locale resolution using heuristics.

Types

mode()

@type mode() :: :fallback | :strict

Functions

has_missing?(data)

@spec has_missing?(any()) :: boolean()

Returns true if any value in the context is :__missing__ (strict mode artifact). Used to decide whether to skip rendering a block.

replace_missing(data)

@spec replace_missing(any()) :: any()

Replaces all :__missing__ atoms with empty strings. For rendering contexts that should show partial content rather than skip.

resolve(value, locale, opts \\ [])

@spec resolve(any(), String.t(), keyword()) :: any()

Resolves a single potentially-localized value for the target locale.

Options

  • :mode:fallback (default) or :strict
  • :default_locale — locale to try if target not found (fallback mode)
  • :locales — list of known locale keys, used to identify localized maps

resolve_deep(data, locale, opts \\ [])

@spec resolve_deep(any(), String.t(), keyword()) :: any()

Recursively resolves all localized maps in a JSONB tree.

Walks maps and lists depth-first. Localized maps are resolved to single values. Rich content maps (EditorJS, Lexical) are preserved as-is.

Same options as resolve/3.

resolve_deep_heuristic(data, locale)

@spec resolve_deep_heuristic(any(), String.t()) :: any()

Simplified deep locale resolution using heuristics.

For cases where the known locales list isn't available. Uses is_localized_heuristic?/1 to detect locale maps: map has "en" key, size ≤ 8, all values are strings or nil.