Packages

phoenix_kit

1.7.86
1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules languages README.md
Raw

lib/modules/languages/README.md

# Languages Module
The PhoenixKit Languages module provides multi-language support with a two-tier locale system (base codes for URLs, full dialects for translations). It manages both frontend user-facing languages and backend admin panel languages.
## Quick Links
- **Admin Interface**: `/{prefix}/admin/settings/languages`
- **Enable Module**: `PhoenixKit.Modules.Languages.enable_system/0`
- **Check Status**: `PhoenixKit.Modules.Languages.enabled?/0`
- **Get Primary Language**: `PhoenixKit.Modules.Languages.get_default_language/0`
- **Get All Languages**: `PhoenixKit.Modules.Languages.get_display_languages/0`
## Storage Details
**Important**: Language configuration is stored in the `phoenix_kit_settings` table using the `value_json` column (not `value`).
| Setting Key | Column | Description |
|-------------|--------|-------------|
| `languages_enabled` | `value` | Boolean flag (`true`/`false`) |
| `languages_config` | `value_json` | JSON with `{"languages": [...]}` structure |
| `admin_languages` | `value` | JSON array of admin language codes |
### Querying Configuration
**From within the application** (recommended):
```elixir
# Get all configured languages
PhoenixKit.Modules.Languages.get_display_languages()
# Get the default/primary language
PhoenixKit.Modules.Languages.get_default_language()
# => %{"code" => "en", "name" => "English", "is_default" => true, "is_enabled" => true}
# Get the primary language code for Publishing module
PhoenixKit.Settings.get_content_language()
# => "en"
# Check if module is enabled
PhoenixKit.Modules.Languages.enabled?()
# => true
```
**Direct database query** (for debugging):
```sql
-- Check if enabled
SELECT value FROM phoenix_kit_settings WHERE key = 'languages_enabled';
-- Get full configuration (note: value_json, not value)
SELECT value_json FROM phoenix_kit_settings WHERE key = 'languages_config';
-- Get admin languages
SELECT value FROM phoenix_kit_settings WHERE key = 'admin_languages';
```
## Language Configuration Structure
Each language in `languages_config` has this structure:
```json
{
"languages": [
{
"code": "en",
"name": "English",
"is_default": true,
"is_enabled": true,
"position": 0
},
{
"code": "sq",
"name": "Albanian",
"is_default": false,
"is_enabled": true,
"position": 1
}
]
}
```
## Two-Tier Locale System
The module uses two types of language codes:
| Type | Example | Used For |
|------|---------|----------|
| **Base codes** | `en`, `es`, `fr` | URLs (SEO-friendly) |
| **Full dialect codes** | `en-US`, `es-ES`, `fr-FR` | Gettext translations |
### Default Dialect Mapping
| Base | Default Dialect |
|------|-----------------|
| `en` | `en-US` |
| `es` | `es-ES` |
| `pt` | `pt-BR` |
| `zh` | `zh-CN` |
| `de` | `de-DE` |
| `fr` | `fr-FR` |
### DialectMapper Functions
```elixir
alias PhoenixKit.Modules.Languages.DialectMapper
DialectMapper.extract_base("en-US") # => "en"
DialectMapper.base_to_dialect("en") # => "en-US"
DialectMapper.resolve_dialect("en", user) # Considers user.custom_fields["preferred_locale"]
```
## Frontend vs Backend Languages
| Setting | Purpose | Storage Key |
|---------|---------|-------------|
| **Frontend Languages** | User-facing language switcher | `languages_config` |
| **Backend Languages** | Admin panel language switcher | `admin_languages` |
These are **independent** - admins can use different languages than site visitors.
### Admin Languages
```elixir
# Get admin languages (returns list of base codes)
PhoenixKit.Settings.get_setting_cached("admin_languages", nil)
# => "[\"en-US\",\"ja\"]"
```
## Key API Functions
### System Management
```elixir
Languages.enable_system() # Enable with default English
Languages.disable_system() # Disable (preserves config)
Languages.enabled?() # Check if enabled
```
### Query Functions
```elixir
Languages.get_languages() # All configured languages
Languages.get_enabled_languages() # Only enabled, sorted by position
Languages.get_default_language() # Language with is_default: true
Languages.get_display_languages() # Configured (if enabled) or top 12 defaults
Languages.get_language("es-ES") # Specific language by code
Languages.enabled_locale_codes() # For URL routing
```
### Management Functions
```elixir
Languages.add_language("es-ES") # Add from predefined list
Languages.remove_language("es-ES") # Remove (not if default or last)
Languages.set_default_language("es-ES") # Change default
Languages.enable_language("fr-FR") # Reactivate disabled
Languages.disable_language("de-DE") # Hide from frontend
Languages.move_language_up("es-ES") # Reorder
Languages.move_language_down("es-ES") # Reorder
```
## Language Switcher Components
```heex
<%!-- Dropdown (recommended) --%>
<.language_switcher_dropdown current_locale={@current_locale} />
<%!-- Button group --%>
<.language_switcher_buttons current_locale={@current_locale} />
<%!-- Inline text --%>
<.language_switcher_inline current_locale={@current_locale} />
```
## Integration with Entities Module
The Entities module uses Languages for **multi-language content storage**. When 2+ languages are enabled, all entity data automatically supports multilang.
### How It Works
1. `PhoenixKit.Utils.Multilang.enabled?/0` checks if Languages has 2+ enabled languages
2. `Multilang.primary_language/0` reads `Languages.get_default_language()`
3. `Multilang.enabled_languages/0` reads `Languages.get_enabled_language_codes()`
4. Entity data JSONB is structured by language code (e.g., `"en-US"`, `"es-ES"`)
### Programmatic Translation Setup
```elixir
# 1. Enable languages
PhoenixKit.Modules.Languages.enable_system()
PhoenixKit.Modules.Languages.add_language("es-ES")
PhoenixKit.Modules.Languages.add_language("fr-FR")
# 2. Multilang is now active — use the convenience API
alias PhoenixKitEntities.EntityData
record = EntityData.get(uuid)
EntityData.set_translation(record, "es-ES", %{"name" => "Producto"})
EntityData.set_title_translation(record, "es-ES", "Mi Producto")
```
### Primary Language Changes
When `Languages.set_default_language/1` is called, existing entity data records lazily re-key on next edit. The new primary is promoted to have all fields. See `lib/modules/entities/OVERVIEW.md` for full details.
### Key Dependency
The Entities Multilang module gracefully degrades when Languages is unavailable — it uses `Code.ensure_loaded?/1` checks and falls back to `"en-US"` as the default language.
---
## Integration with Publishing Module
The Publishing module uses Languages for:
1. **Primary Language**: `PhoenixKit.Settings.get_content_language()` returns the default language code
2. **Multi-language URLs**: `/en/blog/post` vs `/es/blog/post`
3. **Per-post primary_language**: Stored in `.phk` file metadata
4. **Language detection**: Determines if URL segment is language or blog slug
## Troubleshooting
### Languages show empty in database but work in app
The configuration is stored in `value_json` column, not `value`. Query with:
```sql
SELECT value_json FROM phoenix_kit_settings WHERE key = 'languages_config';
```
Or use the application API:
```elixir
PhoenixKit.Modules.Languages.get_display_languages()
```
### Module enabled but no languages showing
Check if `languages_config` has the `{"languages": [...]}` structure:
```elixir
PhoenixKit.Settings.get_json_setting("languages_config", nil)
```
### Primary language returns nil
The primary language comes from `Languages.get_default_language()`. Ensure at least one language has `"is_default": true` in the config.