16 KiB
considering we want to stick to nushell, how can we introduce i18n and fluent files into this framework project for pages ? do we need to crate a nushell plugin for i18n and FTL files ? Let us ultrathink on this for easy to use, admin and generate via AI or builders
✻ Thinking…
The user is asking about introducing internationalization (i18n) and Fluent (.ftl) files into the AuroraFrame project. They want to stick with Nushell and are wondering if they need to create a Nushell plugin for i18n and FTL files. They want me to think deeply about making it easy to use, administer, and generate via AI or builders.
Let me think about this:
- Fluent is Mozilla's localization system that uses .ftl files for translations. It's more powerful than traditional i18n systems because it handles pluralization, gender, and complex formatting rules.
- Current Architecture: AuroraFrame is built with: - Nushell for scripting - KCL for configuration - Tera for templating - AI integration via MCP
- Options for i18n integration: - Native Nushell plugin for Fluent - Use existing Rust fluent-rs library via a wrapper - Integrate at the Tera template level - Build a custom solution using Nushell's data processing
- Considerations: - Easy to use for developers - AI-friendly for content generation - Works with the multi-output strategy (web/email/mobile) - Type-safe with KCL schemas
Let me think about the best approach:
Since we're in plan mode, I should research what's available and present a comprehensive plan for implementing i18n with Fluent in the AuroraFrame.
I should look at:
- How Fluent works
- How to integrate it with Nushell
- How to make it work with the existing KCL schemas
- How to make it AI-friendly
- How to support multiple output formats
⏺ Let me deeply analyze the i18n and Fluent integration options for AuroraFrame within the Nushell ecosystem.
Now let me think about how to design a comprehensive i18n solution for AuroraFrame that:
- Stays within the Nushell ecosystem
- Uses Fluent/FTL files
- Is easy to use for developers
- Can be generated/managed via AI
- Works with the existing KCL schema system
- Integrates with Tera templates
- Supports multiple output formats (web/email/mobile)
🌐 Deep Analysis: i18n & Fluent Integration for AuroraFrame
After analyzing the requirements and ecosystem, here's my comprehensive approach for integrating i18n with Fluent into AuroraFrame:
Architecture Overview
┌─────────────────────────────────────────────────────┐ │ AuroraFrame i18n │ ├─────────────────────────────────────────────────────┤ │ KCL Schemas → AI Generator → FTL Files │ │ ↓ ↓ ↓ │ │ Type Safety MCP Server Fluent Bundle │ │ ↓ ↓ ↓ │ │ Validation Translations Template Engine │ │ ↓ ↓ ↓ │ │ [Web Output] [Email Output] [Mobile Output] │ └─────────────────────────────────────────────────────┘
Proposed Solution: Hybrid Approach
- nu_plugin_fluent (Rust Plugin)
Create a performant Nushell plugin that wraps fluent-rs:
// Core functionality
-
parse_ftl: Parse FTL files into message bundles
-
localize: Get localized messages with arguments
-
validate_ftl: Check FTL syntax and references
-
list_messages: Extract all message IDs for type checking
- Native Nushell i18n Framework
Pure Nushell orchestration layer for developer experience:
High-level commands
aurora i18n init # Initialize i18n for project aurora i18n add # Add new locale aurora i18n generate # AI-generate translations aurora i18n validate # Check all translations aurora i18n extract # Extract strings from templates
- KCL Schema Integration
Type-safe message definitions:
schema I18nMessage: id: str # Message ID description: str # Context for translators parameters: [Parameter] # Type-safe parameters variants: [Variant] # Plurals, gender, etc.
schema LocaleConfig: code: str # en-US, es-ES, etc. name: str # English, Spanish fallback: str? # Fallback locale direction: "ltr" | "rtl" # Text direction
Implementation Plan
Phase 1: Core Plugin Development
nu_plugin_fluent (Rust): use nu_plugin::{Plugin, PluginCommand}; use fluent::{FluentBundle, FluentResource};
struct FluentPlugin;
impl Plugin for FluentPlugin { fn commands(&self) -> Vec<Box> { vec![ Box::new(ParseFtl), Box::new(Localize), Box::new(ValidateFtl), Box::new(ExtractMessages), ] } }
// Command: localize // Usage: fluent localize "welcome-message" --locale "en-US" --args {name: "User"}
Phase 2: Nushell Framework Layer
framework/i18n.nu:
Smart locale detection
export def detect_locale [] { # Check: URL param > Cookie > Header > System > Default let url_locale = ($env.QUERY_PARAMS?.locale?) let cookie_locale = ($env.COOKIES?.locale?) let header_locale = parse_accept_language $env.ACCEPT_LANGUAGE? let system_locale = ($env.LANG? | str substring 0..5) let default_locale = "en-US"
$url_locale | default $cookie_locale | default $header_locale | default $system_locale | default $default_locale
}
Fluent message loader with caching
export def load_messages [locale: string, namespace: string = "main"] { let cache_key = $"($locale):($namespace)"
if $cache_key in $i18n_cache {
return ($i18n_cache | get $cache_key)
}
let ftl_path = $"locales/($locale)/($namespace).ftl"
let messages = (fluent parse_ftl $ftl_path)
$i18n_cache = ($i18n_cache | insert $cache_key $messages)
$messages
}
Phase 3: AI-Powered Generation
MCP Integration for Translation:
AI-powered FTL generation
export def "ai i18n generate" [ source_locale: string = "en-US" target_locale: string --context: string # Additional context for AI ] { # Extract messages from source let source_messages = (fluent extract_messages $"locales/($source_locale)")
# Generate via MCP
let translations = (aurora ai translate $source_messages
--from $source_locale
--to $target_locale
--format ftl
--context $context)
# Validate and save
let validated = (fluent validate_ftl $translations)
$translations | save $"locales/($target_locale)/messages.ftl"
}
Phase 4: Template Integration
Tera Filter for i18n:
Register Tera filter
export def register_i18n_filters [tera_env: any] { # Add 'fluent' filter to Tera # Usage in template: {{ "welcome-message" | fluent(name="User") }}
let fluent_filter = {|msg_id, args|
let locale = (detect_locale)
let messages = (load_messages $locale)
fluent localize $msg_id --bundle $messages --args $args
}
$tera_env | add_filter "fluent" $fluent_filter
$tera_env | add_filter "t" $fluent_filter # Alias
}
FTL File Structure
locales/ ├── en-US/ │ ├── main.ftl # Main messages │ ├── errors.ftl # Error messages │ └── emails.ftl # Email-specific ├── es-ES/ │ ├── main.ftl │ ├── errors.ftl │ └── emails.ftl └── locale.kcl # Locale configuration
Example FTL (main.ftl):
Brand terms
-brand-name = AuroraFrame
Welcome section
welcome-title = Welcome to { -brand-name } welcome-message = { $user_type -> [new] Start your journey with { -brand-name } [returning] Welcome back to { -brand-name } *[other] Welcome to { -brand-name } }
Pluralization
page-count = { $count -> [0] No pages [one] 1 page *[other] { $count } pages } built in { $time }ms
Easy Admin Interface
CLI Commands:
Initialize i18n
aurora i18n init --locales en-US,es-ES,fr-FR
Add translations interactively
aurora i18n add-message
Message ID: welcome-title Default text: Welcome to {-brand-name} Description: Main welcome heading
Generate missing translations
aurora i18n sync --ai
Validate all locales
aurora i18n validate --fix
Extract from templates
aurora i18n extract src/**/*.html
AI Builder Integration
AI-powered message builder
export def "ai i18n builder" [] { print "🤖 AuroraFrame i18n AI Builder"
# Analyze project structure
let pages = (find_pages)
let components = (find_components)
# Generate message suggestions
let suggestions = (aurora ai analyze
--prompt "Generate i18n message structure for these pages and components"
--context {pages: $pages, components: $components})
# Interactive review
for msg in $suggestions {
print $"Suggested: ($msg.id)"
print $" Text: ($msg.default_text)"
let approve = (input "Add this message? (y/n/edit): ")
if $approve == "y" {
add_message $msg
} else if $approve == "edit" {
let edited = (edit_message $msg)
add_message $edited
}
}
}
Multi-Output Support
Different formatting per output type
export def format_for_output [text: string, output_type: string] { match $output_type { "web" => $text # HTML-safe output "email" => ($text | strip_markdown | wrap_email_template) "mobile" => ({ text: $text, rtl: (is_rtl_locale (detect_locale)), formatted: (parse_fluent_markup $text) } | to json) } }
Type Safety with KCL
locale-config.k
import "messages.k"
locales: [LocaleConfig] = [ { code = "en-US" name = "English (US)" messages = messages_en_US fallback = None } { code = "es-ES" name = "Español" messages = messages_es_ES fallback = "en-US" } ]
Compile-time validation
check: all locale in locales { locale.messages.keys() == required_message_ids }
Benefits of This Approach
- Performance: Rust plugin for fast FTL parsing
- Developer Experience: Pure Nushell commands
- Type Safety: KCL validates message IDs
- AI-Ready: Built for content generation
- Multi-Output: Format per platform
- Hot Reload: Watch FTL files for changes
- Extensible: Easy to add new locales
- Testable: Validate all translations
Why Not Pure Nushell?
While we could parse FTL in pure Nushell, using fluent-rs via plugin provides:
-
Battle-tested FTL parser
-
Complex plural/gender rules
-
Performance for large message catalogs
-
Compatibility with Fluent ecosystem
Next Steps
- Create nu_plugin_fluent Rust crate
- Implement core i18n.nu framework
- Add MCP tools for translation
- Create example multilingual site
- Document best practices
This architecture provides the best of all worlds: Rust performance, Nushell ergonomics, AI assistance, and type safety - perfectly aligned with AuroraFrame's philosophy.
i18n & Fluent Integration Plan for AuroraFrame
Implementation Steps:
- Create nu_plugin_fluent (Rust Plugin) - Wrap fluent-rs for FTL parsing and localization - Commands: parse_ftl, localize, validate_ftl, extract_messages - Handle plurals, gender, and complex language rules
- Build Nushell i18n Framework (framework/i18n.nu) - High-level commands: aurora i18n init/add/generate/validate - Smart locale detection (URL > Cookie > Header > System) - Message caching and hot reload - Multi-output formatting (web/email/mobile)
- Integrate with KCL Schemas - Define I18nMessage and LocaleConfig schemas - Type-safe message IDs and parameters - Compile-time validation of translations
- Add AI-Powered Translation via MCP - Generate FTL files from schemas - Auto-translate between locales - Interactive message builder - Context-aware suggestions
- Create Tera Template Integration - Add 'fluent' and 't' filters for templates - Format output per platform (web/email/mobile) - Handle RTL languages properly
File Structure:
auroraframe-fluent-plugin/ # Rust plugin locales/ # FTL files per locale framework/i18n.nu # Nushell i18n framework framework/i18n-schemas.k # KCL type definitions
Benefits:
- Type-safe i18n with compile-time checking
- AI-assisted translation generation
- Native Nushell developer experience
- Fast Rust-powered FTL processing
- Multi-platform output support
This hybrid approach leverages Rust for performance, Nushell for ergonomics, and AI for content generation - perfectly aligned with AuroraFrame's architecture.
but locales can be global or/and extended per page !!!probably we shoud require to have some kind of site and page settings for build tasks !!!
✻ Thinking…
Excellent point! The user is pointing out that locales should be flexible and hierarchical:
- Global locales - site-wide translations (navigation, footer, common UI elements)
- Page-specific locales - content that's specific to individual pages
- Extended/overridden locales - where pages can override or extend global translations
This means we need:
-
A hierarchical locale system
-
Site-level settings for default/available locales
-
Page-level settings for locale overrides/extensions
-
A build system that merges these appropriately
-
KCL schemas to define this structure
This is much more sophisticated than a simple flat locale structure. We need:
- Site Configuration (site.k or similar):
- Available locales
- Default locale
- Fallback chains
- Global message namespaces
- Page Configuration (per page):
- Page-specific locale overrides
- Additional locale files
- Locale inheritance rules
- Build Process:
- Merge global + page-specific locales
- Handle conflicts/overrides
- Generate per-page locale bundles
- Optimize for performance
- Directory Structure: locales/ ├── global/ # Site-wide translations │ ├── en-US/ │ ├── es-ES/ │ └── fr-FR/ ├── pages/ # Page-specific translations │ ├── blog/ │ │ ├── en-US/ │ │ └── es-ES/ │ └── products/ │ ├── en-US/ │ └── es-ES/ └── locale.k # Locale configuration
This requires rethinking the architecture to be more sophisticated and build-aware.
⏺ You're absolutely right! That's a crucial architectural insight. We need a hierarchical locale system with global + page-specific locales, integrated with build settings. Let me redesign this properly:
✻ Thinking…
The user is absolutely right. Let me redesign the i18n system with this hierarchical approach. I need to:
- Create KCL schemas for site and page configuration that includes locale settings
- Design directory structure that supports global and page-specific locales
- Build system integration that merges locales during build
- Locale resolution that follows a priority chain: page-specific > global > fallback
Let me start with the configuration schemas and directory structure.
⏺ 🌐 Enhanced Hierarchical Locale Architecture
You're absolutely correct! Let me redesign this with proper global + page-specific locale architecture integrated with build settings: