PhoenixKit.Modules.Shop.Translations (phoenix_kit v1.7.33)

Copy Markdown View Source

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:

  1. Exact language match (e.g., "ru")
  2. Default language from Languages module
  3. 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.

Returns translatable fields based on entity type.

Gets translation completeness for a language across all translatable fields.

Functions

available_languages(entity, field)

@spec available_languages(
  struct(),
  atom()
) :: [String.t()]

Gets all languages that have a value for a field.

Examples

iex> Translations.available_languages(product, :title)
["en", "ru"]

category_fields()

@spec category_fields() :: [atom()]

Returns the list of translatable fields for categories.

changeset_attrs(entity, field, language, value)

@spec changeset_attrs(struct(), atom(), String.t(), any()) :: map()

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" => "Новое кашпо"}}

changeset_attrs_multi(entity, language, field_values)

@spec changeset_attrs_multi(struct(), String.t(), map()) :: map()

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"}}

default_language()

@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"

enabled_languages()

@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"]

get(entity, field, language)

@spec get(struct(), atom(), String.t()) :: any()

Gets a localized value with automatic fallback chain.

Fallback order:

  1. Exact language match
  2. Default language
  3. First available value

Parameters

  • entity - Product or Category struct
  • field - 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

get_all_for_language(entity, language, fields)

@spec get_all_for_language(struct(), String.t(), [atom()]) :: map()

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: "Описание"}

get_field(entity, field, language)

@spec get_field(struct(), atom(), String.t()) :: any()

DEPRECATED: Use get/3 instead.

This function exists for backward compatibility during migration.

get_slug(entity, language)

@spec get_slug(
  struct(),
  String.t()
) :: String.t() | nil

Gets the localized slug with fallback.

Convenience function for URL slug retrieval.

Examples

iex> Translations.get_slug(product, "es")
"maceta-geometrica"

has_translation?(entity, field, language)

@spec has_translation?(struct(), atom(), String.t()) :: boolean()

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

languages_enabled?()

@spec languages_enabled?() :: boolean()

Checks if Languages module is enabled.

product_fields()

@spec product_fields() :: [atom()]

Returns the list of translatable fields for products.

put(entity, field, language, value)

@spec put(struct(), atom(), String.t(), any()) :: struct()

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" => "Новое кашпо"}}

put_all(entity, language, field_values)

@spec put_all(struct(), String.t(), map()) :: struct()

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"}, ...}

put_field(entity, field, language, value)

@spec put_field(struct(), atom(), String.t(), any()) :: struct()

DEPRECATED: Use put/4 instead.

This function exists for backward compatibility during migration.

translatable_fields(arg1)

@spec translatable_fields(struct()) :: [atom()]

Returns translatable fields based on entity type.

translation_changeset_attrs(current_translations, language, params)

@spec translation_changeset_attrs(map() | nil, String.t(), map()) :: map()

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.

translation_status(entity, language, required_fields \\ nil)

@spec translation_status(struct(), String.t(), [atom()] | nil) :: map()

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]}