Search code examples
aurelia

how to translate only part of html page with i18n


i trying to build logic to translate only part of the page(module) with i18n lib.

i have set i18n globally to change language on page when i change language, but i would like to have one module on that page (like some kind of preview for email) on different language which i can change on that module via some dropdown field. Like some kind of scoped i18n.

I'm using aurelia-i18n 1.4.0 version.

is it possible to set <span t="messages.hello_message">hello<span> to watch for local module changes for language and not the global one, but again to use the same translation files as global does.

Did anyone have some similar problem or idea how can I do this? thanks. :)


Solution

  • You can't do that out of the box. When you change the active locale using setLocale the method fires an event and signals an update to binding behaviors https://github.com/aurelia/i18n/blob/master/src/i18n.js#L54. The TCustomAttribute listens for those changes and automatically rerenders bindings. What you could do though is create your own custom attribute as seen here https://github.com/aurelia/i18n/blob/master/src/t.js and override the bind and unbind methods where you define the condition when the update of translations should happen.

    --- Update with example ---

    Ok so here's a small example what I was thinking about, might not be the nicest way but it should do it.

    In your main.js add a new globalResources

    export function configure(aurelia) {
      aurelia.use
        .standardConfiguration()
        .plugin('aurelia-i18n', (instance) => {
          ...
        })
        .globalResources("./foo-custom-attribute") // <-- this here
    

    now create a file foo-custom-attribute.js

    import {TCustomAttribute} from 'aurelia-i18n';
    import {customAttribute} from 'aurelia-framework';
    
    @customAttribute('foo')
    export class FooCustomAttribute extends TCustomAttribute {
      constructor(element, i18n, ea, tparams) {
        super(element, i18n, ea, tparams);
      }
    
      bind() {
        this.params = this.lazyParams();
    
        if (this.params) {
          this.params.valueChanged = (newParams, oldParams) => {
            this.paramsChanged(this.value, newParams, oldParams);
          };
        }
    
        let p = this.params !== null ? this.params.value : undefined;
        this.service.updateValue(this.element, this.value, p);
      }
    
      unbind() {}
    }
    

    This essentially creates a new attribute called foo, which extends the TCustomAttribute and overrides the bind/unbind methods to exclude the signaling and listening to language changed events.

    In your view you can now use

    <span t="demo"></span>
    <span foo="demo"></span>
    

    Toggling the language now will change the t attribute as usual but will keep the foo as it is.