Manage Laravel translation files

Last update: May 19, 2022

Laravel 5 Translation Manager

For Laravel 4, please use the 0.1 branch!

This is a package to manage Laravel translation files. It does not replace the Translation system, only import/export the php files to a database and make them editable through a webinterface. The workflow would be:

- Import translations: Read all translation files and save them in the database
- Find all translations in php/twig sources
- Optionally: Listen to missing translation with the custom Translator
- Translate all keys through the webinterface
- Export: Write all translations back to the translation files.

This way, translations can be saved in git history and no overhead is introduced in production.

Screenshot

Installation

Require this package in your composer.json and run composer update (or run composer require barryvdh/laravel-translation-manager directly):

composer require barryvdh/laravel-translation-manager

After updating composer, add the ServiceProvider to the providers array in config/app.php

'Barryvdh\TranslationManager\ManagerServiceProvider',

You need to run the migrations for this package.

$ php artisan vendor:publish --provider="Barryvdh\TranslationManager\ManagerServiceProvider" --tag=migrations
$ php artisan migrate

You need to publish the config file for this package. This will add the file config/translation-manager.php, where you can configure this package.

$ php artisan vendor:publish --provider="Barryvdh\TranslationManager\ManagerServiceProvider" --tag=config

In order to edit the default template, the views must be published as well. The views will then be placed in resources/views/vendor/translation-manager.

$ php artisan vendor:publish --provider="Barryvdh\TranslationManager\ManagerServiceProvider" --tag=views

Routes are added in the ServiceProvider. You can set the group parameters for the routes in the configuration. You can change the prefix or filter/middleware for the routes. If you want full customisation, you can extend the ServiceProvider and override the map() function.

This example will make the translation manager available at http://yourdomain.com/translations

If you would like to use auto translation using Google Translate API

php artisan vendor:publish --provider=Tanmuhittin\LaravelGoogleTranslate\LaravelGoogleTranslateServiceProvider

Edit config/laravel_google_translate.php and add your Google Translate API key.

php artisan config:cache

Now you can use Auto Translation Trait

Laravel >= 5.2

The configuration file by default only includes the auth middleware, but the latests changes in Laravel 5.2 makes it that session variables are only accessible when your route includes the web middleware. In order to make this package work on Laravel 5.2, you will have to change the route/middleware setting from the default

    'route' => [
        'prefix' => 'translations',
        'middleware' => 'auth',
    ],

to

    'route' => [
        'prefix' => 'translations',
        'middleware' => [
	        'web',
	        'auth',
		],
    ],

NOTE: This is only needed in Laravel 5.2 (and up!)

Usage

Web interface

When you have imported your translation (via buttons or command), you can view them in the webinterface (on the url you defined with the controller). You can click on a translation and an edit field will popup. Just click save and it is saved :) When a translation is not yet created in a different locale, you can also just edit it to create it.

Using the buttons on the webinterface, you can import/export the translations. For publishing translations, make sure your application can write to the language directory.

You can also use the commands below.

Import command

The import command will search through app/lang and load all strings in the database, so you can easily manage them.

$ php artisan translations:import

Translation strings from app/lang/locale.json files will be imported to the _json group.

Note: By default, only new strings are added. Translations already in the DB are kept the same. If you want to replace all values with the ones from the files, add the --replace (or -R) option: php artisan translations:import --replace

Find translations in source

The Find command/button will look search for all php/twig files in the app directory, to see if they contain translation functions, and will try to extract the group/item names. The found keys will be added to the database, so they can be easily translated. This can be done through the webinterface, or via an Artisan command.

$ php artisan translations:find

If your project uses translation strings as keys, these will be stored into then _json group.

Export command

The export command will write the contents of the database back to app/lang php files. This will overwrite existing translations and remove all comments, so make sure to backup your data before using. Supply the group name to define which groups you want to publish.

$ php artisan translations:export <group>

For example, php artisan translations:export reminders when you have 2 locales (en/nl), will write to app/lang/en/reminders.php and app/lang/nl/reminders.php

To export translation strings as keys to JSON files , use the --json (or -J) option: php artisan translations:export --json. This will import every entries from the _json group.

Clean command

The clean command will search for all translation that are NULL and delete them, so your interface is a bit cleaner. Note: empty translations are never exported.

$ php artisan translations:clean

Reset command

The reset command simply clears all translation in the database, so you can start fresh (by a new import). Make sure to export your work if needed before doing this.

$ php artisan translations:reset

Detect missing translations

Most translations can be found by using the Find command (see above), but in case you have dynamic keys (variables/automatic forms etc), it can be helpful to 'listen' to the missing translations. To detect missing translations, we can swap the Laravel TranslationServiceProvider with a custom provider. In your config/app.php, comment out the original TranslationServiceProvider and add the one from this package:

//'Illuminate\Translation\TranslationServiceProvider',
'Barryvdh\TranslationManager\TranslationServiceProvider',

This will extend the Translator and will create a new database entry, whenever a key is not found, so you have to visit the pages that use them. This way it shows up in the webinterface and can be edited and later exported. You shouldn't use this in production, just in development to translate your views, then just switch back.

TODO

This package is still very alpha. Few things that are on the todo-list:

- Add locales/groups via webinterface
- Improve webinterface (more selection/filtering, behavior of popup after save etc)
- Seed existing languages (https://github.com/caouecs/Laravel-lang)
- Suggestions are welcome :)

GitHub

https://github.com/barryvdh/laravel-translation-manager
Comments
  • 1. Bug with @lang

    Hi, we are using this package and we found a bug with the "$stringPattern" regex for the @lang directive inside "findTranslations" method -If the file starts with @lang -If @lang is immediately after an html tag (no spacing before)

    You can see links below: https://regex101.com/r/Kmz52y/1 https://regex101.com/r/crVgZD/1

    https://regex101.com/r/FRV8ou/1 - works here

    Thank You

    Reviewed by YordanovBg at 2018-06-21 15:53
  • 2. Don't properly work on L 5.4.13

    After updating to L 5.4.13 The translation-manager interface normally opened but after choosing a group to edit translations, keys and translations didn't load. Then i returned to L 5.4.11 and everything work again.

    Really want to make a PR to solve it but i'm not yet enough skilled to do so..

    Reviewed by evrard-c at 2017-02-24 14:58
  • 3. [L5.3.x] BadMethodCallException: Method controller does not exist

    Hi. Tried to add this package to a laravel 5.3.x app and got the following error while publishing config/migrations:

      [BadMethodCallException]
      Method controller does not exist.
    

    laravel.log trace

    #0 C:\Work\www\projects\locales2\vendor\barryvdh\laravel-translation-manager\src\ManagerServiceProvider.php(89): Illuminate\Routing\Router->__call('controller', Array)
    #1 [internal function]: Barryvdh\TranslationManager\ManagerServiceProvider->Barryvdh\TranslationManager\{closure}(Object(Illuminate\Routing\Router))
    #2 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Routing\Router.php(319): call_user_func(Object(Closure), Object(Illuminate\Routing\Router))
    #3 C:\Work\www\projects\locales2\vendor\barryvdh\laravel-translation-manager\src\ManagerServiceProvider.php(90): Illuminate\Routing\Router->group(Array, Object(Closure))
    #4 [internal function]: Barryvdh\TranslationManager\ManagerServiceProvider->boot(Object(Illuminate\Routing\Router))
    #5 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Container\Container.php(507): call_user_func_array(Array, Array)
    #6 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(759): Illuminate\Container\Container->call(Array)
    #7 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(742): Illuminate\Foundation\Application->bootProvider(Object(Barryvdh\TranslationManager\ManagerServiceProvider))
    #8 [internal function]: Illuminate\Foundation\Application->Illuminate\Foundation\{closure}(Object(Barryvdh\TranslationManager\ManagerServiceProvider), 11)
    #9 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(743): array_walk(Array, Object(Closure))
    #10 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\BootProviders.php(17): Illuminate\Foundation\Application->boot()
    #11 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(203): Illuminate\Foundation\Bootstrap\BootProviders->bootstrap(Object(Illuminate\Foundation\Application))
    #12 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php(246): Illuminate\Foundation\Application->bootstrapWith(Array)
    #13 C:\Work\www\projects\locales2\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php(108): Illuminate\Foundation\Console\Kernel->bootstrap()
    #14 C:\Work\www\projects\locales2\artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
    #15 {main}  
    

    Cheers

    Reviewed by rjsworking at 2016-08-11 10:01
  • 4. Unsupported operand types

    I'm getting the following error when I try to go to /translations:

    exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Unsupported operand types' in vendor/barryvdh/laravel-translation-manager/src/Controller.php:31.

    I've done everything like the manual shows. I'm using Laravel v5.1.45.

    Reviewed by nielvrom at 2016-10-27 13:38
  • 5. SQLSTATE[42000]: Syntax error or access violation: 1055

    PDOException in PDOConnection.php line 77:
    SQLSTATE[42000]: Syntax error or access violation: 1055 'invoices.ltm_translations.id' isn't in GROUP BY (SQL: select * from `ltm_translations` group by `locale`)
    

    Clean Laravel 5.3 install, ltm version 2.5. Downgraded to 2.4 - problem vanished.

    Reviewed by zanozik at 2016-10-25 02:22
  • 6. A function to find translation keys in a project

    Hi Barry,

    I was thinking about a new approach to translations in a project. I find myself writting trans('...') in the view and then have to open the translation file for each language and add the key by hand... It's boring and error proof! :smile:

    This is just a raw example:

    <?php
    
    $directory = new RecursiveDirectoryIterator('./app');
    $iterator = new RecursiveIteratorIterator($directory);
    $phpFiles = new RegexIterator($iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH);
    
    $transKeys = array();
    
    $phpFilesCount = 0;
    
    foreach ($phpFiles as $file) {
        $phpFilesCount++;
        $inputFile = file_get_contents($file[0]) or die("Could not access file");
    
        $findTranslation = "trans\(\'([a-zA-Z0-9_]+([-.][a-zA-Z0-9_]+))\'\)";
    
        if(preg_match_all("/$findTranslation/siU", $inputFile, $matches)) { 
            foreach ($matches[1] as $key) {
                $transKeys[] = $key;
            }
        } 
    }
    
    echo "Files scaned: " . $phpFilesCount    . PHP_EOL;
    echo "Keys founded: " . count($transKeys) . PHP_EOL;
    echo "Keys: " . PHP_EOL;
    print_r($transKeys);
    

    Save it to test.php and run it from you project root: $ php test.php

    It's MEGA fast. $ time php test.php

    Files scaned: 392
    Keys founded: 1900
    Keys:
    ...
    php test.php  0,20s user 0,05s system 94% cpu 0,266 total
    

    What do you think?

    thanks

    Reviewed by cossou at 2014-04-23 19:28
  • 7. Undefined property: Barryvdh\TranslationManager\Translator::$manager [package version 0.4.x]

    I've recently upgraded a project from using Laravel 5.4 and laravel-translation-manager 0.2.* to using Laravel 5.5 and laravel-translation-manager 0.4.1, and I started getting the above error from this line: https://github.com/barryvdh/laravel-translation-manager/blob/c9939e6199e92d36301143f37a735fcf36d022f5/src/Translator.php#L42

    I'm a bit confused as to what's causing this error to appear, and specially why this problem didn't show up before. Also, I've never used the setTranslationManager function. However, I've managed to get things working by adding a protected $manager = null; to the Translator class. Is this property supposed to be inherited from Illuminate\Translation\Translator?

    [ EDIT: upgraded Laravel to 5.5! ]

    Reviewed by andrechalom at 2017-09-14 18:11
  • 8. Added support for nested translation files

    Added a where clausule to the registered routes to accept slashes.

    Note sure if the extra added getView method is needed anymore. Can someone confirm?

    Reviewed by markwalet at 2016-10-07 11:30
  • 9. L5.6 support

    Hi! I see PR's to accommodate for Laravel 5.6 are merged with master already. Any idea when a new release will be tagged? I need to upgrade one of my projects but feel a bit iffy ignoring my minimum stability settings in production. Thanks!

    Reviewed by gwleuverink at 2018-03-06 09:09
  • 10. change route?

    I have problems because my routes can't access to /translations

    how can I change the route? or add a filter to my route that not allow to access translations

    Reviewed by carlituxman at 2015-12-17 18:32
  • 11. Invalid argument supplied for foreach()

    After updating composer i noticed this error in te firebug console upon pressng the "import groups" button. I don;t know if this issue existed before the update, or wether something else on my side is wrong.

    ErrorException in Arr.php line 70: Invalid argument supplied for foreach()

    in Arr.php line 70
    at HandleExceptions->handleError('2', 'Invalid argument supplied for foreach()', 'C:\wamp\www\test\vendor\laravel\framework\src\Illuminate\Support\Arr.php', '70', array('array' => '1', 'prepend' => '', 'results' => array())) in Arr.php line 70
    at Arr::dot('1', '') in helpers.php line 90
    at array_dot('1') in Manager.php line 55
    at Manager->importTranslations('0') in Controller.php line 107
    at Controller->postImport()
    at call_user_func_array(array(object(Controller), 'postImport'), array()) in Controller.php line 246
    at Controller->callAction('postImport', array()) in ControllerDispatcher.php line 162
    at ControllerDispatcher->call(object(Controller), object(Route), 'postImport') in ControllerDispatcher.php line 107
    at ControllerDispatcher->Illuminate\Routing\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 141
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 101
    at Pipeline->then(object(Closure)) in ControllerDispatcher.php line 108
    at ControllerDispatcher->callWithinStack(object(Controller), object(Route), object(Request), 'postImport') in ControllerDispatcher.php line 67
    at ControllerDispatcher->dispatch(object(Route), object(Request), 'Barryvdh\TranslationManager\Controller', 'postImport') in Route.php line 198
    at Route->runWithCustomDispatcher(object(Request)) in Route.php line 131
    at Route->run(object(Request)) in Router.php line 692
    at Router->Illuminate\Routing\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 141
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in AuthenticateAdmin.php line 47
    at AuthenticateAdmin->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 101
    at Pipeline->then(object(Closure)) in Router.php line 694
    at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 661
    at Router->dispatchToRoute(object(Request)) in Router.php line 619
    at Router->dispatch(object(Request)) in Kernel.php line 214
    at Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 141
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in VerifyCsrfToken.php line 43
    at VerifyCsrfToken->handle(object(Request), object(Closure)) in VerifyCsrfToken.php line 17
    at VerifyCsrfToken->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in ShareErrorsFromSession.php line 55
    at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in StartSession.php line 61
    at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 36
    at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in EncryptCookies.php line 40
    at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in CheckForMaintenanceMode.php line 42
    at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Language.php line 46
    at Language->handle(object(Request), object(Closure)) in Pipeline.php line 125
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
    at call_user_func(object(Closure), object(Request)) in Pipeline.php line 101
    at Pipeline->then(object(Closure)) in Kernel.php line 115
    at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 84
    at Kernel->handle(object(Request)) in index.php line 53
    
    Reviewed by XaphanBael at 2015-04-15 11:30
  • 12. Find incorrectly extracts keys with dots

    In case if you use statement/text with dots for translation (e.q. Loading...), than this text is treated as key and wrongly split into group Loading, with key "..".

    Correct approach would be to skip group parsing if translation input text contains multiple sequential dots (...) or has spaces.

    Reviewed by mvehar at 2022-03-12 22:44
  • 13. Exclude node_modules, do not ignore views/vendor folder

    In line: https://github.com/barryvdh/laravel-translation-manager/blob/c86849aadfc277a6cf2c5bc05f52824624782f08/src/Manager.php#L191

    1. manager ignores all vendor folders.
    2. does NOT ignore node_modules folder, therefore scans all node_module files
    Reviewed by mvehar at 2022-03-12 22:10
  • 14. change in transaction table name & databae connection

    If you develope a large system, and each part of the system has its own database, but at the same time speech and translation are one. There must be a common database so that the databases are not repeated in more than one place and at the same time the translation is all the same and comes from one place It is also possible to change in values from .env file or config.

    Reviewed by BNhashem16 at 2022-01-29 13:09
  • 15. Translations in folders are not imported

    I have a translation in a folder writer/messages.php This translation is not imported into the database. All translations in folders are not imported into the database. Translations without folders are successfully imported.

    Reviewed by AlexKomMsk at 2021-12-24 10:51
Weblate translation provider for Symfony Translation.

Weblate Translation Provider This bundle provides a Weblate integration for Symfony Translation. Installation composer require m2mtech/weblate-transla

May 6, 2022
Filament Translations - Manage your translation with DB and cache
Filament Translations - Manage your translation with DB and cache

Filament Translations Manage your translation with DB and cache, you can scan your languages tags like trans(), __(), and get the string inside and tr

Apr 22, 2022
A GUI for managing JSON translation files in your laravel projects.
A GUI for managing JSON translation files in your laravel projects.

Laravel Language Manager Langman is a GUI for managing your JSON language files in a Laravel project. Installation Begin by installing the package thr

May 19, 2022
Better translation management for Laravel

Better localization management for Laravel Introduction Keeping a project's translations properly updated is cumbersome. Usually translators do not ha

Apr 14, 2022
Laravel translation made __('simple').
Laravel translation made __('simple').

Translation.io client for Laravel 5.5+/6/7/8 Add this package to localize your Laravel application. Use the official Laravel syntax (with PHP or JSON

May 20, 2022
🎌 Laravel Localization Helper :: Easily add translation variables from Blade templates.

LocalizationHelper Package for convenient work with Laravel's localization features and fast language files generation. Take a look at contributing.md

Jan 15, 2022
[virion] Language management library for automatic translation
[virion] Language management library for automatic translation

libtranslator :: library for automatic translation ✔️ Multilingual support for plugin messages ✔️ Translation language is set according to the player

Feb 15, 2022
Internationalization tools, particularly message translation.

Aura.Intl The Aura.Intl package provides internationalization (I18N) tools, specifically package-oriented per-locale message translation. Installation

Apr 1, 2022
Provides support for message translation and localization for dates and numbers.

The I18n library provides a I18n service locator that can be used for setting the current locale, building translation bundles and translating messages. Additionally, it provides the Time and Number classes which can be used to output dates, currencies and any numbers in the right format for the specified locale.

Mar 3, 2022
The Translation component provides tools to internationalize your application.

Translation Component The Translation component provides tools to internationalize your application. Getting Started $ composer require symfony/transl

May 25, 2022
Package to manage Laravel translations locally
Package to manage Laravel translations locally

Translation Manager For Laravel Easy to use package that helps you with the translation of your Laravel application locally. Features ✅ Check all loca

Jan 8, 2022
Language files manager in your artisan console.

Laravel Langman Langman is a language files manager in your artisan console, it helps you search, update, add, and remove translation lines with ease.

May 13, 2022
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Cashier and Laravel Nova.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

May 28, 2022
75 languages support for Laravel 5 application based on Laravel-Lang/lang.

Laravel-lang 75 languages support for Laravel 5 application based on Laravel-Lang/lang. Features Laravel 5+ && Lumen support. Translations Publisher.

May 19, 2022
Easy localization for Laravel

Laravel Localization Easy i18n localization for Laravel, an useful tool to combine with Laravel localization classes. The package offers the following

May 26, 2022
[Deprecated] A Laravel package for multilingual models
[Deprecated] A Laravel package for multilingual models

This package has been deprecated. But worry not. You can use Astrotomic/laravel-translatable. Laravel-Translatable If you want to store translations o

Apr 20, 2022
Easy multilingual urls and redirection support for the Laravel framework

Linguist - Multilingual urls and redirects for Laravel This package provides an easy multilingual urls and redirection support for the Laravel framewo

Feb 13, 2022
Support multiple language resources for Laravel

Laratrans Support multiple language resources for Laravel. Docs Installation composer require lechihuy/laratrans After you install the package success

Dec 21, 2021
Generates a vue-i18n compatible include file from your Laravel translations

This is fork of martinlindhe/laravel-vue-i18n-generator to give Laravel 8+ support for this excellent package.

Nov 11, 2021