{"id":22937926,"url":"https://github.com/elaborate-code/jigsaw-localization","last_synced_at":"2026-04-06T00:02:58.830Z","repository":{"id":41338682,"uuid":"509198079","full_name":"elaborate-code/jigsaw-localization","owner":"elaborate-code","description":"📦🌐 A localization library for the static site generator 'tightenco/jigsaw' using JSON","archived":false,"fork":false,"pushed_at":"2024-04-29T21:46:02.000Z","size":201,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-19T05:31:24.141Z","etag":null,"topics":["internationalization","jigsaw","language","localization","package","php","translation"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/elaborate-code/jigsaw-localization","language":"PHP","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/elaborate-code.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-30T18:51:35.000Z","updated_at":"2025-01-26T18:50:48.000Z","dependencies_parsed_at":"2022-08-25T15:50:06.673Z","dependency_job_id":null,"html_url":"https://github.com/elaborate-code/jigsaw-localization","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/elaborate-code/jigsaw-localization","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elaborate-code%2Fjigsaw-localization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elaborate-code%2Fjigsaw-localization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elaborate-code%2Fjigsaw-localization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elaborate-code%2Fjigsaw-localization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elaborate-code","download_url":"https://codeload.github.com/elaborate-code/jigsaw-localization/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elaborate-code%2Fjigsaw-localization/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270113971,"owners_count":24529749,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["internationalization","jigsaw","language","localization","package","php","translation"],"created_at":"2024-12-14T12:15:06.282Z","updated_at":"2025-10-19T19:03:04.005Z","avatar_url":"https://github.com/elaborate-code.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jigsaw localization\n\n![Packagist Version](https://img.shields.io/packagist/v/elaborate-code/jigsaw-localization?label=Version\u0026style=plastic)\n![Packagist Downloads](https://img.shields.io/packagist/dt/elaborate-code/jigsaw-localization?label=Downloads\u0026style=plastic)\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elaborate-code/jigsaw-localization/run-tests?label=Tests)\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/elaborate-code/jigsaw-localization/Fix%20PHP%20code%20style%20issues?label=Code%20Style)\n\n![banner](https://banners.beyondco.de/Jigsaw%20Localization.png?theme=dark\u0026packageManager=composer+require\u0026packageName=elaborate-code%2Fjigsaw-localization\u0026pattern=jigsaw\u0026style=style_1\u0026description=Brings+localization+feature+to+%22tightenco%2Fjigsaw%22+using+JSON+files\u0026md=1\u0026showWatermark=0\u0026fontSize=100px\u0026images=globe)\n\nThis package is built on top of [PHP JSON tongue](https://github.com/elaborate-code/php-json-tongue) to bring localization feature to [tightenco/jigsaw](https://jigsaw.tighten.com/) using JSON files.\n\n## Get started\n\n### Requirements\n\n- PHP 8.0 or higher.\n\n### Setup\n\nInstall the package using composer:\n\n```text\ncomposer require elaborate-code/jigsaw-localization\n```\n\nPlug `LoadLocalization` to the builder by registering it in `bootstrap.php`:\n\n```php\n\u003c?php\n\n// bootstrap.php\n\nuse ElaborateCode\\JigsawLocalization\\LoadLocalization;\n\n$events-\u003ebeforeBuild([LoadLocalization::class]);\n```\n\n### Simple usage\n\n#### Defining Translation Strings\n\n1. Create a `lang` folder in the root of your project.\n2. Create subfolders for each language/locale.\n3. Populate the subfolders with JSON files that hold translations using the `original text` as a `key`, and the `translation` as a `value`.\n\nFile structure example:\n\n![example](https://raw.githubusercontent.com/elaborate-code/php-json-tongue/main/illustration.png)\n\n#### Retrieving Translation Strings\n\nSource example:\n\n```php\n\u003ch2\u003e {{ __($page, \"Good morning\", 'en') }} \u003c/h2\u003e\n\n\u003ch2\u003e {{ __($page, \"programmer\", 'es') }} \u003c/h2\u003e\n\n\u003ch2\u003e {{ __($page, \"Good morning\", 'fr') }} \u003c/h2\u003e\n```\n\nThe output:\n\n```html\n\u003ch2\u003e Good morning \u003c/h2\u003e\n\n\u003ch2\u003e programador \u003c/h2\u003e\n\n\u003ch2\u003e Bonjour \u003c/h2\u003e\n```\n\n#### Locale code format\n\n`two or three lowercase letters` for the language code + **optionally** `a dash (-) with two uppercase letters` for the region code. For example, all the following codes `ar`, `es`, `fr-CA`, `haw-US` are considered valid.\n\n- [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or [ISO 639-2](https://www.loc.gov/standards/iso639-2/php/English_list.php) for language codes.\n- [ISO 3166](https://www.iso.org/obp/ui/#search) for region codes.\n\n## The multi folder\n\nFor organizational purpose you can group internationalized translations in one JSON using many `locale` keys.\n\n```text\n/lang\n    ...\n    /multi\n        greetings.json\n        projects_short_descriptions.json\n        ...\n```\n\n`greetings.json` example:\n\n```json\n{\n    \"fr\": {\n        \"Hello\": \"Salut\",\n        \"Goodbye\": \"Au revoir\"\n    },\n    \"es\": {\n        \"Hello\": \"Hola\",\n        \"Goodbye\": \"Adiós\"\n    }\n}\n```\n\n\u003e First level keys must be locale codes!\n\n## Using folder structure for locale code prefix\n\n### The default locale\n\nFirst you need to define `defaultLocale` in `config.php`. If not set, the package will take `en` as a default.\n\n```php\n\u003c?php\n\n// config.php\n\nreturn [\n    // ...\n    'defaultLocale' =\u003e 'es',\n    // ...\n];\n```\n\n### The translation helper\n\nIf you call the `__` helper without providing a `locale` parameter, it will try to resolve it from the page path.\n\n```php\necho __($page, $text);\n```\n\n\u003e If you provide the `__` helper with the `locale` parameter it will proceed with it and ignore the folder structure.\n\n### The folder structure\n\n\u003e domain.com/{locale}/path\n\nPages that reside in the web root folder `source` are assumed to be rendered using the `defaultLocale`. Other pages that reside in **subfolders named after a locale code** have their **locale** set to the **subfolder name**\n\n```text\n/source\n    /fr\n        index.blade.php\n        contact.blade.php\n        about.blade.php\n        ...\n    /es\n        index.blade.php\n        contact.blade.php\n        about.blade.php\n        ...\n    ...\n    index.blade.php\n    contact.blade.php\n    about.blade.php\n    ...\n```\n\n## The included page trick\n\nYou may find your self creating a fully coded `source/index.blade.php` and repeating the same code in `source/fr/index.blade.php` and for other locales. To avoid that we suggest the following approach:\n\n1. Create a `source/_pages` directory which will contain the master pages.\n2. A master page will look like any other ordinary page, _it will have the HTML structure and calls to `__` but no hardcoded `$current_locale` value_ .For example You may directly copy the content of `source/index.blade.php` to `source/_pages/index.blade.php`.\n3. **Include** the master page into other pages that are locale aware.\n4. The included content will be able to know which **locale** to apply on the translation helper `__` calls as a `$current_locale`.\n\n```text\n/source\n    /_pages\n        index.blade.php\n        contact.blade.php\n        ...\n    /fr\n        index.blade.php\n        contact.blade.php\n        ...\n    index.blade.php\n    contact.blade.php\n    ...\n```\n\n```php\n// Both /source/index.blade.php and /source/fr/index.blade.php\n@include('_pages.index')\n```\n\n## Helpers\n\n\u003e IMPORTANT: All the following helpers will try to resolve the locale code from the path if needed!\n\n\u003e Setting `baseUrl` in the **config** is essential if your site root URL isn't 'domain.com/index.html'\n\n### current_path_locale\n\nReturns the **current page locale** deduced from its path.\n\n```php\ncurrent_path_locale($page) // ar | es | fr-CA | haw-US\n```\n\nUsage example:\n\n```php\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"{{ current_path_locale($page) }}\"\u003e\n    \u003chead\u003e\n    \u003c!-- ... --\u003e\n```\n\n### translate_path\n\nWhen you have a page that is available in many locales. `translate_path` helps you get the equivalent translated `path`.\n\n```php\ntranslate_path($page, $target_locale)\n```\n\ninput/output examples:\n\n| current path  | translated path  | current_locale to target_locale |\n| ------------- | ---------------- | ------------------------------- |\n| \"/\"           | \"/fr\"            | default -\u003e fr                   |\n| \"/contact\"    | \"/fr/contact\"    | default -\u003e fr                   |\n| \"/fr\"         | \"/\"              | fr -\u003e default                   |\n| \"/fr/contact\" | \"/contact\"       | fr -\u003e default                   |\n| \"/es/contact\" | \"/fr-CA/contact\" | es -\u003e fr-CA                     |\n| \"/es\"         | \"/fr-CA\"         | es -\u003e fr-CA                     |\n\nUsage example:\n\n```php\n\u003cnav\u003e\n    @foreach(['en', 'es', 'fr'] as $locale)\n        \u003ca href=\"{{ translate_path($page, $locale) }}\"\u003e {{ $locale }} \u003c/a\u003e\n    @endforeach\n\u003c/nav\u003e\n```\n\n### translate_url\n\nJust like the `translate_path` helper, but it prepends the `baseUrl` if set in the config.\n\n```php\ntranslate_url($page, $target_locale)\n```\n\n### locale_path\n\nTo avoid hard coding the `current_locale` into `paths`, input only the partial path that comes after the `locale code` part into this helper and it will handle the rest for you.\n\n```php\nlocale_path($page, $partial_path)\n```\n\n| $partial_path | current_locale | href          |\n| ------------- | -------------- | ------------- |\n| \"/\"           | DEFAULT        | \"/\"           |\n| \"/\"           | \"fr\"           | \"/fr\"         |\n| \"/contact\"    | DEFAULT        | \"/contact\"    |\n| \"/contact\"    | \"fr\"           | \"/fr/contact\" |\n\n### locale_url\n\nJust like the `locale_path` helper, but it prepends the `baseUrl` if set in the config.\n\n```php\nlocale_url($page, $partial_path)\n```\n\n## Live test\n\nWanna see a project that is up and running with this library? checkout this [repo](https://github.com/elaborate-code/it-company-website)\n\n## TODO\n\n- Test behavior with non A-Z languages.\n- Add a router with named routes\n  - Allow custom route patterns (for example set /blog/{locale}/)\n\n## Contributing\n\nAny help is very welcomed, feel free to fork and PR :)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felaborate-code%2Fjigsaw-localization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felaborate-code%2Fjigsaw-localization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felaborate-code%2Fjigsaw-localization/lists"}