{"id":24540670,"url":"https://github.com/mistralys/application-localization","last_synced_at":"2025-04-15T08:42:13.740Z","repository":{"id":57017610,"uuid":"211818572","full_name":"Mistralys/application-localization","owner":"Mistralys","description":"PHP and Javascript localization library","archived":false,"fork":false,"pushed_at":"2024-10-23T05:39:12.000Z","size":318,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-12T07:08:03.883Z","etag":null,"topics":["clientside-javascript","i18n","internationalization","language","library","localization","php","translation","translator-app","user-interface"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mistralys.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-09-30T08:58:54.000Z","updated_at":"2024-10-22T14:16:38.000Z","dependencies_parsed_at":"2022-08-22T11:31:16.360Z","dependency_job_id":null,"html_url":"https://github.com/Mistralys/application-localization","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mistralys%2Fapplication-localization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mistralys%2Fapplication-localization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mistralys%2Fapplication-localization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mistralys%2Fapplication-localization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mistralys","download_url":"https://codeload.github.com/Mistralys/application-localization/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249038887,"owners_count":21202803,"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":["clientside-javascript","i18n","internationalization","language","library","localization","php","translation","translator-app","user-interface"],"created_at":"2025-01-22T18:14:38.720Z","updated_at":"2025-04-15T08:42:13.725Z","avatar_url":"https://github.com/Mistralys.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Application Localization\n\nPHP and JavaScript localization library, written in PHP. It is a simple but powerful\nlocalization layer that stores translated strings in ini files.\n\n## Highlights\n\n* Easy to adjust to an application's file structure\n* Automatic discovery of texts in PHP and JavaScript source files\n* Built-in translator UI that can be integrated into an existing UI\n* Clientside translations with auto-generated include files\n* Translations with or without translation context information for translators\n\n## Installation\n\nRequire the package via composer:\n\n```\ncomposer require mistralys/application-localization\n```\n\nAlso see the [Packagist page][].\n\n## Configuration\n\n### 1) Adding locales\n\nThe native application locale should be english. Any additional locales can be added like this:\n\n```php\nuse AppLocalize\\Localization;\n\nLocalization::addAppLocale('de_DE');\nLocalization::addAppLocale('fr_FR');\n````\n\n\u003e Note: The package has not been tested with non-latin scripts, like Sinic \n\u003e (Chinese, Japanese, Korean, Vietnamese) or Brahmic (Indian, Tibetan, Thai, Lao).\n\n### 2) Adding file source folders\n\nThis defines in which folders to search for PHP or Javascript files. These files will be \nanalyzed to find all places where there are translation function calls. \n\nRegister each folder to look in like this: \n\n```php\nuse AppLocalize\\Localization;\n\n$source = Localization::addSourceFolder(\n    'source-slug', // Must be unique: used in file names and to access the source programmatically\n    'Source label', // Human readable label\n    'Group label', // Group labels are used to group sources in the UI\n    '/path/to/ini/files/', // The localization files will be stored here\n    '/path/to/source/files/' // The PHP and JavaScript source files to search through are here\n);\n```\n\n#### Excluding files and folders\n\nFor performance reasons, it is recommended to exclude any files or folders that do not \nneed to be analyzed. The Javascript analysis in particular still has issues with minified \nlibrary files like jQuery or Bootstrap, so they should definitely be excluded.\n\nTo exclude folders or files by name:\n\n```php\n$source-\u003eexcludeFolder('foldername');\n$source-\u003eexcludeFile('jquery'); // any file with \"jquery\" in its name\n$source-\u003eexcludeFile('jquery-ui.min.js'); // by exact file name match\n```\n\n\u003e Note: No need to specify the absolute path or file name, as long as the name is unique.\n\n### 3) Main configuration settings\n\n\u003e Note: This must be done last, after the locales and sources have been defined.\n\n```php\nuse AppLocalize\\Localization;\n\nLocalization::configure(\n    '/path/to/analysis/cache.json', // Where the text information cache may be saved\n    '/path/to/javascript/includes/' // Where the clientside files should be stored (Optional)\n);\n```\n\nIf no path is specified for the clientside includes, they will be disabled.\n\n### 4) Select the target locale\n\nThe locale is english by default, and you can switch the locale anytime using this:\n\n```php\nuse AppLocalize\\Localization;\n\nLocalization::selectAppLocale('de_DE');\n```\n\n\u003e Note: Your application logic must handle the decision of which locale to use.\n\n### 5) Include the client libraries (optional)\n\nThe localization library automatically creates the necessary javascript include files\nin the folder you specified in step 3). In your application, include the following \nfiles to enable the translation functions:\n\n* `locale-xx.js`\n* `md5.min.js`\n* `translator.js`\n\nWhere `xx` is the two-letter ISO code of the target language. There will be one for \neach of the locales you added.\n\n\u003e Once the javascript include files have been written, they are only refreshed \n\u003e whenever texts are updated in the localization editor UI. We recommend using\n\u003e a cache key (see below).\n\n#### Using a cache key to update libraries \n\nThe libraries cache key is an arbitrary string that can be set. Whenever this changes, the \njavascript include files are refreshed automatically. A good way to keep them up to date \nis to use your application's version number as cache key.\n\n```php\n$myAppVersion = 'v1.5.1';\n\nLocalization::setClientLibrariesCacheKey($myAppVersion);\n```\n\nRefreshing the libraries is then done automatically with each release of your application.\n\n## Using the translation functions\n\n### Serverside setup\n\nTo use the translation functions, you have to add use statements for those you need: \n\n```php\nuse function AppLocalize\\t;\nuse function AppLocalize\\pt;\nuse function AppLocalize\\pts;\nuse function AppLocalize\\tex;\nuse function AppLocalize\\ptex;\nuse function AppLocalize\\ptexs;\n```\n\n### The `t()` function\n\nBe it serverside or clientside, you may use the `t()` function to have texts automatically \ntranslated to the target locale. Simply wrap any of the native english texts in the \nfunction call.\n\nPHP:\n```php\n$text = t('Text to translate here');\n```\n\nJavaScript:\n```javascript\nvar text = t('Text to translate here');\n```\n\n### The `pt()` and `pts()` functions\n\n\u003e Note: This is only available serverside.\n\nThese are the same as `t()`, except that they echo the translated string. This is \nhandy for templates for example:\n\n```php\n\u003ctitle\u003e\u003c?php pt('Page title') ?\u003e\u003c/title\u003e\n```\n\nThe `pts()` function adds a space after the translated string, so that you do not have \nto manually add spaces when chaining several strings:\n\n```php\n\u003cdiv\u003e\n    \u003c?php\n        pts('First sentence here.');\n        pts('Second sentence here.');\n    ?\u003e\n\u003c/div\u003e   \n```\n\n### Using placeholders\n\nThe translation functions accept any number of additional parameters, which are injected \ninto the translated string using the [sprintf][] PHP function. This means you can use \nplaceholders like this:\n\n```php\n$amount = 50;\n$text = t('We found %1$s entries.', $amount);\n```\n\nClientside, you may use the same syntax:\n\n```javascript\nvar amount = 50;\nvar text = t('We found %1$s entries.', amount);\n```\n\n\u003e When using placeholders, we recommend systematically using numbered placeholders\n\u003e like `%1$s` or `%02d`. Primarily because the order of placeholders often changes \n\u003e in translated texts, but also to avoid confusion for whoever does the translating.\n\n### Providing translation context information\n\nIn some cases, knowing in which context a text is used will be critical to correctly\ntranslate it. The context flavored translation functions offer a second parameter\ndedicated to adding this context information.\n\n- `t()` -\u003e `tex()`\n- `pt()` -\u003e `ptex()`\n- `pts()` -\u003e `ptexs()`\n\n```php\nuse function AppLocalize\\ptex;\n\n// Context information comes directly after the text.\nptex(\n    'Text to translate', \n    'Context explanation for translators.'\n);\n\n// Placeholder values come after the context information.\nptex(\n    '%1$s records', \n    'The placeholder contains the amount of records.', \n    42\n);\n```\n\nThe context text must be a string, just like the text to translate.\nLinebreaks and string concatenation are allowed, but no variables or functions,\nsince this extracted offline, instead of being evaluated at runtime.\n\n\u003e Hint: It is possible to use basic HTML tags for formatting.\n\n## Tips \u0026 best practices\n\n### Split sentences\n\nThe number of translatable texts in a typical application can grow very quickly. \nWhenever possible, try to split the texts into manageable chunks by splitting longer \ntexts into smaller sentences. This has the added benefit of being able to reuse some \nof these text chunks in other places.\n\n### Use numbered placeholders\n\nEven if the syntax is more cumbersome than a simple `%s`, using numbered placeholders \nis critical to allow for different sentence structures depending on the language. \nA placeholder placed at the end of a sentence may have to be moved to the beginning \nof the text in another language. Using numbered placeholders makes this easy.\n\n\u003e Note: placeholders are highlighted in the localization UI, so that complex texts stay readable.\n\n### Put HTML tags in placeholders\n\nWhile tags like `\u003cstrong\u003e` or `\u003cem\u003e` are harmless choices to include in texts to \ntranslate, it should still be avoided. HTML is in the layout domain, and on \nprinciple should not be handled by translators.\n\nSo ideally, a text with markup should look like this:\n\n```php\nuse function AppLocalize\\t;\n\n$text = t('This is %1$sbold%2$s text.', '\u003cstrong\u003e', '\u003c/strong\u003e');\n```\n\nThis way, the application can decide not only which tag to use, but also add classes \nto it if needed in the future - without having to touch any of the translated texts.\n\nSame procedure for text links for example:\n\n```php\nuse function AppLocalize\\t;\n\n$textWithLink = t(\n    'Please refer to the %1$sdocumentation%2$s for further details.',\n    '\u003ca href=\"http://...\"\u003e',\n    '\u003c/a\u003e'\n);\n```\n\n### Template texts\n\nTo use a translated text as a template to re-use multiple times, simply replace \nthe placeholders with placeholders.\n\nSounds strange? Look at this example:\n\n```php\nuse function AppLocalize\\t;\n\n$template = t('Entry number %1$s', '%1$s');\n```\n\nTranslated to german, the text in the variable `$template` would look like this:\n\n```\nEintrag Nummer %1$s\n```\n\nThis means you can now use the template multiple times without calling the \ntranslation function each time, with the `sprintf` PHP function:\n\n```php\nfor($i=1; $i \u003c= 10; $i++)\n{\n    echo sprintf($template, $i);\n}\n```\n\n## Going further\n\nThe [Application Utils][] package has a string builder class used for concatenating \nstrings, and which supports this package out of the box. Building complex sentences \nis easy with this, including in an HTML context.\n\nExample:\n\n```php\nuse function AppUtils\\sb;\n\n$html = (string)sb()\n  -\u003ebold(t('Easy string concatenation'))\n  -\u003enl()\n  -\u003et('For more information, see here:')\n  -\u003elink(t('Application Utils'), 'https://github.com/Mistralys/application-utils');\n```\n\n## Events\n\n### When the active locale is changed\n\nThe `LocaleChanged` event is triggered when a different locale is selected\nat runtime. It is possible to add a listener to this event, and react to\nlocale changes.\n\nHere is an example:\n\n```php\nuse AppLocalize\\Localization;\nuse AppLocalize\\Localization\\Event\\LocaleChanged;\n\nLocalization::onLocaleChanged(function(LocaleChanged $event) {\n    // do something\n});\n```\n\n## Countries and Currencies\n\nThe library comes with a collection of countries and currencies for the \nsupported locales. These allow accessing general information about countries\nand currencies, like names, symbols, and codes.\n\n### Countries\n\nTo work with countries, use the factory method:\n\n```php\nuse AppLocalize\\Localization;\nuse AppLocalize\\Localization_Country_ES;\n\n$countries = Localization::createCountries();\n\n// Get a country by its two-letter ISO code\n$germany = $countries-\u003egetByISO('de');\n\n// Every country has a constant for its ISO code\n$spain = $countries-\u003egetByISO(Localization_Country_ES::ISO_CODE);\n\n// Or use the predefined list using choose():\n$france = $countries-\u003echoose()-\u003efr();\n```\n\n### Currencies\n\nTo work with currencies, use the factory method:\n\n```php\nuse AppLocalize\\Localization;\nuse AppLocalize\\Localization_Currency_EUR;\n\n$currencies = Localization::createCurrencies();\n\n// Get a currency by its three-letter ISO code\n$dollar = $currencies-\u003egetByISO('USD');\n\n// Every currency has a constant for its ISO code\n$euro = $currencies-\u003egetByISO(Localization_Currency_EUR::ISO_CODE);\n\n// Or use the predefined list using choose():\n$pound = $currencies-\u003echoose()-\u003egbp();\n```\n\n#### Country-specific currencies\n\nWhen getting a currency from a country, the currency offers formatting\nfeatures that are adjusted to the country's preferences.\n\n```php\nuse AppLocalize\\Localization;\n\n$eurDE = Localization::createCountries()\n    -\u003echoose()\n    -\u003ede()\n    -\u003egetCurrency();\n\necho $eurDE-\u003emakeReadable(1445.42);\n```\n\nThis will output:\n\n```\n1.445,42 €\n```\n\n## Examples\n\nTo run the example editor UI, simply run a `composer update` in the package folder, \nand open the `example` folder in your browser (provided the package is in your \nwebserver's webroot). \n\n## Origins\n\nThere are other localization libraries out there, but this was historically integrated \nin several applications. It has been moved to a separate package to make maintaining \nit easier. It has no pretension of rivalry with any of the established i18n libraries.\n\n\n\n[Packagist page]: https://packagist.org/packages/mistralys/application-localization\n[sprintf]: https://www.php.net/manual/en/function.sprintf.php\n[Application Utils]: https://github.com/Mistralys/application-utils\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmistralys%2Fapplication-localization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmistralys%2Fapplication-localization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmistralys%2Fapplication-localization/lists"}