-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[Form] Example of customizing EnumType
labels
#17149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
case Center = 'Center/Middle aligned'; | ||
case Right = 'Right/End aligned'; | ||
|
||
public function label(): string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this method to the enum class starts mixing data and presentation which I would not advise. Let's configure the choice label using a closure instead (see comment below).
->add('textAlign', EnumType::class, [ | ||
'class' => TextAlign::class, | ||
'choice_label' => static function (TextAlign $choice): string { | ||
return $choice->label(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return $choice->label(); | |
return match ($choice) { | |
TextAlign::Left => 'text_align.left.label', | |
TextAlign::Center => 'text_align.center.label', | |
TextAlign::Right => 'text_align.right.label', | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would work if you only needed to display the labels in your form, but if you also need them to appear anywhere else in your application I think adding a method in the enum class is a better solution. I don't think adding presentation methods in enum classes is a bad practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I had different places where I needed the label, I would go with a separate class that maps enum instances to labels to be honest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be a way to do it but maybe a bit overkill. Even the PHP documentation suggests adding a label method in enum classes in their examples : https://www.php.net/manual/fr/language.enumerations.examples.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what to say here. I think both of you gave good reasons to do opposite things.
Let's ask @wouterj and @OskarStark. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @xabbuh here. I understand your point, @robinbrisa, and it is also proven by the official PHP docs.
However, I would say that an enum can ship a generic presentation layer. The labels provided in this example indirectly couple the Enum's presentation layer to the Symfony Translation component - without it, the labels render worse human readable than their default string representation from the BackedEnum
.
In that case, I would favor to keep the enum decoupled from Symfony Translation and handle the presentation in the layer that is responsible for mapping between Symfony Translation and the Enum, which is this function :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to see it would be to have MyEnum::getLabel()
and/or MyEnum::getTranslationKey()
to make it more reusable with respect for different layers.
However for the docs I agree this callable is a good way to go.
EnumType
labels
'choice_label' => static function (TextAlign $choice): string { | ||
return $choice->label(); | ||
}, | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
]) | |
]); |
Default behavior when creating a EnumType form element is that the choice labels displayed to the user are the enum names. This PR adds an example of how to use a function inside an enum to return labels and how to bind this function to the form element.
ca038d5
to
65ece3e
Compare
Default behavior when creating a EnumType form element is that the choice labels displayed to the user are the enum names.
This PR adds an example of how to use a function inside an enum to return labels and how to bind this function to the form element.