Laravel-Lang / publisher

Publisher provides functionality for working with application localization
https://laravel-lang.com/packages-publisher.html
MIT License
211 stars 25 forks source link

Overloaded translation #329

Closed forxer closed 1 year ago

forxer commented 1 year ago

Environment

Issue description

Hello,

I'm experiencing strange behavior with my forxer/generic-term-translations-for-laravel plugin for Laravel Lang

I have a file /source/misc.php in which there is an array key named "required"' Link

When I update the language files, I find /lang/{language}/misc.php with the good translation.

So far, so good

But when I call the translation {{ trans('misc.required') }} this is replaced by that of the validation.php file.

I was expecting to get what's in the plugin's misc.php file but I got what's in the validation.php file instead.

Steps to reproduce

Install forxer/generic-term-translations-for-laravel

Display in a view {{ trans('misc.required') }}

Expected string:

Result string:

andrey-helldar commented 1 year ago

My steps:

1.

    laravel new test
    cd test
    composer require forxer/generic-term-translations-for-laravel --dev
    php artisan lang:add en fr
  1. Replace locale option with en value in the config/app.php file
  2. I see the structure of the lang/fr/misc.php file according to the original. All keys are translated into French.

image

  1. I replaced the contents of the resources/views/welcome.blade.php file with:

    {{ trans('misc.required') }}
  2. Call the php artisan serve console command and open http://127.0.0.1:8000

  3. I see requis:

image

Environment

andrey-helldar commented 1 year ago

The following test also showed no problems:

  1. php artisan lang:update
  2. Call the php artisan serve console command and open http://127.0.0.1:8000/

image

Next, I publish internal files:

php artisan lang:publish

image

And no problem either.

image

Next, I run several commands and already here the problem was found:

composer require laravel-lang/common
php artisan lang:update
php artisan serve

image

image

The problem is that translation files contain common values regardless of the source file. Thus, if the misc and variations files contain the same keys (in our example, it is "required"), then in the end the translation will be taken from the "variations" file, because it comes after "misc" alphabetically, and the "array_merge" function overwrites the previous values.

This was done specifically to reduce the amount of translation, because. identical keys generally expect the same values. But sometimes there are such collisions.

andrey-helldar commented 1 year ago

If you take a look at the php.json file, you will notice that it contains all the keys from the php files in the source folder.

When updating localizations in an application, the publisher first downloads all available plugins containing translations, compiles a map of localizations, loads the necessary keys, and only after that processes the files, extracting the necessary translations from them.

Answering the question why then not to separate the work of plugins so that each is responsible for their own translations, I’ll say that we used to have it like this, and for each plugin we had to wait for the translation, and in this mechanism, if the string is already translated in another plugin, then it will be taken and for the one where this translation is not available. Thus, we increase the coverage of translation files.

The only working solution at the moment is to use a prefix when forming the name, or wrap them in an additional key.

For example:

// source/misc.php
<?php

return [
    'labels' => [
        'required' => 'required',
    ],
];
{{ trans('misc.labels.required') }}

Yes, it doesn't look very elegant, but it's guaranteed to work.

andrey-helldar commented 1 year ago

I will figure out how to solve this problem.

forxer commented 1 year ago

Ok I was thinking about this kind of mechanism, but I couldn't find the path.

I have such generic terms (that's what the plugin is about) that I must have other overloads of the same type.

Thank you for the answer.

andrey-helldar commented 1 year ago

Offhand, add an isolation option to the plugin so that it only reads translations from its own files, ignoring the translations of other plugins. In this case, this problem will be fixed. After the vacation, I will make changes to the project.