Gettext not working with validate_length

I tried to modify the message in the errors.po file but it is not working, despite the fact that modifying the message of validate_required works

|> validate_length(:password, min: 12, max: 72)

so for example let’s say that there is in the schema module the following code:

|> validate_required([:password], message: "test validate required")

and in the errors.po file the following code:

msgid "test validate required"
msgstr "success test validate required"

it prints success and that is perfect :+1:

but when I do the same in the schema file:

|> validate_length(:password, min: 12, max: 72, message: "test validate length")

and the errors.po file:

msgid "test validate length"
msgstr "success test validate length"

it does not work! :no_mouth:, that is unexpected.

Maybe are you editing the wrong message in your errors.po?
Did you translate all the messages ?

I think the validate_length is handled by multiple messages:

msgid "should be %{count} character(s)"
msgid "should be at least %{count} character(s)"
msgid "should be at most %{count} character(s)"

Have you all that translated ?

Maybe show us what it looks like the part of the file you edited.

1 Like

No I used the correct translation can you reread the question I have added more information

Oh I see ! You are using a custom error message. In that case you should use a gettext backend in your changeset like this:

|> validate_required([:password], message: MyApp.Gettext.gettext(“test validate required”))

Then of course you will use mix gettext to extract the new message into your po files. You don’t have to add the msgid by hand.

1 Like

While useful for being able to extract those strings, that shouldn’t be necessary at all. MyAppWeb.ErrorHelper will run any ecto error through a translation step.


Ah, thanks for pointing this. I didn’t know that.

Great this worked with dgettext but not with gettext
like the following

|> validate_length(:password, min: 12, max: 72, message: MyAppWeb.Gettext.dgettext("errors", "test validate length %{count}"))

But the maximum limit, should have another message

I tried to reproduce the issue you are facing and this is what I can say.

1- Adding bare custom message in the validate_length without gettext then editing by hand errors.pot then merging the new msgid with mix gettext.merge into errors.po won’t work.

2- Importing MyApp.gettext/1 in the changeset and passing the message through it, work as expected. In my case after running mix gettext.extract --merge and adding the translation in default.po work. I can see you’ve done something similar but with dgettext.

Now if you want to customize your message depending on the kind of error then just add multiple validations:

|> validate_length(:password, min: 12, message: dgettext("errors", "too short"))
|> validate_length(:password, max: 72, message: dgettext("errors", "too long"))

I didn’t test this but I guess it should work.

Edit :

I realise you were saying that you are not getting the same error message as expected. That is weird, when I pass min and max in the same validation options I have the same error message as expected. I just tested it right now.

1 Like

Yes dgettext can extract your messages in specific domain file such as errors.pot. But if you just use gettext then they will be found in default.pot and default.po.