Jesús Pérez d9ef2f0d5b
Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
Nightly Build / Check for Changes (push) Has been cancelled
Nightly Build / Validate Setup (push) Has been cancelled
Nightly Build / Nightly Build (darwin-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (darwin-arm64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (windows-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-arm64) (push) Has been cancelled
Nightly Build / Create Nightly Pre-release (push) Has been cancelled
Nightly Build / Notify Build Status (push) Has been cancelled
Nightly Build / Nightly Maintenance (push) Has been cancelled
chore: update all plugins to Nushell 0.111.0
- Bump all 18 plugins from 0.110.0 to 0.111.0
  - Update rust-toolchain.toml channel to 1.93.1 (nu 0.111.0 requires ≥1.91.1)

  Fixes:
  - interprocess pin =2.2.x → ^2.3.1 in nu_plugin_mcp, nu_plugin_nats, nu_plugin_typedialog
    (required by nu-plugin-core 0.111.0)
  - nu_plugin_typedialog: BackendType::Web initializer — add open_browser: false field
  - nu_plugin_auth: implement missing user_info_to_value helper referenced in tests

  Scripts:
  - update_all_plugins.nu: fix [package].version update on minor bumps; add [dev-dependencies]
    pass; add nu-plugin-test-support to managed crates
  - download_nushell.nu: rustup override unset before rm -rf on nushell dir replace;
    fix unclosed ) in string interpolation
2026-03-11 03:22:42 +00:00

10 KiB

nu_plugin_fluent\n\nA Nushell plugin for Fluent internationalization (i18n) and localization (l10n) workflows.\n\n## Overview\n\nThis plugin provides powerful tools for managing multilingual applications using Mozilla's Fluent localization system. It enables you to parse, validate, localize, and manage Fluent Translation List (.ftl) files directly from Nushell.\n\n## Installing\n\nClone this repository\n\n> [!WARNING]\n> nu_plugin_fluent has dependencies to nushell source via local path in Cargo.toml\n> Nushell and plugins require to be sync with same version\n\nClone Nushell alongside this plugin or change dependencies in Cargo.toml\n\nThis plugin is also included as submodule in nushell-plugins\nas part of plugins collection for Provisioning project\n\nBuild from source\n\nnushell\n> cd nu_plugin_fluent\n> cargo install --path .\n\n\n### Nushell\n\nIn a Nushell\n\nnushell\n> plugin add ~/.cargo/bin/nu_plugin_fluent\n\n\n## Commands\n\n### fluent-parse\n\nParse a Fluent Translation List (.ftl) file and extract its message structure.\n\nnushell\n> fluent-parse <file>\n\n\nParameters:\n\n- file <path>: FTL file to parse\n\nExample:\n\nnushell\n> fluent-parse locales/en-US/main.ftl\n╭───────────────┬─────────────────────────────╮\n│ file │ locales/en-US/main.ftl │\n│ message_count │ 3 │\n│ messages │ [list of parsed messages] │\n╰───────────────┴─────────────────────────────╯\n\n\n### fluent-localize\n\nLocalize a message using the Fluent translation system with hierarchical fallback support.\n\nnushell\n> fluent-localize <message_id> <locale> [--files] [--bundle] [--args] [--fallback]\n\n\nParameters:\n\n- message_id <string>: Message ID to localize\n- locale <string>: Locale code (e.g., en-US, es-ES)\n\nFlags:\n\n- --files -f <list>: FTL files to load\n- --bundle -b <record>: Pre-loaded message bundle\n- --args -a <record>: Arguments for message interpolation\n- --fallback -F: Return message ID if translation not found\n\nExamples:\n\nBasic localization:\n\nnushell\n> fluent-localize welcome-message en-US --files [locales/en-US/main.ftl]\n"Welcome to our application!"\n\n\nWith arguments:\n\nnushell\n> fluent-localize user-greeting en-US --files [locales/en-US/main.ftl] --args {name: "Alice"}\n"Hello, Alice! Welcome back."\n\n\nWith fallback:\n\nnushell\n> fluent-localize missing-message es-ES --files [locales/es-ES/main.ftl] --fallback\n"[[missing-message]]"\n\n\n### fluent-validate\n\nValidate the syntax of a Fluent Translation List (.ftl) file.\n\nnushell\n> fluent-validate <file>\n\n\nParameters:\n\n- file <path>: FTL file to validate\n\nExample:\n\nnushell\n> fluent-validate locales/en-US/main.ftl\n╭────────┬─────────────────────────╮\n│ valid │ true │\n│ file │ locales/en-US/main.ftl │\n│ errors │ [] │\n╰────────┴─────────────────────────╯\n\n\n### fluent-extract\n\nExtract message IDs from a Fluent Translation List (.ftl) file.\n\nnushell\n> fluent-extract <file>\n\n\nParameters:\n\n- file <path>: FTL file to extract messages from\n\nExample:\n\nnushell\n> fluent-extract locales/en-US/main.ftl\n╭───┬─────────────────╮\n│ 0 │ welcome-message │\n│ 1 │ user-greeting │\n│ 2 │ goodbye-message │\n╰───┴─────────────────╯\n\n\n### fluent-list-locales\n\nList available locales from a directory structure.\n\nnushell\n> fluent-list-locales <directory>\n\n\nParameters:\n\n- directory <path>: Directory containing locale folders\n\nExample:\n\nnushell\n> fluent-list-locales ./locales\n╭───┬───────╮\n│ 0 │ en-US │\n│ 1 │ es-ES │\n│ 2 │ fr-FR │\n│ 3 │ de-DE │\n╰───┴───────╯\n\n\n### fluent-create-bundle\n\nCreate a merged Fluent bundle from global and page-specific locale files.\n\nnushell\n> fluent-create-bundle <locale> [--global] [--page] [--fallback] [--override]\n\n\nParameters:\n\n- locale <string>: Locale code (e.g., en-US)\n\nFlags:\n\n- --global -g <list>: Global FTL files to include\n- --page -p <list>: Page-specific FTL files to include\n- --fallback -f <list>: Fallback locales in order\n- --override -o: Allow page files to override global messages\n\nExamples:\n\nCreate bundle with global and page-specific files:\n\nnushell\n> fluent-create-bundle en-US --global [global/en-US/common.ftl] --page [pages/blog/en-US/blog.ftl]\n\n\nCreate bundle with fallback support:\n\nnushell\n> fluent-create-bundle es-ES --fallback [en-US] --global [global/es-ES/common.ftl]\n\n\n## Workflow Examples\n\n### Complete Localization Workflow\n\n1. Set up your locale directory structure:\n\nplaintext\nlocales/\n├── en-US/\n│ ├── common.ftl\n│ └── pages.ftl\n├── es-ES/\n│ ├── common.ftl\n│ └── pages.ftl\n└── fr-FR/\n ├── common.ftl\n └── pages.ftl\n\n\n1. List available locales:\n\nnushell\n> fluent-list-locales ./locales\n\n\n1. Validate all locale files:\n\nnushell\n> ls locales/**/*.ftl | each { |file| fluent-validate $file.name }\n\n\n1. Extract all message IDs for translation coverage:\n\nnushell\n> ls locales/en-US/*.ftl | each { |file|\n fluent-extract $file.name | wrap messages | insert file $file.name\n} | flatten\n\n\n1. Create a localization function:\n\nnushell\ndef localize [message_id: string, locale: string = "en-US"] {\n let files = (ls $"locales/($locale)/*.ftl" | get name)\n fluent-localize $message_id $locale --files $files --fallback\n}\n\n\n1. Use the localization function:\n\nnushell\n> localize "welcome-message" "es-ES"\n"¡Bienvenido a nuestra aplicación!"\n\n\n### Quality Assurance Workflow\n\nCheck for missing translations across locales:\n\nnushell\ndef check-translation-coverage [] {\n let base_locale = "en-US"\n let base_messages = (ls $"locales/($base_locale)/*.ftl"\n | each { |file| fluent-extract $file.name }\n | flatten | uniq)\n\n ls locales/*/\n | get name\n | path basename\n | where $it != $base_locale\n | each { |locale|\n let locale_messages = (ls $"locales/($locale)/*.ftl"\n | each { |file| fluent-extract $file.name }\n | flatten | uniq)\n\n let missing = ($base_messages | where $it not-in $locale_messages)\n {locale: $locale, missing_count: ($missing | length), missing: $missing}\n }\n}\n\n> check-translation-coverage\n\n\n## Fluent File Format\n\nExample .ftl file structure:\n\nlocales/en-US/common.ftl\n\nfluent\n# Simple message\nwelcome-message = Welcome to our application!\n\n# Message with variables\nuser-greeting = Hello, { $name }! Welcome back.\n\n# Message with attributes\nlogin-button =\n .label = Sign In\n .aria-label = Sign in to your account\n .tooltip = Click here to access your account\n\n# Message with variants\nunread-emails = You have { $count ->\n [one] one unread email\n *[other] { $count } unread emails\n}.\n\n# Message with functions\nlast-login = Last login: { DATETIME($date, month: "long", day: "numeric") }\n\n\n## Features\n\n- Parse FTL files - Extract and analyze message structure\n- Validate syntax - Ensure FTL files are syntactically correct\n- Localize messages - Translate messages with variable interpolation\n- Fallback support - Hierarchical locale fallback system\n- Bundle management - Merge global and page-specific translations\n- Message extraction - List all message IDs for coverage analysis\n- Locale discovery - Auto-detect available locales\n- Quality assurance - Tools for translation completeness checking\n\n## Use Cases\n\n- Web Applications: Manage frontend translations with dynamic content\n- CLI Tools: Internationalize command-line applications\n- Documentation: Maintain multilingual documentation systems\n- Content Management: Handle localized content workflows\n- Quality Assurance: Automate translation coverage and validation\n- Build Systems: Integrate i18n validation into CI/CD pipelines\n\n## Integration with Nushell\n\nThis plugin leverages Nushell's powerful data processing capabilities:\n\nnushell\n# Batch validate all locale files\nls locales/**/*.ftl\n| par-each { |file| fluent-validate $file.name }\n| where valid == false\n\n# Generate translation progress report\ndef translation-report [] {\n fluent-list-locales ./locales\n | each { |locale|\n let files = (ls $"locales/($locale)/*.ftl" | get name)\n let message_count = ($files | each { |f| fluent-extract $f } | flatten | length)\n {locale: $locale, messages: $message_count}\n }\n}\n\n# Find untranslated messages\ndef find-missing-translations [base_locale: string, target_locale: string] {\n let base_msgs = (ls $"locales/($base_locale)/*.ftl" | each { |f| fluent-extract $f.name } | flatten)\n let target_msgs = (ls $"locales/($target_locale)/*.ftl" | each { |f| fluent-extract $f.name } | flatten)\n $base_msgs | where $it not-in $target_msgs\n}\n\n\n## Contributing\n\nContributions are welcome! Please feel free to submit issues, feature requests, or pull requests.\n\n## License\n\nThis project is licensed under the MIT License.\n\n## Related Projects\n\n- Fluent - Mozilla's localization system\n- Nushell - A new type of shell\n- nu_plugin_tera - Tera templating plugin for Nushell