Skip to content

Conversation

@vpratfr
Copy link
Contributor

@vpratfr vpratfr commented Mar 12, 2021

Use case

There is a complex form with similar fields present in different groups. For instance, within a network form, we want to define the name and IP of machines having some specific roles. The same field could in some cases have a specific translation but in most cases it would always be translated the same way.

Current

The validation attributes translation definition would look like that:

'attributes'=> [
    'network.*.http.host_name' => 'HTTP server name',
    'network.*.db_master.host_name' => 'Server name',
    'network.*.db_slave.host_name' => 'Server name',
    'network.*.other.host_name' => 'Server name',
]

Notice that if the user add some more roles to the form, he will then have to define more translations: e.g. 'network.*.dns.host_name' => 'Server name'. This becomes even more cumbersome as the number of fields grow per group.

Notice also that in the use case described in laravel/ideas#2533 (dynamic validation rules per form item) we simply cannot get any translation.

Proposed fix

When a specific translation is missing, we could simply look if we find a more generic translation key. In the above example, we could simply the above translations to:

'attributes'=> [
    'network.*.http.host_name' => 'HTTP server name',
    'host_name' => 'Server name',                                
]

When the network.*.db_slave.host_name is looked up, we will sequentially look for the following keys within the validation.attributes array:

  1. network.*.db_slave.host_name
  2. *.db_slave.host_name
  3. db_slave.host_name
  4. host_name

Gain from the user perspective

This allows the user to drastically lower the number of translations used, and to lower maintainance cost when new similar fields are added.

In the application we are working on, we currently have around 500 keys of attribute translations, with a lot of duplicate entries. The proposed fixe would allow to divide that number by around 3, leaving around 150 unique keys.

The gain is obvious when it comes to changing a translation (having to make sure we do not forget a key) and adding new groups of fields (not forgetting to define the specific duplicate for that particular group).

Further improvements

I think the same enhancement could be provided for the validation.values translations too.

fixes laravel/ideas#2533 and laravel/ideas#1771

@driesvints driesvints changed the title Allow validation error attribute names to fallback to a more generic translation [8.x] Allow validation error attribute names to fallback to a more generic translation Mar 12, 2021
@taylorotwell
Copy link
Member

This would be a breaking change also I'm not sure it's particularly intuitive or time-saving.

@vpratfr
Copy link
Contributor Author

vpratfr commented Mar 15, 2021

Hi,

This would be a breaking change

Actual behaviour is to return the string when translation found, the key when not found (which is anyway not the desired output).

Proposed behaviour is to look for an alternative key with a matching name using a hierarchy.

I'm not sure it's particularly intuitive or time-saving

I can guarantee the gain on maintainance cost for translations. In a real life project, we are struggling with 500+ lines of attribute name translations and that keeps growing as more forms are added. We have no way to always use the same attribute names for those forms, hence we keep on duplicating lines for no reason. Accumulating bugs because someone forgot to copy/paste one of the translations.

That said, as explained in the description, we are also facing an issue where when you add a complex sometimes validation rule for a particular array item (let's say items.123.name), the translation items.*.name is not applied. We get back the items.123.name string.

Currently there is no workaround possible given the way translations are fetched by the validator. We cannot plug our own logic, we cannot override the behaviour for getting attribute translations.

  • Would you have a suggestion on how to get around that limitation?
  • How we could maybe simply override the framework's default logic when it comes to fetching the attribute translation?

The validator can be customized for some aspects of it, like Validator::replacer for instance. Nothing documented for attributes/values translations though.

@FrittenKeeZ
Copy link
Contributor

Just a thought.. what if the operator was double asterisk ** instead? Would that break anything?

'attributes'=> [
    'network.**.http.host_name' => 'HTTP server name',
    '**.host_name' => 'Server name',                                
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Laravel custom attribute translation for array validation

3 participants