How do you interpret variable value as translation key? #548
-
Hi there, I have a use case where want a variable value to be interpreted as translation key. {
"messages": {
"templates": {
"goToLocation": "Please go to {{location}} {{ messages.pointsInTime.{{pointInTime}} }}." // <- As mockup
},
"pointsInTime": {
"now": "now",
"in30mins": "in 30 minutes"
}
}
} Now I could for example have these messages: [
{ template: 'goToLocation', params: { location: 'the kitchen', pointInTime: 'now' } },
{ template: 'goToLocation', params: { location: 'the office', pointInTime: 'in30mins' } }
] Which I would then translate like this in the template: <ng-container *transloco="let t; read: 'messages'>
<div *ngFor="let msg of messages">
{{t(msg.template, msg.params)}}
</div>
</ng-container> The result should be <div>Please go to the kitchen now.</div>
<div>Please go to the office in 30 minutes.</div> Now, this does not work. This way I'd get e.g. "Please go to the kitchen }}." Is there a way to achieve this with transloco? Of course I can go by and create a separate key for each variant, but it would be nice to be able to mix and match like this. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I have one approach now that seems to be working and that is using a custom transpiler. I've extended the functional transpiler (so I have the option to use its functionality) and just replaced every occurance of the variable name with the respective value (with custom match pattern): import { Injectable, Injector } from '@angular/core';
import { FunctionalTranspiler, HashMap, isString, Translation, TranslocoTranspiler } from '@ngneat/transloco';
@Injectable()
export class CustomTranspiler extends FunctionalTranspiler implements TranslocoTranspiler {
constructor(private injector1: Injector) {
super(injector1);
}
transpile(value: any, params: HashMap<any> | undefined, translation: Translation) {
let transpiled = value;
if (isString(value)) {
// pattern: #* ... *#
transpiled = value.replace(/#\*\s*(\w+)\s*\*#/g, (match: string, functionName: string, args: string) => {
// replace variable name with variable value, will be interpolated by default transpiler later on
if (params && params[functionName]) return params![functionName];
else
throw new Error(
`CustomTranspiler: Params ${params ? Object.keys(params) : 'undefined'} does not match variable ${functionName}`
);
});
}
return super.transpile(transpiled, params, translation);
}
} If somebody has a better or simpler solution (e.g. without custom transpiler), I'd like to hear it. |
Beta Was this translation helpful? Give feedback.
I have one approach now that seems to be working and that is using a custom transpiler. I've extended the functional transpiler (so I have the option to use its functionality) and just replaced every occurance of the variable name with the respective value (with custom match pattern):