Astrotomic / laravel-translatable

A Laravel package for multilingual models
https://docs.astrotomic.info/laravel-translatable/
MIT License
1.23k stars 155 forks source link

Translated validation attributes #209

Open justijndepover opened 3 years ago

justijndepover commented 3 years ago

I'm sorry if this has been asked before, but I can't seem to find an answer.

I validate my fields with the RuleFactory::make command. For example:

class CategoryRequest extends FormRequest
{
    public function rules()
    {
        return RuleFactory::make([
            '%name%' => ['required', 'string', 'max:255'],
            '%description%' => ['required', 'string'],
         ]);
    }
}

When I show the errors below the inputs, I get something like: fr.name is verplicht. How can I translate the attribute name so fr.name is translated in the app locale (dutch in this case): naam

Gummibeer commented 3 years ago

Hey,

good point. The first way would be to add all of them to your validation translations file. Not so cool.^^ but what would work right now.

I PR I would be open to merge is a change in the rule factory or any method to run in service provider to automatically add all the locale specific translation keys by copy'n'paste the original translation value.

A simple example I have in mind:

RuleFactory::copyAttributeTranslations(
  ['name']
);

// logic
foreach $attributes as $attribute
  $trans = trans(validation.attributes.$attribute)
  foreach $locales as $locale
    Translator::add(validation.attributes.$locale.$attribute)
justijndepover commented 3 years ago

I tried adding this to my AppServiceProvider:

$translator = app('translator');
$currentLocale = $translator->getLocale();

$translator->addLines([
    "validation.attributes.nl.name" => 'naam', // this can be dynamic
], $currentLocale);

But that doesn't work and breaks all other validation.attributes translations. Temporarily fixed this issue by adding this to my FormRequest:

public function attributes()
{
    return RuleFactory::make([
        '%name%' => __('validation.attributes.name'),
        '%description%' => __('validation.attributes.description'),
    ]);
}

But would love a cleaner solution.

Gummibeer commented 3 years ago

I will check this out and why the first one errors and how to possibly solve this.

But I think that the last one with a dedicated method would be the cleanest! So instead of make an attributes() method or similar that could possibly also automatically do the trans() call if you follow default naming.

justijndepover commented 3 years ago

Personally I'm already satisfied with the solution I have.

I also think that this way is more clear for programmers than doing all behind the scenes (for example in your TranslatableServiceProvider).

I think the best solution would be to add something like this to the FormRequest

public function attributes()
{
    return RuleFactory::translatedValidationAttributes(); // don't know if RuleFactory is the best place for this logic
}

And perhaps make it possible to add your own if the field name isn't in the validation.attributes array:

public function attributes()
{
    return RuleFactory::translatedValidationAttributes([
        'age' => __('default.age'),
    ]);

    // which would result in: ['nl.age' => 'leeftijd', 'fr.age' => 'leeftijd', ... all the other attributes]
}

What do you think?

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 21 days with no activity. Remove stale label or comment or this will be closed in 7 days