PHPackages                             subhash/translation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. subhash/translation

ActiveLibrary[Localization &amp; i18n](/categories/localization)

subhash/translation
===================

A Translation package for Laravel 10 with database and cache support

2.5.1(2y ago)0339↓100%MITPHPPHP ^8.1

Since Apr 4Pushed 2y agoCompare

[ Source](https://github.com/Subhash2053/translation)[ Packagist](https://packagist.org/packages/subhash/translation)[ RSS](/packages/subhash-translation/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (5)Versions (2)Used By (0)

Better localization management for Laravel
==========================================

[](#better-localization-management-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/679262b869562b2d5555e785ee8e483605b589aeeac2efcc8033a5a7d2575a21/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f77616176692f7472616e736c6174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/waavi/translation)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Build Status](https://camo.githubusercontent.com/c51cda3d63edf265d1daaa79807a1a69bcee0fbd73d9e2d0919b917996e69f7e/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f57616176692f7472616e736c6174696f6e2f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/Waavi/translation)[![Total Downloads](https://camo.githubusercontent.com/2127d1092c00e250e199d2965442c55611e9a9e1566097565ab0c7db7d487204/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f77616176692f7472616e736c6174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/waavi/translation)

Introduction
------------

[](#introduction)

Keeping a project's translations properly updated is cumbersome. Usually translators do not have access to the codebase, and even when they do it's hard to keep track of which translations are missing for each language or when updates to the original text require that translations be revised.

This package allows developers to leverage their database and cache to manage multilanguage sites, while still working on language files during development and benefiting from all the features Laravel's Translation bundle has, like pluralization or replacement.

WAAVI is a web development studio based in Madrid, Spain. You can learn more about us at [waavi.com](http://waavi.com)

Table of contents
-----------------

[](#table-of-contents)

- [Laravel compatibility](#laravel-compatibility)
- [Features overview](#features-overview)
- [Installation](#installation)
- [Set source for translations](#translations-source)
    - [Load translations from files](#load-translations-from-files)
    - [Load translations from the database](#load-translations-from-the-database)
    - [Mixed mode](#mixed-mode)
    - [Loading your files into the database](#loading-your-files-into-the-database)
- [Cache translations](#cache-translations)
- [Managing languages and translations in the Database](#managing-languages-and-translations-in-the-database)
    - [Managing Languages](#managing-languages)
    - [Managing Translations](#managing-translations)
- [Model attributes translation](#model-attributes-translation)
- [Uri localization](#uri-localization)

Laravel compatibility
---------------------

[](#laravel-compatibility)

Laraveltranslation4.x1.0.x5.0.x2.0.x5.1.x|5.3.x2.1.x5.4.x2.2.x5.5.x2.3.x and higher5.6.x2.3.x and higher6.x|7.x2.4.x and higher10.x2.5.x and higherFeatures overview
-----------------

[](#features-overview)

- Allow dynamic changes to the site's text and translations.
- Cache your localization entries.
- Load your translation files into the database.
- Force your urls to be localized (ex: /home -&gt; /es/home) and set the locale automatically through the browser's config.
- Localize your model attributes.

Installation
------------

[](#installation)

Require through composer

```
composer require waavi/translation 2.4.x

```

Or manually edit your composer.json file:

```
"require": {
	"waavi/translation": "2.4.x"
}

```

Once installed, in your project's config/app.php file replace the following entry from the providers array:

```
Illuminate\Translation\TranslationServiceProvider::class

```

with:

```
Waavi\Translation\TranslationServiceProvider::class

```

Remove your config cache:

```
php artisan config:clear

```

Publish both the configuration file and the migrations:

```
php artisan vendor:publish --provider="Waavi\Translation\TranslationServiceProvider"

```

Execute the database migrations:

```
php artisan migrate

```

You may check the package's configuration file at:

```
config/translator.php

```

Translations source
-------------------

[](#translations-source)

This package allows you to load translation from the regular Laravel localization files (in /resources/lang), from the database, from cache or in a mix of the previous for development. You may configure the desired mode of operation through the translator.php config file and/or the TRANSLATION\_SOURCE environment variable. Accepted values are:

- 'files' To load translations from Laravel's language files (default)
- 'database' To load translations from the database
- 'mixed' To load translations both from the filesystem and the database, with the filesystem having priority.
- 'mixed\_db' To load translations both from the filesystem and the database, with the database having priority. \[v2.1.5.3\]

NOTE: When adding the package to an existing Laravel project, 'files' must be used until migrations have been executed.

For cache configuration, please go to [cache configuration](#cache-translations)

### Load translations from files

[](#load-translations-from-files)

If you do not wish to leverage your database for translations, you may choose to load language lines exclusively through language files. This mode differs from Laravel in that, in case a line is not found in the specified locale, instead of returning the key right away, we first check the default language for an entry. In case you wish to use this mode exclusively, you will need to set the 'available\_locales' config file:

```
config/translator.php
	'available_locales' => ['en', 'es', 'fr'],

```

Example:

The content in en/validations.php, where 'en' is the default locale, is:

```
		[
			'missing_name'			=>	'Name is missing',
			'missing_surname'		=>	'Surname is missing',
		];
```

The content in es/validations.php is:

```
		[
			'missing_name'			=>	'Falta el nombre',
		];
```

Output for different keys with 'es' locale:

```
		trans('validations.missing_name'); 		// 		'Falta el nombre'
		trans('validations.missing_surname'); 	// 		'Surname is missing'
		trans('validations.missing_email'); 	// 		'validations.missing_email'
```

### Load translations from the database

[](#load-translations-from-the-database)

You may choose to load translations exclusively from the database. This is very useful if you intend to allow users or administrators to live edit the site's text and translations. In a live production environment, you will usually want this source mode to be activated with the translation's cache. Please see [Loading your files into the database](#loading-your-files-into-the-database) for details on the steps required to use this source mode.

Example:

The content in the languages table is:

```
	| id | locale | name    |
	-------------------------
	| 1  | en     | english |
	| 2  | es     | spanish |

```

The relevant content in the language\_entries table is:

```
	| id | locale | namespace | group       | item	          | text                    |
	-------------------------------------------------------------------------------------
	| 1  | en     | *         | validations | missing.name    | Name is missing         |
	| 2  | en     | *         | validations | missing.surname | Surname is missing      |
	| 3  | en     | *         | validations | min_number      | Number is too small     |
	| 4  | es     | *         | validations | missing.name    | Falta nombre   			|
	| 5  | es     | *         | validations | missing.surname | Falta apellido 			|

```

Output for different keys with es locale:

```
		trans('validations.missing.name');   //    'Falta nombre'
		trans('validations.min_number');     //    'Number is too small'
		trans('validations.missing.email');  //    'missing_email'
```

### Mixed mode

[](#mixed-mode)

In mixed mode, both the language files and the database are queried when looking for a group of language lines. Entries found in the filesystem take precedence over the database. This source mode is useful when in development, so that both the filesystem and the user entries are taken into consideration.

Example:

```
When files and database are set like in the previous examples:

```

```
		trans('validations.missing_name');     //    'Falta el nombre'
		trans('validations.missing_surname');  //    'Falta apellido'
		trans('validations.min_number');       //    'Number is too small'
		trans('validations.missing_email');    //    'missing_email'
```

### Loading your files into the database

[](#loading-your-files-into-the-database)

When using either the database or mixed translation sources, you will need to first load your translations into the database. To do so, follow these steps:

- Run the migrations detailed in the installation instructions.
- Add your languages of choice to the database (see [Managing Database Languages](#managing-database-languages))
- Load your language files into the database using the provided Artisan command:

    `php artisan translator:load`

When executing the artisan command, the following will happen:

- Non existing entries will be created.
- Existing entries will be updated **except if they're locked**. When allowing users to live edit the translations, it is recommended you do it throught the updateAndLock method provided in the [Translations repository](#managing-translations). This prevents entries being overwritten when reloading translations from files.
- When an entry in the default locale is edited, all of its translations will be flagged as **pending review**. This gives translators the oportunity to review translations that might not be correct, but doesn't delete them so as to avoid minor errata changes in the source text from erasing all translations. See [Managing translations](#managing-translations) for details on how to work with unstable translations.

Both vendor files and subdirectories are supported. Please keep in mind that when loading an entry inside a subdirectory, Laravel 5 has changed the syntax to:

```
	trans('subdir/file.entry')
	trans('package::subdir/file.entry')
```

Cache translations
------------------

[](#cache-translations)

Since querying the database everytime a language group must be loaded is grossly inefficient, you may choose to leverage Laravel's cache system. This module will use the same cache configuration as defined by you in app/config/cache.php.

You may enable or disable the cache through the translator.php config file or the 'TRANSLATION\_CACHE\_ENABLED' environment variable. Config options are:

Env keytypedescriptionTRANSLATION\_CACHE\_ENABLEDbooleanEnable / disable the translations cacheTRANSLATION\_CACHE\_TIMEOUTintegerMinutes translation items should be kept in the cache.TRANSLATION\_CACHE\_SUFFIXstringDefault is 'translation'. This will be the cache suffix applied to all translation cache entries.### Cache tags

[](#cache-tags)

Available since version 2.1.3.8, if the cache store in use allows for tags, the TRANSLATION\_CACHE\_SUFFIX will be used as the common tag to all cache entries. This is recommended to be able to invalidate only the translation cache, or even just a given locale, namespace and group configuration.

### Clearing the cache

[](#clearing-the-cache)

Available since version 2.1.3.8, you may clear the translation cache through both an Artisan Command and a Facade. If cache tags are in use, only the translation cache will be cleared. All of your application cache will however be cleared if you cache tags are not available.

Cache flush command:

```
php artisan translator:flush

```

In order to access the translation cache, add to your config/app.php files, the following alias:

```
    'aliases'         => [
        /* ... */
        'TranslationCache' => \Waavi\Translation\Facades\TranslationCache::class,
    ]
```

Once done, you may clear the whole translation cache by calling:

```
    \TranslationCache::flushAll();
```

You may also choose to invalidate only a given locale, namespace and group combination.

```
    \TranslationCache::flush($locale, $group, $namespace);
```

- The locale is the language locale you wish to clear.
- The namespace is either '\*' for your application translation files, or 'package' for vendor translation files.
- The group variable is the path to the translation file you wish to clear.

For example, say we have the following file in our resources/lang directory: en/auth.php, en/auth/login.php and en/vendor/waavi/login.php. To clear the cache entries for each of them you would call:

```
    \TranslationCache::flush('en', 'auth', '*');
    \TranslationCache::flush('en', 'auth/login', '*');
    \TranslationCache::flush('en', 'login', 'waavi');
```

Managing languages and translations in the Database
---------------------------------------------------

[](#managing-languages-and-translations-in-the-database)

The recommended way of managing both languages and translations is through the provided repositories. You may circumvent this by saving changes directly through the Language and Translation models, however validation is no longer executed automatically on model save and could lead to instability and errors.

Both the Language and the Translation repositories provide the following methods:

MethodDescriptionhasTable();Returns true if the corresponding table exists in the database, false otherwiseall($related = \[\], $perPage = 0);Retrieve all records from the DB. A paginated record will be return if the second argument is &gt; 0, with $perPage items returned per pagefind($id);Find a record by idcreate($attributes);Validates the given attributes and inserts a new record. Returns false if validation errors occureddelete($id);Delete a record by idrestore($id);Restore a record by idcount();Return the total number of entriesvalidate(array $attributes);Checks if the given attributes are validvalidationErrors();Get validation errors for create and update methods### Managing Languages

[](#managing-languages)

Language management should be done through the **\\Waavi\\Translation\\Repositories\\LanguageRepository** to ensure proper data validation before inserts and updates. It is recommended that you instantiate this class through Dependency Injection.

A valid Language record requires both its name and locale to be unique. It is recommended you use the native name for each language (Ex: English, Español, Français)

The provided methods are:

MethodDescriptionupdate(array $attributes);Updates a Language entry \[id, name, locale\]trashed($related = \[\], $perPage = 0);Retrieve all trashed records from the DB.findTrashed($id, $related = \[\]);Find a trashed record by idfindByLocale($locale);Find a record by localefindTrashedByLocale($locale);Finds a trashed record by localeallExcept($locale);Returns a list of all languages excluding the given localeavailableLocales();Returns a list of all available localesisValidLocale($locale);Checks if a language exists with the given localepercentTranslated($locale);Returns the percent translated for the given locale### Managing Translations

[](#managing-translations)

Translation management should be done through the **\\Waavi\\Translation\\Repositories\\TranslationRepository** to ensure proper data validation before inserts and updates. It is recommended that you instantiate this class through Dependency Injection.

A valid translation entry cannot have the same locale and language code than another.

The provided methods are:

MethodDescriptionupdate($id, $text);Update an unlocked entryupdateAndLock($id, $text);Update and lock an entry (locked or not)allByLocale($locale, $perPage = 0);Get all by localeuntranslated($locale, $perPage = 0, $text = null);Get all untranslated entries. If $text is set, entries will be filtered by partial matches to translation value.pendingReview($locale, $perPage = 0);List all entries pending reviewsearch($locale, $term, $perPage = 0);Search by all entries by locale and a partial match to both the text value and the translation code.randomUntranslated($locale);Get a random untranslated entrytranslateText($text, $textLocale, $targetLocale);Translate text to another localeflagAsReviewed($id);Flag entry as reviewedThings to consider:

- You may lock translations so that they can only be updated through updateAndLock. The language file loader uses the update method and will not be able to override locked translations.
- When a text entry belonging to the default locale is updated, all of its siblings are marked as pending review.
- When deleting an entry, if it belongs to the default locale its translations will also be deleted.

Model attributes translation
----------------------------

[](#model-attributes-translation)

You can also use the translation management system to manage your model attributes translations. To do this, you only need to:

- Make sure either the database or mixed source are set.
- Make sure your models use the Waavi\\Translation\\Translatable\\Trait
- In your model, add a translatableAttributes array with the names of the attributes you wish to be available for translation.
- For every field you wish to translate, make sure there is a corresponding attributeName\_translation field in your database.

Example:

```
	\Schema::create('examples', function ($table) {
        $table->increments('id');
        $table->string('slug')->nullable();
        $table->string('title')->nullable();
        $table->string('title_translation')->nullable();
        $table->string('text')->nullable();
        $table->string('text_translation')->nullable();
        $table->timestamps();
    });

    class Example extends Model
	{
	    use \Waavi\Translation\Traits\Translatable;
	    protected $translatableAttributes = ['title', 'text'];
	}
```

Uri localization
----------------

[](#uri-localization)

You may use Waavi\\Translation\\Middleware\\TranslationMiddleware to make sure all of your urls are properly localized. The TranslationMiddleware will only redirect GET requests that do not have a locale in them.

For example, if a user visits the url /home, the following would happen:

- The middleware will check if a locale is present.
- If a valid locale is present:
    - it will globally set the language for that locale
    - the following data will be available in your views:
        - currentLanguage: current selected Language instance.
        - selectableLanguages: list of all languages the visitor can switch to (except the current one)
        - altLocalizedUrls: a list of all localized urls for the current resource except this one, formatted as \['locale' =&gt; 'en', 'name' =&gt; 'English', 'url' =&gt; '/en/home'\]
- If no locale is present:
    - Check the first two letters of the brower's accepted locale HTTP\_ACCEPT\_LANGUAGE (for example 'en-us' =&gt; 'en')
    - If this is a valid locale, redirect the visitor to that locale =&gt; /es/home
    - If not, redirect to default locale =&gt; /en/home
    - Redirects will keep input data in the url, if any

You may choose to activate this Middleware globally by adding the middleware to your App\\Http\\Kernel file:

```
	protected $middleware = [
		/* ... */
        \Waavi\Translation\Middleware\TranslationMiddleware::class,
    ]
```

Or to apply it selectively through the **'localize'** route middleware, which is already registered when installing the package through the ServiceProvider.

It is recommended you add the following alias to your config/app.php aliases:

```
	'aliases'         => [
		/* ... */
		'UriLocalizer'	=> Waavi\Translation\Facades\UriLocalizer::class,
    ];
```

Every localized route must be prefixed with the current locale:

```
	// If the middleware is globally applied:
	Route::group(['prefix' => \UriLocalizer::localeFromRequest()], function(){
		/* Your routes here */
	});

	// For selectively chosen routes:
	Route::group(['prefix' => \UriLocalizer::localeFromRequest(), 'middleware' => 'localize')], function () {
	    /* Your routes here */
	});
```

Starting on v2.1.6, you may also specify a custom position for the locale segment in your url. For example, if the locale info is the third segment in a URL (/api/v1/es/my\_resource), you may use:

```
    // For selectively chosen routes:
    Route::group(['prefix' => 'api/v1'], function() {
        /** ... Non localized urls here **/

        Route::group(['prefix' => \UriLocalizer::localeFromRequest(2), 'middleware' => 'localize:2')], function () {
            /* Your localized routes here */
        });
    });
```

In your views, for routes where the Middleware is active, you may present the user with a menu to switch from the current language to another by using the shared variables. For example:

```

    {{ $currentLanguage->name }}

        @foreach ($altLocalizedUrls as $alt)
            {{ $alt['name'] }}
        @endforeach

```

###  Health Score

27

—

LowBetter than 52% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 64.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1083d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6baf5f2428d1af9b27441b6c35b1136c0eed72f3786e44523fd697814c293761?d=identicon)[Subhash2053](/maintainers/Subhash2053)

---

Top Contributors

[![sildraug](https://avatars.githubusercontent.com/u/767887?v=4)](https://github.com/sildraug "sildraug (50 commits)")[![dylian94](https://avatars.githubusercontent.com/u/5433980?v=4)](https://github.com/dylian94 "dylian94 (4 commits)")[![al0mie](https://avatars.githubusercontent.com/u/5223895?v=4)](https://github.com/al0mie "al0mie (2 commits)")[![lysz210](https://avatars.githubusercontent.com/u/2990464?v=4)](https://github.com/lysz210 "lysz210 (2 commits)")[![makstech](https://avatars.githubusercontent.com/u/25028046?v=4)](https://github.com/makstech "makstech (2 commits)")[![michail1982](https://avatars.githubusercontent.com/u/326304?v=4)](https://github.com/michail1982 "michail1982 (2 commits)")[![subashgc](https://avatars.githubusercontent.com/u/187246366?v=4)](https://github.com/subashgc "subashgc (2 commits)")[![dmitryuk](https://avatars.githubusercontent.com/u/661654?v=4)](https://github.com/dmitryuk "dmitryuk (1 commits)")[![AlexRegenbogen](https://avatars.githubusercontent.com/u/242872?v=4)](https://github.com/AlexRegenbogen "AlexRegenbogen (1 commits)")[![saji89](https://avatars.githubusercontent.com/u/236861?v=4)](https://github.com/saji89 "saji89 (1 commits)")[![alexhouse](https://avatars.githubusercontent.com/u/2657291?v=4)](https://github.com/alexhouse "alexhouse (1 commits)")[![MarkRedeman](https://avatars.githubusercontent.com/u/1114829?v=4)](https://github.com/MarkRedeman "MarkRedeman (1 commits)")[![thku](https://avatars.githubusercontent.com/u/17138144?v=4)](https://github.com/thku "thku (1 commits)")[![MortezaPoussaneh](https://avatars.githubusercontent.com/u/49806042?v=4)](https://github.com/MortezaPoussaneh "MortezaPoussaneh (1 commits)")[![ngima](https://avatars.githubusercontent.com/u/23276565?v=4)](https://github.com/ngima "ngima (1 commits)")[![ockle](https://avatars.githubusercontent.com/u/2755069?v=4)](https://github.com/ockle "ockle (1 commits)")[![andersLAL](https://avatars.githubusercontent.com/u/25003890?v=4)](https://github.com/andersLAL "andersLAL (1 commits)")[![AymanElarian](https://avatars.githubusercontent.com/u/364872?v=4)](https://github.com/AymanElarian "AymanElarian (1 commits)")[![Balakir](https://avatars.githubusercontent.com/u/697735?v=4)](https://github.com/Balakir "Balakir (1 commits)")[![divdax](https://avatars.githubusercontent.com/u/1456739?v=4)](https://github.com/divdax "divdax (1 commits)")

---

Tags

laravellocalizationtranslationtranslatorlaravel-translatorwaavi

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/subhash-translation/health.svg)

```
[![Health](https://phpackages.com/badges/subhash-translation/health.svg)](https://phpackages.com/packages/subhash-translation)
```

###  Alternatives

[waavi/translation

A Translation package for Laravel 5 with database and cache support

367437.9k6](/packages/waavi-translation)[jayesh/laravel-gemini-translator

An interactive command to extract and generate Laravel translations using Gemini AI.

691.7k](/packages/jayesh-laravel-gemini-translator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
