{"id":22031405,"url":"https://github.com/omaralalwi/lexi-translate","last_synced_at":"2025-05-07T12:23:04.800Z","repository":{"id":263089565,"uuid":"889324466","full_name":"omaralalwi/lexi-translate","owner":"omaralalwi","description":"simplify managing translations for multilingual Eloquent models with power of morph relationships and caching .","archived":false,"fork":false,"pushed_at":"2025-03-21T22:47:31.000Z","size":1088,"stargazers_count":44,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-31T10:01:38.343Z","etag":null,"topics":["eloquent-translation","i18n","language-selector","laravel-localization","laravel-translations","lexi-translate","locales","localization","many-languages","multi-region","multilanguage","multilingual","omaralalwi","ranslator","text-localization","translate","translated-attributes","translation-management","translations"],"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/omaralalwi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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}},"created_at":"2024-11-16T04:37:37.000Z","updated_at":"2025-03-27T12:45:41.000Z","dependencies_parsed_at":"2024-11-16T08:00:21.516Z","dependency_job_id":"a4b77d13-f5f2-4024-bb05-e07b9abaa396","html_url":"https://github.com/omaralalwi/lexi-translate","commit_stats":null,"previous_names":["omaralalwi/lexi-translate"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omaralalwi%2Flexi-translate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omaralalwi%2Flexi-translate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omaralalwi%2Flexi-translate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omaralalwi%2Flexi-translate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omaralalwi","download_url":"https://codeload.github.com/omaralalwi/lexi-translate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252874556,"owners_count":21817850,"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":["eloquent-translation","i18n","language-selector","laravel-localization","laravel-translations","lexi-translate","locales","localization","many-languages","multi-region","multilanguage","multilingual","omaralalwi","ranslator","text-localization","translate","translated-attributes","translation-management","translations"],"created_at":"2024-11-30T08:17:06.630Z","updated_at":"2025-05-07T12:23:04.778Z","avatar_url":"https://github.com/omaralalwi.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lexi Translate\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://omaralalwi.github.io/lexi-translate\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/lexi-translate/master/public/images/lexi-translate-banner.jpg\" alt=\"lexi translate banner\" width=\"600\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nEasily manage translations for multilingual Eloquent models using morph relationships and caching.\n\nIts lightweight design and flexibility make it an excellent choice for applications needing multi-language support with minimal performance overhead.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Defining LexiTranslatable Models](#defining-lexitranslatable-models)\n  - [update or Create Translations](#update-or-Create-translations)\n  - [Retrieving Translations](#retrieving-translations)\n  - [More Examples](#more-examples)\n  - [Helper Functions](#helper-functions)\n  - [Usage in Queries](#Usage-in-Queries)\n  - [Cache Handling](#cache-handling)\n  - [Using middlewares](#using-middlewares-for-locale-management)\n- [Testing](#testing)\n- [Alternative Solutions](#alternative-solutions)\n- [Changelog](#changelog)\n- [Contributing](#contributing)\n- [Features](#features)\n- [Security](#security)\n- [License](#license)\n- [Contributors](#contributors)\n- [Helpful Packages](#helpful-open-source-packages)\n\n## Installation\n\nYou can install the package via Composer:\n\n```bash\ncomposer require omaralalwi/lexi-translate\n```\n\n### Publishing Configuration File\n\n```bash\nphp artisan vendor:publish --tag=lexi-translate\n```\n\nupdate table name (if you need, before migration) or any thing in config file if you need .\n\n### Publishing Migration File (optional)\n\n```bash\nphp artisan vendor:publish --tag=lexi-migrations\n```\n\n### Migration for `translations` Table\n\nRun the following command to create the `translations` table:\n\n```bash\nphp artisan migrate\n```\n\n## Usage\n\n### Defining LexiTranslatable Models\n\nTo use the package, include the `LexiTranslatable` trait in your Eloquent models, and add translated attributes in `$translatableFields` array:\n\n```php\nnamespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Omaralalwi\\LexiTranslate\\Traits\\LexiTranslatable;\n\nclass Post extends Model\n{\n    use LexiTranslatable;\n\n    protected $translatableFields = ['title', 'description'];\n}\n```\n\n### Update or Create Translations\n\nYou can use `setTranslations` method to create or update bulk translations for a model in a single step:\n\n```php\n$post = Post::find(1);\n// must same following format\n$post-\u003esetTranslations([\n    'ar' =\u003e [\n        'name' =\u003e 'العنوان باللغة العربية',\n        'description' =\u003e 'الوصف باللغة العربية',\n    ],\n\n    'en' =\u003e [\n        'name' =\u003e 'English language Title',\n        'description' =\u003e 'description in English language',\n    ],\n]);\n\n```\n\nOR You can use `setTranslation` method to create or update one translation for a model in a single step:\n\n```php\n$post-\u003esetTranslation('title', 'en', 'English Language Title');\n$post-\u003esetTranslation('description', 'en', 'English Language description');\n\n$post-\u003esetTranslation('title', 'ar', 'عنوان باللغة العربية');\n$post-\u003esetTranslation('description', 'ar', 'وصف باللغة العربية');\n```\n\n**Note** you can add translated `name` and `description` for `Post` model even if `Post` model did not has (`name` and `description`) attributes .\n\n### Retrieving Translations\n\n**Important Note:** To get better performance , **Do Not Depend on `translations`** relation directly when return translations, because it did not use cache Never.\nit did not use cache to keep it return `MorphMany` relation , it Return fresh translations from DB , So you can depend on it to create and update translations .\n\n**To retrieve translations, simply use `transAttr` method :**\n\nBy default it return default app local, else you can specify local.\n\n```php\n// get title and description in default app local\n$title = $post-\u003etransAttr('title');\n$title = $post-\u003etransAttr('description');\n\n// or get title and description in specific local\n$titleInArabic = $post-\u003etransAttr('title', 'ar');\n$titleInEnglish = $post-\u003etransAttr('title', 'ar');\n```\n\n### More Examples\n\nyou can find more detail examples in **[Examples File](examples.md)** .\n\n### Helper Functions\n\nyou can use `lexi_locales` to get supported locals as array, depend on `supported_Locales` in config file.\n\n### Usage in Queries\n\nit is easy to use the `scopeSearchByTranslation` and `scopeFilterByTranslation` methods:\n\n#### search by Translated attribute\n\n```php\n$posts = Post::searchByTranslation('title', 'keyword')-\u003eget();\n```\n\n####  Specify Locale\n\n```php\n$posts = Post::searchByTranslation('title', 'keyword', 'ar')-\u003eget();\n```\n\n#### Filter Posts by Exact Translated Description\n\n```php\n$posts = Post::filterByTranslation('description', 'Specific Translated Text')-\u003eget();\n```\n\n\n### Cache Handling\n\n**Disable Cache**:\n\nby default the cache enabled, you can disable it  by make `use_cache` = false , in `config/lexi-translate.php` file\n\n**Cache Management**:\n\nLexi Translate automatically caches translations to boost performance.\nAlso Cache is cleared automatically when translations are updated or deleted by `booted` function in `Translation` model .\n\n**Clear Model Cache Manually**:\n\nIf you need to manually clear the cache, you can do so `$model-\u003eclearTranslationsCache()` for ex :\n\n```php\n$post-\u003eclearTranslationsCache();\n```\n\n---\n**Note**:\n\nPlease note that the `supported_Locales` setting in the configuration file defines the locales that will be handled by the cache by default.\nIf you add additional locales for translations, make sure to include them in the `supported_Locales` list to ensure proper cache handling. Failing to do so may result in cache issues for locales not added to the list.\n\n---\n\n### Using Middlewares for Locale Management\n\n**(this is Optional)**\n\n**This section is optional , it is additional features to handle language switching for API Or Web , without need to install another package .**\n\nLexiTranslate provides built-in middlewares to handle locale switching seamlessly for both web and API requests. \nThese middlewares simplify the process of dynamically setting the application's locale based on user input or request headers.\n\n\n#### **1 . WebLocalized Middleware**\n\nThe `WebLocalized` middleware is designed to handle locale switching for web requests. It determines the locale based on the following order of priority:\n- The `locale` route parameter.\n- The `locale` query string parameter.\n- The current session's locale.\n- The `locale` stored in cookies.\n- The application's default locale.\n\n#### Registering the Middleware\n\n```php\n// Other middlewares...\n'localized.web' =\u003e \\Omaralalwi\\LexiTranslate\\Middleware\\WebLocalized::class,\n```\n[Register Middleware in Laravel](https://laravel.com/docs/11.x/middleware#registering-middleware)\n\n#### Applying the Middleware to Routes\n\njust add `locale` prefix for all routes that want to apply multilingual for them .\n\n```php\nRoute::prefix('{locale}')-\u003emiddleware('localized.web')-\u003egroup(function () {\n     // your routes\n});\n```\nOR\n```php\nRoute::middleware(['localized.web'])-\u003egroup(function () {\n    Route::get('/{locale}/dashboard', function () {\n        return view('dashboard');\n    });\n});\n```\n\n#### **2. ApiLocalized Middleware**\n\nThe `ApiLocalized` middleware is designed for API requests. It sets the application's locale based on the value of a custom header defined in your configuration file (`api_locale_header_key`). If the header is not provided, it defaults to the application's default locale.\n\n#### Registering the Middleware\n\n```php\n // Other middlewares...\n'localized.api' =\u003e \\Omaralalwi\\LexiTranslate\\Middleware\\WebLocalized::class,\n```\n\n#### Applying the Middleware to API Routes\n\n```php\nRoute::middleware(['localized.api'])-\u003egroup(function () {\n        // your routes\n});\n```\n\n---\n\n## Features\n\n- **Dynamic Morph Relationships:** Manage translations across different models with ease, thanks to its dynamic morph able relationships.\n- **Automatic Caching:** Enjoy enhanced performance as translations are automatically cached and invalidated, ensuring quick access and updates.\n- **Fallback Mechanism:** Never worry about missing translations—Lexi Translate falls back to the default language if a translation is not available.\n- **Simple, Intuitive API:** A clean and consistent API for adding, retrieving, and managing translations.\n- **Eloquent-Friendly:** Seamlessly integrates with Laravel's Eloquent ORM, making it easy to work with translated data while maintaining the power of Laravel’s query builder.\n-  **Search and Filter:** Scopes for search and filters by translations .\n- **Built-in middlewares** to handle locale switching seamlessly for both web and API requests.\n- **Feature Tests:** supported with Feature Tests .\n- **Customize table name:** in config file you can change `table_name` to any name as you want.\n\n## Testing\n\nTo run the tests for this package:\n\n```bash\ncomposer test\n```\n\n---\n\n## Alternative Solutions\n\nIf Lexi Translate doesn't fully meet your application's needs, you may also consider these popular alternatives:\n\n- **[Spatie Laravel Translatable](https://github.com/spatie/laravel-translatable):**  \n  Stores translations in a JSON column within the main table. Best suited for smaller applications with simple multilingual requirements.\n\n- **[Astrotomic Laravel Translatable](https://github.com/Astrotomic/laravel-translatable):**  \n  Similar to Spatie's package but includes additional features like better locale handling. It’s an excellent choice for lightweight multilingual support.\n\nBoth packages offer robust solutions for managing translations but rely on JSON-based storage. If you require scalable, relational storage with built-in caching and dynamic morph relationships, **Lexi Translate** is the better choice for large-scale or performance-critical applications.\n\n--- \n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on recent updates.\n\n## Contributing\n\nWe welcome contributions! If you'd like to contribute, please check the [CONTRIBUTING](CONTRIBUTING.md) guide for details.\n\n### Contributors\n\nThis project exists thanks to all the people who contribute.\n\n- [Omar alalwi](https://github.com/omaralalwi)\n\n## Security\n\nIf you discover any security-related issues, please email [omaralwi2010@gmail.com](mailto:omaralwi2010@gmail.com) instead of using the issue tracker.\n\n## License\n\nThe MIT License (MIT). Please see the [License File](LICENSE.md) for more information.\n\n---\n\n## Contributors ✨\n\nThanks to these wonderful people for contributing to this project! 💖\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003ca href=\"https://github.com/omaralalwi\"\u003e\n        \u003cimg src=\"https://avatars.githubusercontent.com/u/25439498?v=4\" width=\"100px;\" alt=\"Omar Al Alwi\"/\u003e\n        \u003cbr /\u003e\n        \u003csub\u003e\u003cb\u003eOmar Al Alwi\u003c/b\u003e\u003c/sub\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      🏆 Owner\n    \u003c/td\u003e\n    \u003c!-- Contributors --\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003ca href=\"https://github.com/HamzaHassanM\"\u003e\n        \u003cimg src=\"https://avatars.githubusercontent.com/u/62448602?v=4\" width=\"100px;\" alt=\"Contributor Name\"/\u003e\n        \u003cbr /\u003e\n        \u003csub\u003e\u003cb\u003eHamza Hasan\u003c/b\u003e\u003c/sub\u003e\n      \u003c/a\u003e\n      \u003cbr /\u003e\n      💻 Contributor\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nWant to contribute? Check out the [contributing guidelines](./CONTRIBUTING.md) and submit a pull request! 🚀\n\n---\n\n## Helpful Open Source Packages\n\n- \u003ca href=\"https://github.com/omaralalwi/Gpdf\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/Gpdf/master/public/images/gpdf-banner-bg.jpg\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"laravel Taxify\" /\u003e Gpdf \u003c/a\u003e Open Source HTML to PDF converter for PHP \u0026 Laravel Applications, supports Arabic content out-of-the-box and other languages..\n\n- \u003ca href=\"https://github.com/omaralalwi/laravel-taxify\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/laravel-taxify/master/public/images/taxify.jpg\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"laravel Taxify\" /\u003e **laravel Taxify** \u003c/a\u003e Laravel Taxify provides a set of helper functions and classes to simplify tax (VAT) calculations within Laravel applications.\n\n- \u003ca href=\"https://github.com/omaralalwi/laravel-deployer\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/laravel-deployer/master/public/images/deployer.jpg\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"laravel Deployer\" /\u003e **laravel Deployer** \u003c/a\u003e Streamlined Deployment for Laravel and Node.js apps, with Zero-Downtime and various environments and branches.\n\n- \u003ca href=\"https://github.com/omaralalwi/laravel-trash-cleaner\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/laravel-trash-cleaner/master/public/images/laravel-trash-cleaner.jpg\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"laravel Trash Cleaner\" /\u003e **laravel Trash Cleaner** \u003c/a\u003eclean logs and debug files for debugging packages.\n\n- \u003ca href=\"https://github.com/omaralalwi/laravel-time-craft\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/laravel-time-craft/master/public/images/laravel-time-craft.jpg\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"laravel Trash Cleaner\" /\u003e **laravel Time Craft** \u003c/a\u003esimple trait and helper functions that allow you, Effortlessly manage date and time queries in Laravel apps.\n\n- \u003ca href=\"https://github.com/omaralalwi/laravel-startkit\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/omaralalwi/laravel-startkit/master/public/screenshots/backend-rtl.png\" width=\"26\" height=\"26\" style=\"border-radius:13px;\" alt=\"Laravel Startkit\" /\u003e **Laravel Startkit** \u003c/a\u003e  Laravel Admin Dashboard, Admin Template with Frontend Template, for scalable Laravel projects.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomaralalwi%2Flexi-translate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomaralalwi%2Flexi-translate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomaralalwi%2Flexi-translate/lists"}