{"id":38495164,"url":"https://github.com/wheels-dev/wheels-i18n","last_synced_at":"2026-04-24T16:01:11.245Z","repository":{"id":327031571,"uuid":"1104579663","full_name":"wheels-dev/wheels-i18n","owner":"wheels-dev","description":"Internationalization (i18n) plugin for Wheels","archived":false,"fork":false,"pushed_at":"2025-12-22T18:30:41.000Z","size":114271,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-17T16:52:53.797Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"ColdFusion","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wheels-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-26T12:01:08.000Z","updated_at":"2025-12-22T18:30:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wheels-dev/wheels-i18n","commit_stats":null,"previous_names":["zainforbjs/wheels-i18n"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/wheels-dev/wheels-i18n","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wheels-dev%2Fwheels-i18n","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wheels-dev%2Fwheels-i18n/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wheels-dev%2Fwheels-i18n/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wheels-dev%2Fwheels-i18n/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wheels-dev","download_url":"https://codeload.github.com/wheels-dev/wheels-i18n/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wheels-dev%2Fwheels-i18n/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32230421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-17T05:50:20.133Z","updated_at":"2026-04-24T16:01:11.239Z","avatar_url":"https://github.com/wheels-dev.png","language":"ColdFusion","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wheels-i18n\n\n**The simplest, fastest, and most powerful internationalization package for Wheels 4.x+**\n\n• Lightweight\n• Zero dependencies\n• JSON or Database backed\n• Built-in pluralization\n• Full fallback support\n\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wheels-dev/wheels-i18n/blob/main/LICENSE)\n[![Wheels 4+](https://img.shields.io/badge/Wheels-4%2B-brightgreen)](https://wheels.dev)\n\n## Features\n\n- `t()` – Simple key-based translation with variable interpolation\n- `tp()` – Pluralization support (`.zero`, `.one`, `.other`)\n- JSON file or database translation sources\n- Session-based locale switching\n- Fallback locale \u0026 missing key handling\n- Optional in-memory caching (great for production)\n- Works in views and controllers (mixed into the `controller` target)\n\n## Requirements\n\n- Wheels 4.0+\n- Lucee 5+, Adobe ColdFusion 2018+, or BoxLang\n\n## Installation\n\n```bash\nwheels packages install wheels-i18n\n```\n\nAfter installation the package lands in `vendor/wheels-i18n/` and auto-loads on the next application start. Run `wheels reload` (or hit `?reload=true\u0026password=...`) to pick it up without a restart.\n\n### Upgrading from the 3.x plugin\n\nThe 3.x plugin (installed under `plugins/i18n/`) is incompatible with Wheels 4.0's package system. To upgrade:\n\n1. Delete the old `plugins/i18n/` directory and any lingering `plugins/I18n/` folder.\n2. Run `wheels packages install wheels-i18n`.\n3. Your existing `config/settings.cfm` values (`i18n_defaultLocale`, etc.) and `app/locales/*.json` files continue to work unchanged.\n\n## Translation via JSON File\n\n### Step 1: Configuration Settings\n\nAdd these settings in your `config/settings.cfm` file:\n\n```cfml\nset(i18n_defaultLocale=\"en\");\nset(i18n_availableLocales=\"en,es\");\nset(i18n_fallbackLocale=\"en\");\nset(i18n_translationSource=\"json\");\nset(i18n_translationsPath=\"/app/locales\");\nset(i18n_cacheTranslations=false);\n```\n\nBelow is a description of all available i18n configuration settings and their default values:\n\n| Setting Name | Default | Description  |\n|-------------|-----------------|-----------|\n| i18n_defaultLocale | `en` | Default locale if none is set in session |\n| i18n_availableLocales | `en` | A comma-separated list of all supported locales: \"en,es\" |\n| i18n_fallbackLocale | `en` | Used if a translation key is missing in current locale |\n| i18n_translationSource | `json` | Translation method: \"json\" or \"database\" |\n| i18n_translationsPath | `/app/locales` | Path for JSON files (only used with json source) |\n| i18n_cacheTranslations | `false` | Cache translations in memory (recommended for production) |\n\n___Pro Tip___: __Set i18n_cacheTranslations=true in production for fast performance.__\n\n### Step 2: Add Your First Translation\n\nCreate this file: `/app/locales/en/common.json`\n\n```json\n{\n  \"welcome\": \"Welcome to my app!\",\n  \"greeting\": \"Hello, {name}!\",\n  \"save\": \"Save\",\n  \"posts\": {\n    \"zero\": \"No Post Found\",\n    \"one\": \"{count} Post Found\", \n    \"other\": \"{count} Posts Found\" \n  },\n  \"nav\": {\n    \"home\": \"Home\",\n    \"about\": {\n        \"service\": \"Service\",\n        \"portfolio\": \"Portfolio\"\n    },\n    \"contact\": \"Contact\"\n  }\n}\n```\n\nSame for different language: `/app/locales/es/common.json`\n\n```json\n{\n  \"welcome\": \"Bienvenido a nuestra aplicación\",\n  \"greeting\": \"¡Hola, {name}!\",\n  \"save\": \"Guardar\",\n  \"posts\": {\n    \"zero\": \"No se encontraron publicaciones\",\n    \"one\": \"{count} publicación encontrada\",\n    \"other\": \"{count} publicaciones encontradas\"\n  },\n  \"nav\": {\n    \"home\": \"Hogar\",\n    \"about\": {\n        \"service\": \"Servicio\",\n        \"portfolio\": \"Cartera\"\n    },\n    \"contact\": \"Contacto\"\n  }\n}\n```\n\n### Directory Structure\n\nYour application should follow the following localization structure:\n\n```bash\n/app\n  /locales\n    /en\n      common.json\n      forms.json\n    /es\n      common.json\n      forms.json\n```\n\n### Step 3: Use It Anywhere\n\n```cfml\n#t(\"common.welcome\")#\n#t(\"common.greeting\", name=\"Sarah\")#\n#t(\"common.nav.about.service\")#\n#tp(\"common.posts\", count=5)#\n```\n\n__Your Are Done!__\n\n## Translation via Database\n\n### Step 1: Configuration Settings\n\nAdd these settings in your `config/settings.cfm` file:\n\n```cfml\nset(i18n_defaultLocale=\"en\");\nset(i18n_availableLocales=\"en,es\");\nset(i18n_fallbackLocale=\"en\");\nset(i18n_translationSource=\"database\");\nset(i18n_cacheTranslations=false);\n```\n\n___Optional:___ __Customize database table and column names if your schema differs.__\n\n``` cfml\nset(i18n_dbTable=\"i18n_translations\");\nset(i18n_dbLocaleColumn=\"locale\");\nset(i18n_dbKeyColumn=\"translation_key\");\nset(i18n_dbValueColumn=\"translation_value\");\n```\n\n### Database Options\n\n  Setting               Default               Description\n  --------------------- --------------------- -------------------\n  i18n_dbTable          `i18n_translations`   Translation table\n  i18n_dbLocaleColumn   `locale`              Locale column\n  i18n_dbKeyColumn      `translation_key`     Translation key\n  i18n_dbValueColumn    `translation_value`   Translation value\n\n------------------------------------------------------------------------\n\n___Note:___ __These settings are only used when `i18n_translationSource=\"database\"`. If not defined, the package automatically uses the default values.__\n\n### Step 2: Create the Translation Table\n\nCreate the database table using a standard Wheels migration:\n\n#### Run the command in CLI:\n\n```bash\nwheels dbmigrate create table i18n_translations\n```\n\nThen replace the generated file with this content:\n\n```cfml\n// app/migrator/migrations/XXXX_cli_create_table_i18n_translations.cfc\ncomponent {\n  function up() {\n    t = createTable(name = 'i18n_translations', force='false', id='true', primaryKey='id');\n    t.string(columnNames = 'locale', limit = '10', allowNull = false);\n    t.string(columnNames = 'translation_key', limit = '255', allowNull = false);\n    t.text(columnNames = 'translation_value', allowNull = false);\n    t.timestamps();\n    t.create();\n\n    addIndex(table=\"i18n_translations\", columnNames=\"locale\");\n    addIndex(table=\"i18n_translations\", columnNames=\"translation_key\");\n  }\n\n  function down() {\n    dropTable(\"i18n_translations\");\n  }\n}\n```\n\nThen this command in CLI to run your migration:\n\n```bash\nwheels dbmigrate up\n```\n\n## Using a Custom Database Schema\n\nIf your project already has a translations table, simply map it:\n```\nset(i18n_translationSource=\"database\");\nset(i18n_dbTable=\"translations\");\nset(i18n_dbLocaleColumn=\"lang\");\nset(i18n_dbKeyColumn=\"key_name\");\nset(i18n_dbValueColumn=\"value_text\");\n```\n\n__No package code changes are required.__\n\n### Step 3: Add Insertions in the i18n_translations Table\n\nInsert your translations keys according to your database to run your translation. here's a sample in MySQL\n\n```\nINSERT INTO i18n_translations (locale, translation_key, translation_value, createdAt, updatedAt) VALUES\n('en', 'common.welcome', 'Welcome to our application', NOW(), NOW()),\n('en', 'common.greeting', 'Hello, {name}!', NOW(), NOW()),\n('en', 'common.goodbye', 'Goodbye', NOW(), NOW()),\n('en', 'common.posts.zero', 'No Post Found', NOW(), NOW()),\n('en', 'common.posts.one', '{count} Post Found', NOW(), NOW()),\n('en', 'common.posts.other', '{count} Posts Found', NOW(), NOW()),\n('es', 'common.welcome', 'Bienvenido a nuestra aplicación', NOW(), NOW()),\n('es', 'common.greeting', '¡Hola, {name}!', NOW(), NOW()),\n('es', 'common.goodbye', 'Adiós', NOW(), NOW()),\n('es', 'common.posts.zero', 'Ningún Post Encontrado', NOW(), NOW()),\n('es', 'common.posts.one', '{count} Post Encontrado', NOW(), NOW()),\n('es', 'common.posts.other', '{count} Posts Encontrados', NOW(), NOW());\n```\n\n### Step 4: Use It Anywhere\n\n```cfml\n#t(\"common.welcome\")#\n#t(\"common.greeting\", name=\"Sarah\")#\n#tp(\"common.posts\", count=5)#\n```\n\n__Your Are Done!__\n\n### (Optional) Add Admin Panel\n\nWant translators or clients to edit translations live in the browser?\n\nYou can easily build your own admin area using standard Wheels tools:\n\n* Create a simple model mapped to the i18n_translations table\n* Add a controller with index and save actions\n* Build a clean view with a form (locale + key + value)\n\nThat’s it — your translators can now update text instantly.\n\n___Many agencies love this workflow. You’re in full control — build it exactly how you want.___\n\n___Design Philosophy:___ __All configuration options have sensible defaults. You only need to configure what differs from your application. This keeps setup fast while remaining fully flexible.__\n\n\u003chr\u003e\n\n## Package Functions\n\n- `#t(\"key\")#` → Translate\n- `#t(\"key\", name=\"[param]\")#` → With variables\n- `#tp(\"key\", count=[param])#` → Pluralization (.zero, .one, .other)\n- `#currentLocale()#` → Get current language\n- `#changeLocale(\"es\")#` → Switch language\n- `#availableLocales()#` → Array of supported languages\n\n## Usage\n\n### Basic Translation Function - `t()`\n\nThe core function to translate a key to the current locale, with parameter interpolation and fallback logic.\n\n```cfml\n// Basic Usage\n#t(\"common.welcome\")#       // (Output: Welcome to our application)\n\n// With parameter interpolation\n#t(key=\"common.greeting\", name=\"John Doe\")#       // (Output: \"Hello, John Dow!\")\n```\n\n### Pluralization Function - `tp()`\n\nTranslates a key and automatically selects the correct singular (.one) or plural (.other) form based on the count argument. The count is also available for interpolation as {count}.\n\nNote: This implementation assumes the simple English plural rule (1 is singular, anything else is plural).\n\n```cfml\n// Zero usage (Count = 0) \n#tp(key=\"common.posts\", count=0)#     // (Output: \"No Post Found\")\n\n// Singular usage (Count = 1)\n#tp(key=\"common.posts\", count=1)#     // (Output: \"1 Post Found\")\n\n// Plural usage (Count \u003e 1)\n#tp(key=\"common.posts\", count=5)#     // (Output: \"5 Posts Found\")\n```\n\n### Change Locale - `changeLocale()`\n\nSets the application locale in Session and returns a boolean based on success.\n\n```cfml\n// Change to Spanish\nchangeLocale(\"es\");\n\n// Unsupported locale\nchangeLocale(\"jp\");       // false\n```\n\n### Get Current Locale - `currentLocale()`\n\nGets the current application locale from the Session, or the default locale if not set.\n\n```cfml\nlocale = currentLocale();       // \"en\"\n```\n\n### Get All Available Locales - `availableLocales()`\n\nReturns an array of all configured available locales.\n\n```cfml\nlocales = availableLocales();       // [\"en\", \"es\", \"fr\"]\n```\n\n## License\n\n[MIT](https://github.com/wheels-dev/wheels-i18n/blob/main/LICENSE)\n\n## Author\n\n[Wheels-dev](https://forgebox.io/@wheels%2Ddev)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwheels-dev%2Fwheels-i18n","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwheels-dev%2Fwheels-i18n","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwheels-dev%2Fwheels-i18n/lists"}