{"id":21662590,"url":"https://github.com/php-gettext/gettext","last_synced_at":"2025-05-14T11:08:45.722Z","repository":{"id":4376206,"uuid":"5512902","full_name":"php-gettext/Gettext","owner":"php-gettext","description":"PHP library to collect and manipulate gettext (.po, .mo, .php, .json, etc)","archived":false,"fork":false,"pushed_at":"2025-05-04T20:35:59.000Z","size":1194,"stargazers_count":697,"open_issues_count":27,"forks_count":137,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-05-04T21:29:18.583Z","etag":null,"topics":["gettext","i18n","internationalization","translation"],"latest_commit_sha":null,"homepage":"","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/php-gettext.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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},"funding":{"github":"oscarotero","patreon":"misteroom","custom":"https://paypal.me/oscarotero"}},"created_at":"2012-08-22T17:32:16.000Z","updated_at":"2025-05-04T20:36:04.000Z","dependencies_parsed_at":"2023-07-05T18:32:23.333Z","dependency_job_id":"ae5f1bf7-9492-4c91-9c4b-d099b2d886c5","html_url":"https://github.com/php-gettext/Gettext","commit_stats":{"total_commits":690,"total_committers":65,"mean_commits":"10.615384615384615","dds":"0.49420289855072463","last_synced_commit":"46b053c3559803d4f7e0a281c5425be5a8c3d9ad"},"previous_names":[],"tags_count":88,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-gettext%2FGettext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-gettext%2FGettext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-gettext%2FGettext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/php-gettext%2FGettext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/php-gettext","download_url":"https://codeload.github.com/php-gettext/Gettext/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129488,"owners_count":22019628,"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","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":["gettext","i18n","internationalization","translation"],"created_at":"2024-11-25T10:17:11.404Z","updated_at":"2025-05-14T11:08:45.695Z","avatar_url":"https://github.com/php-gettext.png","language":"PHP","funding_links":["https://github.com/sponsors/oscarotero","https://patreon.com/misteroom","https://paypal.me/oscarotero"],"categories":[],"sub_categories":[],"readme":"# Gettext\n\n[![Latest Version on Packagist][ico-version]][link-packagist]\n[![Software License][ico-license]](LICENSE)\n![ico-ga]\n[![Total Downloads][ico-downloads]][link-downloads]\n\n\u003e Note: this is the documentation of the new 5.x version. Go to [4.x branch](https://github.com/php-gettext/Gettext/tree/4.x) if you're looking for the old 4.x version\n\nCreated by Oscar Otero \u003chttp://oscarotero.com\u003e \u003coom@oscarotero.com\u003e (MIT License)\n\nGettext is a PHP (^7.2) library to import/export/edit gettext from PO, MO, PHP, JS files, etc.\n\n## Installation\n\n```\ncomposer require gettext/gettext\n```\n\n## Classes and functions\n\nThis package contains the following classes:\n\n* `Gettext\\Translation` - A translation definition\n* `Gettext\\Translations` - A collection of translations (under the same domain)\n* `Gettext\\Scanner\\*` - Scan files to extract translations (php, js, twig templates, ...)\n* `Gettext\\Loader\\*` - Load translations from different formats (po, mo, json, ...)\n* `Gettext\\Generator\\*` - Export translations to various formats (po, mo, json, ...)\n\n## Usage example\n\n```php\nuse Gettext\\Loader\\PoLoader;\nuse Gettext\\Generator\\MoGenerator;\n\n//import from a .po file:\n$loader = new PoLoader();\n$translations = $loader-\u003eloadFile('locales/gl.po');\n\n//edit some translations:\n$translation = $translations-\u003efind(null, 'apple');\n\nif ($translation) {\n    $translation-\u003etranslate('Mazá');\n}\n\n//export to a .mo file:\n$generator = new MoGenerator();\n$generator-\u003egenerateFile($translations, 'Locale/gl/LC_MESSAGES/messages.mo');\n```\n\n## Translation\n\nThe `Gettext\\Translation` class stores all information about a translation: the original text, the translated text, source references, comments, etc.\n\n```php\nuse Gettext\\Translation;\n\n$translation = Translation::create('comments', 'One comment', '%s comments');\n\n$translation-\u003etranslate('Un comentario');\n$translation-\u003etranslatePlural('%s comentarios');\n\n$translation-\u003egetReferences()-\u003eadd('templates/comments/comment.php', 34);\n$translation-\u003egetComments()-\u003eadd('To display the amount of comments in a post');\n\necho $translation-\u003egetContext(); // comments\necho $translation-\u003egetOriginal(); // One comment\necho $translation-\u003egetTranslation(); // Un comentario\n\n// etc...\n```\n\n## Translations\n\nThe `Gettext\\Translations` class stores a collection of translations:\n\n```php\nuse Gettext\\Translations;\n\n$translations = Translations::create('my-domain');\n\n//You can add new translations:\n$translation = Translation::create('comments', 'One comment', '%s comments');\n$translations-\u003eadd($translation);\n\n//Find a specific translation\n$translation = $translations-\u003efind('comments', 'One comment');\n\n//Edit headers, domain, etc\n$translations-\u003egetHeaders()-\u003eset('Last-Translator', 'Oscar Otero');\n$translations-\u003esetDomain('my-blog');\n```\n\n## Loaders\n\nThe loaders allow to get gettext values from multiple formats. For example, to load a .po file:\n\n```php\nuse Gettext\\Loader\\PoLoader;\n\n$loader = new PoLoader();\n\n//From a file\n$translations = $loader-\u003eloadFile('locales/en.po');\n\n//From a string\n$string = file_get_contents('locales2/en.po');\n$translations = $loader-\u003eloadString($string);\n```\n\nAs of version 5.7.0, a `StrictPoLoader` has been included, with a parser more aligned to the GNU gettext tooling with the same expectations and failures (see the tests for more details).\n- It will fail with an exception when there's anything wrong with the syntax, and display the reason together with the line/byte where it happened.\n- It might also emit useful warnings, e.g. when there are more/less plural translations than needed, missing translation header, dangling comments not associated with any translation, etc.\n- Due to its strictness and speed (about 50% slower than the `PoLoader`), it might be interesting to be used as a kind of `.po` linter in a build system.\n- It also implements the previous translation comment (e.g. `#| msgid \"previous\"`) and extra escapes (16-bit unicode `\\u`, 32-bit unicode `\\U`, hexadecimal `\\xFF` and octal `\\77`).\n\nThe usage is basically the same as the `PoLoader`:\n\n```php\nuse Gettext\\Loader\\StrictPoLoader;\n\n$loader = new StrictPoLoader();\n\n//From a file\n$translations = $loader-\u003eloadFile('locales/en.po');\n\n//From a string\n$string = file_get_contents('locales2/en.po');\n$translations = $loader-\u003eloadString($string);\n\n//Display error messages using \"at line X column Y\" instead of \"at byte X\"\n$loader-\u003edisplayErrorLine = true;\n//Throw an exception when a warning happens\n$loader-\u003ethrowOnWarning = true;\n//Retrieve the warnings\n$loader-\u003egetWarnings();\n```\n\nThis package includes the following loaders:\n\n- `MoLoader`\n- `PoLoader`\n- `StrictPoLoader`\n\nAnd you can install other formats with loaders and generators:\n\n- [Json](https://github.com/php-gettext/Json)\n\n## Generators\n\nThe generators export a `Gettext\\Translations` instance to any format (po, mo, etc).\n\n```php\nuse Gettext\\Loader\\PoLoader;\nuse Gettext\\Generator\\MoGenerator;\n\n//Load a PO file\n$poLoader = new PoLoader();\n\n$translations = $poLoader-\u003eloadFile('locales/en.po');\n\n//Save to MO file\n$moGenerator = new MoGenerator();\n\n$moGenerator-\u003egenerateFile($translations, 'locales/en.mo');\n\n//Or return as a string\n$content = $moGenerator-\u003egenerateString($translations);\nfile_put_contents('locales/en.mo', $content);\n```\n\nThis package includes the following generators:\n\n- `MoGenerator`\n- `PoGenerator`\n\nAnd you can install other formats with loaders and generators:\n\n- [Json](https://github.com/php-gettext/Json)\n\n\n## Scanners\n\nScanners allow to search and extract new gettext entries from different sources like php files, twig templates, blade templates, etc. Unlike loaders, scanners allows to extract gettext entries with different domains at the same time:\n\n```php\nuse Gettext\\Scanner\\PhpScanner;\nuse Gettext\\Translations;\n\n//Create a new scanner, adding a translation for each domain we want to get:\n$phpScanner = new PhpScanner(\n    Translations::create('domain1'),\n    Translations::create('domain2'),\n    Translations::create('domain3')\n);\n\n//Set a default domain, so any translations with no domain specified, will be added to that domain\n$phpScanner-\u003esetDefaultDomain('domain1');\n\n//Extract all comments starting with 'i18n:' and 'Translators:'\n$phpScanner-\u003eextractCommentsStartingWith('i18n:', 'Translators:');\n\n//Scan files\nforeach (glob('*.php') as $file) {\n    $phpScanner-\u003escanFile($file);\n}\n\n//Get the translations\nlist('domain1' =\u003e $domain1, 'domain2' =\u003e $domain2, 'domain3' =\u003e $domain3) = $phpScanner-\u003egetTranslations();\n```\n\nThis package does not include any scanner by default. But there are some that you can install:\n\n- [PHP Scanner](https://github.com/php-gettext/PHP-Scanner)\n- [JS Scanner](https://github.com/php-gettext/JS-Scanner)\n\n## Merging translations\n\nYou will want to update or merge translations. The function `mergeWith` create a new `Translations` instance with other translations merged:\n\n```php\n$translations3 = $translations1-\u003emergeWith($translations2);\n```\n\nBut sometimes this is not enough, and this is why we have merging options, allowing to configure how two translations will be merged. These options are defined as constants in the `Gettext\\Merge` class, and are the following:\n\nConstant | Description\n--------- | -----------\n`Merge::TRANSLATIONS_OURS` | Use only the translations present in `$translations1`\n`Merge::TRANSLATIONS_THEIRS` | Use only the translations present in `$translations2`\n`Merge::TRANSLATIONS_OVERRIDE` | Override the translation and plural translations with the value of `$translation2`\n`Merge::HEADERS_OURS` | Use only the headers of `$translations1`\n`Merge::HEADERS_REMOVE` | Use only the headers of `$translations2`\n`Merge::HEADERS_OVERRIDE` | Overrides the headers with the values of `$translations2`\n`Merge::COMMENTS_OURS` | Use only the comments of `$translation1`\n`Merge::COMMENTS_THEIRS` | Use only the comments of `$translation2`\n`Merge::EXTRACTED_COMMENTS_OURS` | Use only the extracted comments of `$translation1`\n`Merge::EXTRACTED_COMMENTS_THEIRS` | Use only the extracted comments of `$translation2`\n`Merge::FLAGS_OURS` | Use only the flags of `$translation1`\n`Merge::FLAGS_THEIRS` | Use only the flags of `$translation2`\n`Merge::REFERENCES_OURS` | Use only the references of `$translation1`\n`Merge::REFERENCES_THEIRS` | Use only the references of `$translation2`\n\nUse the second argument to configure the merging strategy:\n\n```php\n$strategy = Merge::TRANSLATIONS_OURS | Merge::HEADERS_OURS;\n\n$translations3 = $translations1-\u003emergeWith($translations2, $strategy);\n```\n\nThere are some typical scenarios, one of the most common:\n\n- Scan php templates searching for entries to translate\n- Complete these entries with the translations stored in a .po file\n- You may want to add new entries to the .po file\n- And also remove those entries present in the .po file but not in the templates (because they were removed)\n- But you want to update some translations with new references and extracted comments\n- And keep the translations, comments and flags defined in .po file\n\nFor this scenario, you can use the option `Merge::SCAN_AND_LOAD` with the combination of options to fit this needs (SCAN new entries and LOAD a .po file).\n\n```php\n$newEntries = $scanner-\u003escanFile('template.php');\n$previousEntries = $loader-\u003eloadFile('translations.po');\n\n$updatedEntries = $newEntries-\u003emergeWith($previousEntries);\n```\n\nMore common scenarios may be added in a future.\n\n## Related projects\n\n- [gettext-wp-scanner](https://github.com/10quality/gettext-wp-scanner) WordPress code scanner to use with this library.\n\n## Contributors\n\nThanks to all [contributors](https://github.com/oscarotero/Gettext/graphs/contributors) specially to [@mlocati](https://github.com/mlocati).\n\n---\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information about recent changes and [CONTRIBUTING](CONTRIBUTING.md) for contributing details.\n\nThe MIT License (MIT). Please see [LICENSE](LICENSE) for more information.\n\n[ico-version]: https://img.shields.io/packagist/v/gettext/gettext.svg?style=flat-square\n[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\n[ico-ga]: https://github.com/php-gettext/Gettext/workflows/testing/badge.svg\n[ico-downloads]: https://img.shields.io/packagist/dt/gettext/gettext.svg?style=flat-square\n\n[link-packagist]: https://packagist.org/packages/gettext/gettext\n[link-downloads]: https://packagist.org/packages/gettext/gettext\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphp-gettext%2Fgettext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphp-gettext%2Fgettext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphp-gettext%2Fgettext/lists"}