odoo-i18n
Comprehensive Odoo i18n toolkit for extracting translatable strings, validating .po files, generating translation reports, managing Arabic/RTL layouts, and handling multilingual deployments across Odoo 14-19. <example> Context: User wants to extract translatable strings user: "Extract all translatable strings from my Odoo 17 module to a .pot file" assistant: "I will use the odoo-i18n skill to scan Python _() calls, XML translate attributes, and field strings, then generate a properly structured .pot template file." <commentary>Core trigger - translation extraction workflow.</commentary> </example> <example> Context: User wants Arabic translation user: "Generate an Arabic .po file for my Odoo module" assistant: "I will use the odoo-i18n skill to create an ar.po file with RTL-aware formatting and placeholder translations for all extractable strings." <commentary>Language-specific trigger - Arabic/RTL translation generation.</commentary> </example> <example> Context: User wants to validate a translation file user: "Validate my Arabic .po file for errors" assistant: "I will use the odoo-i18n skill to check syntax, encoding, empty translations, fuzzy entries, and RTL-specific issues." <commentary>Validate trigger - .po file validation.</commentary> </example> <example> Context: User wants to find missing translations user: "Find all strings missing Arabic translation in my module" assistant: "I will compare the .pot template against ar.po and report all untranslated or fuzzy entries." <commentary>Missing trigger - translation gap analysis.</commentary> </example> <example> Context: User wants RTL/SCSS help user: "Fix the RTL layout issues in my Odoo theme for Arabic" assistant: "I will use the odoo-i18n skill to apply CSS logical properties, [dir='rtl'] overrides, and Font Awesome icon swaps for Arabic support." <commentary>RTL trigger - Arabic layout and styling guidance.</commentary> </example> <example> Context: User needs to export/import translations via Odoo CLI user: "Export translations for my module using Odoo CLI" assistant: "I will use the odoo-i18n skill to run the Odoo export command and generate the .po file." <commentary>Export trigger - Odoo CLI translation export.</commentary> </example> <example> Context: User needs to load a language into Odoo user: "How do I activate Arabic language in my Odoo database?" assistant: "I will use the odoo-i18n skill to load the Arabic language pack and activate it via shell or CLI." <commentary>Language activation trigger.</commentary> </example> <example> Context: User has translation issues after deployment user: "My translations are not showing after I updated the module" assistant: "I will diagnose the issue: check encoding, language activation, module update, and browser cache." <commentary>Troubleshooting trigger - translation visibility issues.</commentary> </example>
What this skill does
# Odoo i18n Skill
Provides deep expertise in Odoo internationalization (i18n) and localization (l10n) across Odoo 14-19.
## Critical Translation Rules
1. **NEVER** use f-strings inside `_()` -- use `%` formatting: `_('Record %s') % name`
2. **NEVER** concatenate strings inside `_()` -- give the translator the full sentence
3. **Use `_lt()`** for class-level strings (selection values, class attributes)
4. **NEVER wrap** `string=` field attributes in `_()` -- they are auto-translated by Odoo
5. **Save `.po` files as UTF-8** without BOM
6. **Arabic** `.po` files must have `nplurals=6` in Plural-Forms header
7. **Always update the module** after editing `.po` files: `-u module --stop-after-init`
---
## Workflow 1: Extract Translatable Strings
Scans an Odoo module for all translatable strings and generates `.pot` (template) and `.po` (language) files.
### Usage
```bash
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_extractor.py --module <path> --lang <code> [--output <dir>] [--no-pot] [--verbose]
```
| Argument | Required | Description |
|----------|----------|-------------|
| `--module` | Yes | Path to the Odoo module directory |
| `--lang` | Yes | Target language code (e.g., `ar`, `fr`, `tr`) |
| `--output` | No | Custom output directory (default: `module/i18n/`) |
| `--no-pot` | No | Skip generating .pot template |
| `--verbose` | No | Show all extracted strings |
### What Gets Extracted
**Python (`*.py`)** -- `_('...')` and `_lt('...')`:
```python
# Extracted:
raise UserError(_('Record %s not found') % name)
state = fields.Selection([('draft', _lt('Draft'))])
# NOT extracted: _(variable), _(f'Hello {name}')
```
**XML (`*.xml`)** -- `string=`, `help=`, `placeholder=` attributes; `name=` on menus/actions; HTML text:
```xml
<field name="state" string="Status"/> <!-- extracted -->
<h1>Welcome to our website</h1> <!-- extracted -->
<record id="view_my_form" model="ir.ui.view"> <!-- NOT extracted -->
```
**JavaScript (`*.js`)** -- `_t('...')` and `_lt('...')`:
```javascript
const msg = _t("Save Changes"); // extracted
const msg = _t(someVariable); // NOT extracted
```
### Generated File Structure
```po
# Translation template for my_module
msgid ""
msgstr ""
"Project-Id-Version: Odoo Module my_module\n"
"Content-Type: text/plain; charset=UTF-8\n"
#: models/my_model.py:45
#, python-format
msgid "Record %s not found"
msgstr ""
```
### Alternative: Odoo's Built-in Extractor
```bash
python odoo-bin -c conf/myproject.conf -d mydb \
--i18n-export --modules=my_module --language=ar \
--output=my_module/i18n/ar.po --stop-after-init
```
The Odoo CLI extractor includes database strings (model names, action names) that the plugin extractor does not. For production, the built-in extractor is more complete.
### After Extraction
1. Open the `.po` file in a translation editor (Poedit, Virtaal, or text editor)
2. Fill in all `msgstr` entries
3. Validate: run `i18n_validator.py --po-file path/to/ar.po`
4. Check coverage: run `i18n_reporter.py --module path/ --lang ar`
5. Load into Odoo: update module or use export/import workflow
---
## Workflow 2: Validate .po Files
Validates a `.po` file for syntax errors, encoding issues, empty translations, fuzzy entries, format specifier mismatches, and Arabic/RTL-specific problems.
### Usage
```bash
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_validator.py --po-file <path> [--lang <code>] [--strict] [--output <file>]
```
| Argument | Required | Description |
|----------|----------|-------------|
| `--po-file` | Yes | Path to the `.po` file to validate |
| `--lang` | No | Language code for language-specific checks (auto-detected from filename) |
| `--strict` | No | Treat untranslated strings as errors instead of warnings |
| `--output` | No | Write report to a file instead of stdout |
### What is Validated
**Syntax:** UTF-8 encoding (no BOM/Latin-1), header with Content-Type/charset/Language/MIME-Version, properly quoted strings, no parse errors.
**Translations:** Empty `msgstr` (untranslated), fuzzy flags needing review, duplicate `msgid`, obsolete (`#~`) entries.
**Format Specifiers:** `%s`/`%d`/`%f` count must match; `%(name)s` named specifiers must all appear:
```po
# WRONG - missing second %s:
msgid "Invoice %s due on %s"
msgstr "fatura %s"
# CORRECT:
msgid "Invoice %s due on %s"
msgstr "fatura %s vadesi %s"
```
**Arabic-Specific (`--lang ar`):** Arabic characters present, encoding artifacts from Latin-1, direction control chars, `nplurals=6` required, BIDI overrides flagged.
### Common Errors and Fixes
**"Charset must be UTF-8":**
```bash
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action convert --po ar.po --output ar_fixed.po
```
**"Fuzzy translation (needs review)"** -- remove the `fuzzy` flag after verifying:
```po
# Before: # After:
#, fuzzy, python-format #, python-format
msgid "Record %s not found" msgid "Record %s not found"
msgstr "record not found" msgstr "record not found"
```
**"Arabic should have nplurals=6":**
```po
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
```
### CI/CD Integration
```yaml
- name: Validate Arabic translations
run: python odoo-i18n/scripts/i18n_validator.py --po-file my_module/i18n/ar.po --lang ar --strict
```
Exit code `0` = passed (may have warnings), `1` = failed (errors found).
---
## Workflow 3: Find Missing Translations
Compares translatable strings from a module's source files against an existing `.po` file to report what is missing or incomplete.
### Usage
```bash
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_reporter.py --module <path> --lang <code> [--format text|json|csv] [--output <file>] [--min-pct <N>]
```
| Argument | Required | Description |
|----------|----------|-------------|
| `--module` | Yes | Path to the Odoo module directory |
| `--lang` | Yes | Language code to check (e.g., `ar`, `fr`) |
| `--format` | No | Output format: `text` (default), `json`, `csv` |
| `--output` | No | Write report to a file instead of stdout |
| `--min-pct` | No | Exit code 1 if completion below threshold |
### Understanding the Report
- **Missing**: String in source code but NO entry in `.po`
- **Empty in .po**: Entry exists but `msgstr` is `""` (not yet translated)
- **Fuzzy**: Auto-matched, needs human review; NOT shown to users (Odoo falls back to source)
- **Completion %** = Translated / Total Active Strings * 100 (non-empty, non-fuzzy, non-obsolete)
### Workflow: Fixing Missing Translations
1. Run `i18n_reporter.py` to identify gaps
2. Open `.po` in Poedit, Virtaal, or text editor
3. Fill in missing `msgstr` entries
4. If strings are entirely absent from `.po`, run `i18n_extractor.py` first
5. Validate with `i18n_validator.py`
6. Re-run `i18n_reporter.py` to confirm coverage
### Updating .po After Source Changes
```bash
# 1. Re-extract new strings
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_extractor.py --module /path/ --lang ar --no-pot
# 2. Merge (preserves existing translations)
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py \
--action merge --base /path/i18n/ar.po --new /path/i18n/ar.po --output /path/i18n/ar_merged.po
# 3. Check remaining gaps
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_reporter.py --module /path/ --lang ar
```
---
## Workflow 4: Export/Import via Odoo CLI
Requires PostgreSQL and a valid database.
### Exporting Translations
```bash
# Single module
python odoo-bin -c conf/myproject.conf -d mydb \
--i18n-export --modules=my_module --language=ar \
--output=my_module/i18n/ar.po --stop-after-init
# Export .pot template (no --language = empty msgstr)
python odoo-bin -c conf/myproject.conf -d mydb \
--i18n-export --modules=my_module \
--output=my_module/i18n/my_module.pot --stop-after-init
# Multiple modules / all installed
python odoo-bin -c conf/myproject.coRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.