fix(ivy): template compiler should render correct $localize placeholder names (#32509)
The `goog.getMsg()` function requires placeholder names to be camelCased. This is not the case for `$localize`. Here placeholder names need match what is serialized to translation files. Specifically such placeholder names keep their casing but have all characters that are not in `a-z`, `A-Z`, `0-9` and `_` converted to `_`. PR Close #32509
This commit is contained in:

committed by
Matias Niemelä

parent
9166baf709
commit
ea6a2e9f25
@ -9,7 +9,6 @@ import * as i18n from '../../../i18n/i18n_ast';
|
||||
import * as o from '../../../output/output_ast';
|
||||
|
||||
import {serializeIcuNode} from './icu_serializer';
|
||||
import {i18nMetaToDocStmt, metaFromI18nMessage} from './meta';
|
||||
import {formatI18nPlaceholderName} from './util';
|
||||
|
||||
export function createLocalizeStatements(
|
||||
@ -37,7 +36,7 @@ class MessagePiece {
|
||||
}
|
||||
class LiteralPiece extends MessagePiece {}
|
||||
class PlaceholderPiece extends MessagePiece {
|
||||
constructor(name: string) { super(formatI18nPlaceholderName(name)); }
|
||||
constructor(name: string) { super(formatI18nPlaceholderName(name, /* useCamelCase */ false)); }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2021,13 +2021,15 @@ export function getTranslationDeclStmts(
|
||||
message: i18n.Message, variable: o.ReadVarExpr, closureVar: o.ReadVarExpr,
|
||||
params: {[name: string]: o.Expression} = {},
|
||||
transformFn?: (raw: o.ReadVarExpr) => o.Expression): o.Statement[] {
|
||||
const formattedParams = i18nFormatPlaceholderNames(params, /* useCamelCase */ true);
|
||||
const statements: o.Statement[] = [
|
||||
declareI18nVariable(variable),
|
||||
o.ifStmt(
|
||||
o.variable(NG_I18N_CLOSURE_MODE),
|
||||
createGoogleGetMsgStatements(variable, message, closureVar, formattedParams),
|
||||
createLocalizeStatements(variable, message, formattedParams)),
|
||||
createGoogleGetMsgStatements(
|
||||
variable, message, closureVar,
|
||||
i18nFormatPlaceholderNames(params, /* useCamelCase */ true)),
|
||||
createLocalizeStatements(
|
||||
variable, message, i18nFormatPlaceholderNames(params, /* useCamelCase */ false))),
|
||||
];
|
||||
|
||||
if (transformFn) {
|
||||
|
@ -232,6 +232,11 @@ describe('serializeI18nMessageForGetMsg', () => {
|
||||
.toEqual('Some text {$interpolation} and {$interpolation_1}');
|
||||
});
|
||||
|
||||
it('should serialize interpolation with named placeholder for `GetMsg()`', () => {
|
||||
expect(serialize('{{ valueB + valueC // i18n(ph="PLACEHOLDER NAME") }}'))
|
||||
.toEqual('{$placeholderName}');
|
||||
});
|
||||
|
||||
it('should serialize content with HTML tags for `GetMsg()`', () => {
|
||||
expect(serialize('A <span>B<div>C</div></span> D'))
|
||||
.toEqual('A {$startTagSpan}B{$startTagDiv}C{$closeTagDiv}{$closeTagSpan} D');
|
||||
@ -277,14 +282,14 @@ describe('serializeI18nMessageForLocalize', () => {
|
||||
it('should serialize text with interpolation for `$localize()`', () => {
|
||||
expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }} done')).toEqual({
|
||||
messageParts: ['Some text ', ' and ', ' done'],
|
||||
placeHolders: ['interpolation', 'interpolation_1']
|
||||
placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
|
||||
});
|
||||
});
|
||||
|
||||
it('should serialize text with interpolation at start for `$localize()`', () => {
|
||||
expect(serialize('{{ valueA }} and {{ valueB + valueC }} done')).toEqual({
|
||||
messageParts: ['', ' and ', ' done'],
|
||||
placeHolders: ['interpolation', 'interpolation_1']
|
||||
placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
|
||||
});
|
||||
});
|
||||
|
||||
@ -292,21 +297,27 @@ describe('serializeI18nMessageForLocalize', () => {
|
||||
it('should serialize text with interpolation at end for `$localize()`', () => {
|
||||
expect(serialize('Some text {{ valueA }} and {{ valueB + valueC }}')).toEqual({
|
||||
messageParts: ['Some text ', ' and ', ''],
|
||||
placeHolders: ['interpolation', 'interpolation_1']
|
||||
placeHolders: ['INTERPOLATION', 'INTERPOLATION_1']
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should serialize only interpolation for `$localize()`', () => {
|
||||
expect(serialize('{{ valueB + valueC }}'))
|
||||
.toEqual({messageParts: ['', ''], placeHolders: ['interpolation']});
|
||||
.toEqual({messageParts: ['', ''], placeHolders: ['INTERPOLATION']});
|
||||
});
|
||||
|
||||
|
||||
it('should serialize interpolation with named placeholder for `$localize()`', () => {
|
||||
expect(serialize('{{ valueB + valueC // i18n(ph="PLACEHOLDER NAME") }}'))
|
||||
.toEqual({messageParts: ['', ''], placeHolders: ['PLACEHOLDER_NAME']});
|
||||
});
|
||||
|
||||
|
||||
it('should serialize content with HTML tags for `$localize()`', () => {
|
||||
expect(serialize('A <span>B<div>C</div></span> D')).toEqual({
|
||||
messageParts: ['A ', 'B', 'C', '', ' D'],
|
||||
placeHolders: ['startTagSpan', 'startTagDiv', 'closeTagDiv', 'closeTagSpan']
|
||||
placeHolders: ['START_TAG_SPAN', 'START_TAG_DIV', 'CLOSE_TAG_DIV', 'CLOSE_TAG_SPAN']
|
||||
});
|
||||
});
|
||||
|
||||
@ -346,7 +357,7 @@ describe('serializeI18nMessageForLocalize', () => {
|
||||
'{gender, select, male {male} female {female} other {other}}<div>{gender, select, male {male} female {female} other {other}}</div>'))
|
||||
.toEqual({
|
||||
messageParts: ['', '', '', '', ''],
|
||||
placeHolders: ['icu', 'startTagDiv', 'icu', 'closeTagDiv']
|
||||
placeHolders: ['ICU', 'START_TAG_DIV', 'ICU', 'CLOSE_TAG_DIV']
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user