Localized fields helper for Shop module.
All translatable fields are stored as JSONB maps directly in the field:
%Product{
title: %{"en" => "Planter", "ru" => "Кашпо"},
slug: %{"en" => "planter", "ru" => "kashpo"},
description: %{"en" => "Modern pot", "ru" => "Современное кашпо"}
}Fallback Chain
When retrieving a translated field, the fallback chain is:
- Exact language match (e.g., "ru")
- Default language from Languages module
- First available value in the map
Usage Examples
# Get translated field with automatic fallback
Translations.get(product, :title, "ru")
#=> "Кашпо"
Translations.get(product, :title, "fr")
#=> "Planter" (fallback to default or first available)
# Set a single translated field
product = Translations.put(product, :title, "es", "Maceta")
# Build changeset attrs for localized field update
attrs = Translations.changeset_attrs(product, :title, "ru", "Новое кашпо")
#=> %{title: %{"en" => "Planter", "ru" => "Новое кашпо"}}
Summary
Functions
Gets all languages that have a value for a field.
Returns the list of translatable fields for categories.
Builds changeset attrs for localized field update.
Builds changeset attrs for multiple localized fields at once.
Returns the default/master language code.
Returns list of enabled language codes.
Gets a localized value with automatic fallback chain.
Gets all values for a specific language from the entity's localized fields.
DEPRECATED: Use get/3 instead.
Gets the localized slug with fallback.
Checks if translation exists for language in a specific field.
Checks if Languages module is enabled.
Returns the list of translatable fields for products.
Sets a localized value for a language.
Sets multiple translated fields for a language.
DEPRECATED: Use put/4 instead.
Returns translatable fields based on entity type.
DEPRECATED: Use changeset_attrs_multi/3 instead.
Gets translation completeness for a language across all translatable fields.
Functions
Gets all languages that have a value for a field.
Examples
iex> Translations.available_languages(product, :title)
["en", "ru"]
@spec category_fields() :: [atom()]
Returns the list of translatable fields for categories.
Builds changeset attrs for localized field update.
Merges the new value into the existing field map for the given language.
Examples
iex> Translations.changeset_attrs(product, :title, "ru", "Новое кашпо")
%{title: %{"en" => "Planter", "ru" => "Новое кашпо"}}
Builds changeset attrs for multiple localized fields at once.
Examples
iex> Translations.changeset_attrs_multi(product, "ru", %{title: "Кашпо", slug: "kashpo"})
%{title: %{"en" => "Planter", "ru" => "Кашпо"}, slug: %{"en" => "planter", "ru" => "kashpo"}}
@spec default_language() :: String.t()
Returns the default/master language code.
Checks Languages module first, falls back to Settings content language, then defaults to "en".
Examples
iex> Translations.default_language()
"en"
@spec enabled_languages() :: [String.t()]
Returns list of enabled language codes.
When Languages module is enabled, returns all enabled language codes. Otherwise returns only the default language.
Examples
iex> Translations.enabled_languages()
["en", "es", "ru"]
# When Languages module disabled:
iex> Translations.enabled_languages()
["en"]
Gets a localized value with automatic fallback chain.
Fallback order:
- Exact language match
- Default language
- First available value
Parameters
entity- Product or Category structfield- Field atom (e.g., :title, :name, :slug)language- Language code (e.g., "ru", "en")
Examples
iex> product = %Product{title: %{"en" => "Planter", "ru" => "Кашпо"}}
iex> Translations.get(product, :title, "ru")
"Кашпо"
iex> Translations.get(product, :title, "fr")
"Planter" # Falls back to default or first available
Gets all values for a specific language from the entity's localized fields.
Returns a map of field => value for the given language.
Examples
iex> Translations.get_all_for_language(product, "ru", [:title, :slug, :description])
%{title: "Кашпо", slug: "kashpo", description: "Описание"}
DEPRECATED: Use get/3 instead.
This function exists for backward compatibility during migration.
Gets the localized slug with fallback.
Convenience function for URL slug retrieval.
Examples
iex> Translations.get_slug(product, "es")
"maceta-geometrica"
Checks if translation exists for language in a specific field.
Examples
iex> Translations.has_translation?(product, :title, "ru")
true
iex> Translations.has_translation?(product, :title, "zh")
false
@spec languages_enabled?() :: boolean()
Checks if Languages module is enabled.
@spec product_fields() :: [atom()]
Returns the list of translatable fields for products.
Sets a localized value for a language.
Returns the updated entity struct (not persisted to database).
Examples
iex> product = Translations.put(product, :title, "ru", "Новое кашпо")
%Product{title: %{"en" => "Planter", "ru" => "Новое кашпо"}}
Sets multiple translated fields for a language.
Returns the updated entity struct (not persisted to database).
Examples
iex> product = Translations.put_all(product, "es", %{title: "Maceta", slug: "maceta"})
%Product{title: %{"en" => "Planter", "es" => "Maceta"}, ...}
DEPRECATED: Use put/4 instead.
This function exists for backward compatibility during migration.
Returns translatable fields based on entity type.
DEPRECATED: Use changeset_attrs_multi/3 instead.
Builds changeset attrs for updating translations. This function adapts the old API to the new localized fields approach.
Gets translation completeness for a language across all translatable fields.
Examples
iex> Translations.translation_status(product, "ru")
%{complete: 4, total: 6, percentage: 67, missing: [:body_html, :seo_description]}