Skip to content
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

Component labels aren't translated in validation messages #150

Open
shawnbot opened this issue Dec 4, 2020 · 1 comment
Open

Component labels aren't translated in validation messages #150

shawnbot opened this issue Dec 4, 2020 · 1 comment
Assignees
Labels
bug Something isn't working translation Translations don't work as expected

Comments

@shawnbot
Copy link
Member

shawnbot commented Dec 4, 2020

Well, this is not great:

The problem here is that even though it's properly translating the error message, formio.js is passing an un-translated string into it:

message(component) {
  //                                        "required" is translated...
  //                                         ↓
  return component.t(component.errorMessage('required'), {
    field: component.errorLabel, // ← but the error label placeholder is not
    data: component.data
  });
}

In this case, it's using the correct required translation ("{{field}} es requerido"), and interpolating the {{field}} placeholder with the un-translated label ("Your name") instead of the translation of the field's label ("Su nombre").

Workaround

I believe the workaround is to add Phrase translations for {key}.validate.customMessage, as formio.js's validation logic appears to prefer the component's validate.customMessage property over the message of the validation(s) that failed. In this case, the name.validate.customMessage Phrase translations could be "Your name is required" in English and "Su nombre es requerido" in Spanish.

Patch

The place to patch this is in the errorLabel getter of the Component class:

  /**
   * Returns the error label for this component.
   * @return {*}
   */
  get errorLabel() {
    return this.t(this.component.errorLabel
      || this.component.label
      || this.component.placeholder
      || this.key);
  }

For our case (Phrase translations with predictable keys), we'd patch it as something like this:

  get errorLabel () {
    const { key, errorLabel, label, placeholder } = this.component
    return this.t([
      `${key}.errorLabel`,
      `${key}.label`,
      `${key}.placeholder`,
      errorLabel || label || placeholder || key
    ])
  }
@shawnbot shawnbot added the bug Something isn't working label Dec 4, 2020
@shawnbot shawnbot self-assigned this Dec 4, 2020
@shawnbot shawnbot added the translation Translations don't work as expected label Dec 4, 2020
@shawnbot
Copy link
Member Author

Another workaround for this might be to pass the field key of the interpolated data through t():

const Component = Formio.Components.components.component
hook(Component.prototype, 't', function (t, [text, params, ...rest]) {
  if (params?.label) {
    params.label = this.i18next.t(params.label)
  }
  return t(text, params, ...rest)
})

This approach would give us more fine-grained control over how any of the interpolated strings are translated. We could even iterate over all the keys of the params object and translate any that are strings. 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working translation Translations don't work as expected
Projects
None yet
Development

No branches or pull requests

1 participant