Gestire le traduzione di un testo in AX è un'operazione molto comune. Abbiamo a disposizione due framework. Il primo è quello che si appoggia sulla tabella LanguageTxt, già presente fin dalle primissime versioni; il secondo è quello che è stato introdotto sulla 2012 e si basa sulla classe SysTranslationHelper. In questo post vediamo come utilizzarli entrambe.
Allo scopo definiamo una tabella codice,descrizione che chiameremo "LILtestTable" con la relativa form omonima.
1)LanguageTxt framework
Per prima cosa dobbiamo creare l'estensione della tabella LanguageTxt ed aggiungere la relation con la nostra tabella (possiamo copiare tutte le proprietà dalle relation già esistenti, si veda l'estensione standard LanguageTxt.Extension) così:
A questo punto nella nostra form basta trascinare nel design il menù item display "LanguageTxt" ed impostare "LILTestTable" nella proprietà "datasource".
Con questo metodo possiamo recuperare la traduzione:
public static FreeTxt txt(
Voucher _code,
LanguageId _languageId = CompanyInfo::languageId())
{
LILTestTable testTable = LILTestTable::find(_code);
LanguageTxt languageTxt = LanguageTxt::find(
testTable.TableId,
testTable.RecId,
_languageId);
return languageTxt.Txt ? languageTxt.Txt : testTable.Description;
}
2)SysTranslationHelper framework
Dobbiamo creare una nuova tabella che chiameremo LILTestTableTranslation fatta così:
Questa nuova tabella và aggiunta come datasource alla form e messa in join deleayed con il datasource principale LILtestTable. Dobbiamo poi scrivere una classe fatta così:
class LILTestTableTranslationHelper extends LedgerDimensionTranslationHelper
{
protected TableId getBackingEntityTranslationTableId()
{
return tableNum(LILTestTableTranslation);
}
protected Array getGetBackingEntityTranslatedFieldIds()
{
Array backingEntityTranslatedFieldIds;
backingEntityTranslatedFieldIds = new Array(Types::Integer);
backingEntityTranslatedFieldIds.value(1, fieldNum(LILTestTable, Description));
return backingEntityTranslatedFieldIds;
}
public static client void main(Args _args)
{
LILTestTableTranslationHelper TranslationHelper;
TranslationHelper = LILTestTableTranslationHelper::newFromArgs(_args);
TranslationHelper.launchTranslationDetailForm();
}
public static client LILTestTableTranslationHelper newFromArgs(Args _args)
{
LILTestTableTranslationHelper TranslationHelper;
LILTestTable LILTestTable;
if ( !(_args && _args.record() is LILTestTable))
{
throw error(strFmt("@SYS134996", tableStr(LILTestTable)));
}
LILTestTable = _args.record() as LILTestTable;
TranslationHelper = new LILTestTableTranslationHelper();
TranslationHelper.parmBackingEntity(LILTestTable);
return TranslationHelper;
}
}
Ho preso la classe STD LedgerDimensionTranslationHelper perchè è una buona base generica che si presta molto all'estensione
Dobbiamo poi creare un menù item action che punta a questa classe ed inserirlo nel design della form:
Con questo metodo possiamo recuperare la traduzione:
public Description localizedDescription(LanguageId _languageId = new xInfo().language())
{
Description description;
LILTestTableTranslation translation;
if(this.RecId)
{
select firstonly translation
where translation.LILTestTable == this.RecId
&& translation.Language == _languageId;
description = translation.Description;
}
if(!description)
{
description = this.Description;
}
return description;
}
Conlusioni:
Come abbiamo visto il primo framework è molto più semplice del primo e di fatto non richiede codice.Lo svantaggio è che richiede di aggiungere ogni volta una nuova relation alla tabella languageTxt.
Un vantaggio che ho riscontrato utilizzando il secondo framework (oltre ad essere più "user friendly")è che avendo una tabella dedicata risulta più semplice creare la relativa entity delle traduzioni