If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Check out the web debug toolbar: it's highlighted with the number of validation errors, which is pretty cool. It's even cooler because we can see where those are coming from.
The default message for the NotBlank
constraint is obviously
This value should not be blank
We can easily change this by passing a message
option to the annotation. But wait
a second: we're going to use NotBlank
a lot. Is there a way to customize the default
message across the whole system?
Yea! All of these strings are passed through Symfony's translator. And we can take advantage of that to customize this message, even in English.
First, in case you don't already have it enabled, open up app/config/config.yml
.
Activate the translator
service by uncommenting out the translator
key under
framework
:
... lines 1 - 11 | |
framework: | |
... line 13 | |
translator: { fallbacks: ["%locale%"] } | |
... lines 15 - 74 |
Refresh this page and watch the web debug toolbar. Suddenly, there's an extra icon that's coming from the translator. It's reporting that there are ten missing messages. In other words, we are apparently already sending ten messages through the translator that are missing translation strings.
This is because every form field and all validation errors are automatically sent through the translator. Nothing looks weird, because those strings are already English, so it's not really a problem that they aren't translated.
But, if you want to customize this message, copy it. And, notice, the domain is
validators
: that's basically a translation "category", and it's important for
what we do next.
We don't have any translation files yet, so create a new directory called translations
in app/Resources
. Inside, add a new file: validators.en.yml
. This is validators
because the message is being translated in that domain.
Inside, paste the string and set it to "Hi! Please enter something for this field.":
"This value should not be blank.": Hi! Please enter *something* for this field :) |
And that's it! Go back and refresh! Oh no, it didn't work! Well, I kind of expected that. Find your terminal, open a new tab, and run:
./bin/console cache:clear
You almost never need to worry about clearing your cache while developing but very occasionally, you'll find a quirk in Symfony that needs this. Sometimes, when you add a new translation file, this happens.
Let's refresh again. There it is!
So yay validation! There's one more constraint I want you to see: Callback
. This
is your Swiss army knife: it allows you to write whatever custom validation logic
you want inside a method. There, you can create different validation errors and map
them to any field.
Hey Mike P.
I'm not sure if using keys impacts performance, but it is recommended to use them, they are short, descriptive, and hard to change.
You can dive deeper about internationalization best practices here: http://symfony.com/doc/curr...
Also symfony has a dedicated section for best practices: http://symfony.com/doc/curr...
I hope it helps you :)
Is it possible to combine the message field with the translation file?
Example:
I want the following error message: "Email cannot be longer than than {{ limit }} characters"
Of course this constraint message is the same for a lot of different fields, just the name "Email" changes.
I want:
Entity:
* @Assert\Length(max=100, maxMessage="Email length.max")
Validators:
length.max: cannot be longer than than {{ limit }} characters
Wanted Result:
Email cannot be longer than than {{ limit }} characters
But this doesn't seem to work.
A TWIG Variable like {{ label }} doesn't seem to exist. (Idea was to add length.max: {{ label }} cannot be longer than than {{ limit }} characters)
Do I really have to generate a translation row inside the validation file for every single label field?
Hey Mike,
That's a good question about customization but a a little overhead. Actually, you don't need field labels in translation messages because errors tied to its fields. Therefore, considering this fact, you already have a context about what exactly field is invalid. So, if you have an HTML layout with a good CSS styles - it should look fine.
Anyway, you *can* override that error message, and you *can* use custom variables in it, so your overwritten message should look like:
{{ label }} cannot be longer than than {{ limit }} characters.
But you need to inject that {{ label }} variable manually in place where this message is translated, for that you need to override a Symfony form template for this field with your own, i.e. create your custom Twig form theme. Here's a bit more information how to create and use your custom Twig form: https://knpuniversity.com/s...
Cheers!
Hey guys, I have a weird error, the Symfony profiler toolbar is showing on list page, but not on the new genus page, any idea how I can track this down?!
Hey Shaun T.
Could you show me your controller's code ?
I believe you are missing the head/body tags on your page, does your controller extends from Symfony's base controller ?
Cheers!
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"knplabs/knp-markdown-bundle": "^1.4", // 1.4.2
"doctrine/doctrine-migrations-bundle": "^1.1" // 1.1.1
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0", // v3.1.3
"nelmio/alice": "^2.1", // 2.1.4
"doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
}
}
Is there a best practice for translated validation messages?
Because in this video you show us to use the string directly:
"This value should not be blank.": Hi! Please enter something for this field :)
`In another video someone recommends using:
user:
email:
`
(and set the validation message as user.email.unique)
Does this differ in terms of performance / best practice?