I18N: Error Message Localization for Particular Model

i18n: error message localization for particular model

Try this:

en:
mongoid:
errors:
messages:
taken: "It is already taken"
models:
user:
attributes:
login:
taken: "It is already taken. %{link}"

Reference:

ActiveRecord code comments

PS:
The localization string should use interpolation variable for dynamic substitution.

E.g:
Add an error on the login field of user object:

user.errors.add(:login, :taken, :link => "foo")

ASP.NET Core Model Binding Error Messages Localization

To customize framework model binding error messages, you need to set custom accessors for different error message accessors of ModelBindingMessageProvider.

Example

Here you can download a full source code of what is described in this post. The repository contains example for ASP.NET Core 2.0 (VS 2017.3) and ASP.NET Core 1.1 (VS 2015):

  • r-aghaei/AspNetCoreLocalizationSample

Also here you can see the example, live:

  • aspnetcorelocalizationsample.azurewebsites.net

Default Error Messages

These are default error messages which the framework shows when model binding to a property fails:

MissingBindRequiredValueAccessor    A value for the '{0}' property was not provided.
MissingKeyOrValueAccessor A value is required.
ValueMustNotBeNullAccessor The value '{0}' is invalid.
AttemptedValueIsInvalidAccessor The value '{0}' is not valid for {1}.
UnknownValueIsInvalidAccessor The supplied value is invalid for {0}.
ValueIsInvalidAccessor The value '{0}' is invalid.
ValueMustBeANumberAccessor The field {0} must be a number.

In addition to above messages, ASP.NET Core 2.0 have these messages as well:

MissingRequestBodyRequiredValueAccessor       A non-empty request body is required.
NonPropertyAttemptedValueIsInvalidAccessor The value '{0}' is not valid.
NonPropertyUnknownValueIsInvalidAccessor The supplied value is invalid.
NonPropertyValueMustBeANumberAccessor The field must be a number.

Localize ASP.NET Core Model Binding Error Messages

To localize ASP.NET Core model binding error messages, follow these steps:

  1. Create Resource File - Create a resource file under Resources folder in your solution and name the file ModelBindingMessages.fa.resx. The name can be anything else but we will use it to create a localizer. In the example, I used fa (Persian) culture.

  2. Add Resource Keys - Open the resource file and add keys and values which you want to use for localizing error messages. I used keys and values like below image:

    Sample Image

    Keys which I used are like original messages, except the key for ValueMustNotBeNull which was the same as ValueIsInvalid, so I used Null value is invalid. for it.

  3. Configure Options - In ConfigureServices method, when adding Mvc, configure its options to set message accessors for ModelBindingMessageProvider:

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddLocalization(options => { options.ResourcesPath = "Resources"; });
    services.AddMvc(options =>
    {
    var F = services.BuildServiceProvider().GetService<IStringLocalizerFactory>();
    var L = F.Create("ModelBindingMessages", "AspNetCoreLocalizationSample");
    options.ModelBindingMessageProvider.ValueIsInvalidAccessor =
    (x) => L["The value '{0}' is invalid.", x];
    options.ModelBindingMessageProvider.ValueMustBeANumberAccessor =
    (x) => L["The field {0} must be a number.", x];
    options.ModelBindingMessageProvider.MissingBindRequiredValueAccessor =
    (x) => L["A value for the '{0}' property was not provided.", x];
    options.ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor =
    (x, y) => L["The value '{0}' is not valid for {1}.", x, y];
    options.ModelBindingMessageProvider.MissingKeyOrValueAccessor =
    () => L["A value is required."];
    options.ModelBindingMessageProvider.UnknownValueIsInvalidAccessor =
    (x) => L["The supplied value is invalid for {0}.", x];
    options.ModelBindingMessageProvider.ValueMustNotBeNullAccessor =
    (x) => L["Null value is invalid.", x];
    })
    .AddDataAnnotationsLocalization()
    .AddViewLocalization();
    services.Configure<RequestLocalizationOptions>(options =>
    {
    var supportedCultures = new[]{new CultureInfo("en"), new CultureInfo("fa")};
    options.DefaultRequestCulture = new RequestCulture("en", "en");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    });
    }

    Also add this code at beginning of Configure method:

    var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("fa") };
    app.UseRequestLocalization(new RequestLocalizationOptions()
    {
    DefaultRequestCulture = new RequestCulture(new CultureInfo("en")),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
    });

Important Note for ASP.NET Core 2.0

In ASP.NET Core 2.0, model binding message provider properties has got
read only, but a setter method for each property has been added.

For example, to set
ValueIsInvalidAccessor, you should use SetValueIsInvalidAccessor()
method this way:

options.ModelBindingMessageProvider.SetValueIsInvalidAccessor (
(x) => L["The value '{0}' is invalid.", x]);

Return Rails error messages in a language other than English

in rails you have to use localization files present into /app/config/locales folder

For example if you have 2 locales for your app, english and french, you will have 2 YAML files:
/app/config/locales/en.yml

/app/config/locales/fr.yml

The localization keys will be provided by related localization file.
So for example:
/app/config/locales/en.yml

en:
some_error_occurred: "Some error occurred."

/app/config/locales/fr.yml

fr:
some_error_occurred: "Une erreur s'est produite."

So then in your controller or views you can show related message with something like this:

I18n.t('some_error_occurred', locale: :en)

If you don't explicit locale param, current locale will be used.

In your case you should handle the scenario into controller and then render the proper view that contain the related message.

Localization is powerful and to proper understand every aspect you should really read related documentation: http://guides.rubyonrails.org/i18n.html

Ruby on Rails i18n - Want To Translate Custom Messages in Models

Use a symbol for the message:

validates :email, presence:   true, length: { maximum: 60 },
format: { with: valid_email_regex, message: :bad_email },
uniqueness: { case_sensitive: false }

then in the yaml file

[lang]:
activerecord:
errors:
messages:
bad_email: "just ain't right"

If there's a translation specific to this model, it will override the general one above:

[lang]:
activerecord:
errors:
models:
model_name: # or namespace/model_name
attributes:
email:
bad_email: "model-specific message for invalid email"

If you write custom validations, add_error(:email, :bad_email) will do the lookup above, but errors[:email] << :bad_email will not.

Rails Internationalization (I18n) in model validations: Possible or not?

The solution is to NOT include any custom message keys in the models, like...

:message => I18n.t('activerecord.errors.models.my_model.attributes.whatever.please_select_whatever')

The model will then apply the default message keys, for example ":inclusion" in the case of "validates_inclusion_of"

...and in config/locales/en.yml you need to have:

en:
activerecord:
errors:
models:
my_model:
attributes:
whatever:
inclusion: "Please select whatever." # see default key: "inclusion"

for reference, check out the respective Rails guide:

http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models



Related Topics



Leave a reply



Submit