有个业务需求:Salesfroce前端需要下载某个对象当前的页面,需要选择指定语言然后下载内容,比如联系人,下载当前联系人的姓名、电话等字段,需要将字段姓名、电话的标签转为指定的语言(注:不包含值)
1.在Salesfroce的设置搜索“翻译”,找到用户界面-翻译工作台-翻译语言设置,可以设置系统支持的语言。
2.进入自定义标签创建标签,在标签上新增翻译。
3.通过调用CustomLabelTranslation类的getCustomLabelsByLanguage的方法,返回自定义标签指定的翻译文本。
public without sharing class CustomLabelTranslation {
private static final String INSTANCE_URL = Url.getSalesforceBaseUrl().toExternalForm();
private static final String TOOLING_ENDPOINT = '/services/data/v52.0/tooling/query/?q=';
private static final String TOOLING_LABEL_QUERY = 'Select+id,Name,Value,Language+from+ExternalString';
private static final String TOOLING_LABEL_TRANSLATION_QUERY = 'Select+Value,Language,ExternalString.Name+from+ExternalStringLocalization';
private static final String LABEL_WHERE_STRING = '+where+Name+IN+';
private static final String LABEL_TRANSLATION_WHERE_STRING = '+where+ExternalString.Name+IN+';
private static List<Records> externalStringRecords = new List<Records>();
/**
* @Description: label:标签Name,lan:zh_CN中文简体、en_US英语、de德语、ft法语、ja日语、ko韩语、ru俄语、it意大利语、zh_TW中文繁体
* @Author: Zaki
* @CreateDate: 2022-06-08 17:32
* @UpdateDate: 2022-06-08 17:32
*/
public static String getCustomLabelsByLanguage(String label, String lan) {
try {
Map<String, Map<String, String>> customLabelsByLanguage = CustomLabelTranslation.getCustomLabels(new List<String>{label});
Map<String, String> labelMap = customLabelsByLanguage.get(lan);
String re = labelMap.get(label);
return re;
} catch (Exception e) {
return null;
}
}
public static Map<String, Map<String, String>> getCustomLabels(List<String> customLabelNames) {
String externalStringQuery = getExternalStringQuery(customLabelNames);
String externalStringLocalizationQuery = getExternalStringLocalizationQuery(customLabelNames);
makeCustomLabelCallout(externalStringQuery, null);
makeCustomLabelCallout(externalStringLocalizationQuery, null);
Map<String, Map<String, String>> languageToLabels = mapCustomLabelsByLanguage(externalStringRecords);
return languageToLabels;
}
public static void makeCustomLabelCallout(String query, String nextQueryUrl) {
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
req.setHeader('Content-Type', 'application/json');
if(String.isBlank(nextQueryUrl)) {
req.setEndpoint(query);
}
else{
req.setEndpoint(INSTANCE_URL + nextQueryUrl);
}
req.setMethod('GET');
Http h = new Http();
HttpResponse res = h.send(req);
Response response = (Response) JSON.deserialize(res.getBody(), Response.class);
externalStringRecords.addAll(response.records);
if(!response.done){
makeCustomLabelCallout(null, response.nextRecordsUrl);
}
}
private static String getExternalStringQuery(List<String> customLabelNames){
if (customLabelNames != null) {
return INSTANCE_URL + TOOLING_ENDPOINT + TOOLING_LABEL_QUERY + LABEL_WHERE_STRING + formatLabelNamesForQuery(customLabelNames);
}
//Retrieve all labels
return INSTANCE_URL + TOOLING_ENDPOINT + TOOLING_LABEL_QUERY;
}
private static String getExternalStringLocalizationQuery(List<String> customLabelNames){
if (customLabelNames != null) {
return INSTANCE_URL + TOOLING_ENDPOINT + TOOLING_LABEL_TRANSLATION_QUERY + LABEL_TRANSLATION_WHERE_STRING + formatLabelNamesForQuery(customLabelNames);
}
//Retrieve all labels
return INSTANCE_URL + TOOLING_ENDPOINT + TOOLING_LABEL_TRANSLATION_QUERY;
}
private static String formatLabelNamesForQuery(List<String> customLabelNames) {
String value = '(';
for (String s : customLabelNames) {
value += ''' + s + ''' + ',';
}
if (String.isNotBlank(value)) {
value = value.removeEnd(',');
value += ')';
}
return value;
}
public static Map<String, Map<String, String>> mapCustomLabelsByLanguage(List<Records> customLabelRecords) {
Map<String, Map<String, String>> languageToLabelsMap = new Map <String, Map<String, String>>();
for (Records record : customLabelRecords) {
if (String.isNotBlank(record.Language)) {
Map<String, String> customLabels = languageToLabelsMap.get(record.Language);
if (customLabels == null) customLabels = new Map<String, String>();
//Handle scenario where custom label name is coming from lookup to ExternalString
if (record?.ExternalString?.Name != null) {
customLabels.put(record.ExternalString.Name, record.Value);
} else {
customLabels.put(record.Name, record.Value);
}
languageToLabelsMap.put(record.Language, customLabels);
}
}
return languageToLabelsMap;
}
public class Response {
public Integer size;
public Integer totalSize;
public Boolean done;
public String queryLocator;
public String nextRecordsUrl;
public String entityTypeName;
public List<Records> records;
}
public class Attributes {
public String type;
public String url;
}
public class ExternalString {
public Attributes attributes;
public String Name;
}
public class Records {
public Attributes attributes;
public String Id;
public String Name;
public String Language;
public String Value;
public ExternalString ExternalString;
}
}
调用示例:
CustomLabelTranslation.getCustomLabelsByLanguage('Test', 'en_US');
输出结果:
其他思路:
1.在翻译工作台-翻译也可以实现对象的字段翻译,同时还可以指定值的翻译,最终的翻译结果,可以在objectTranslations/Contact-en_US.objectTranslation里查看翻译信息,它的内容是存在CustomObjectTranslation对象中的,所以,我们应该也是可以通过调用Salesforce标准接口去获取翻译文本的,但是,我经历一番波折并没有找到相关的接口,所以也就放弃了这种方法。
2.当我们在翻译工作台对指定标签翻译成指定语言的时候,我们到打开个人设置-我的个人信息-语言与时区-语言,修改成指定语言的时候,我们通过Apex直接输出该对象的字段Label就已经是翻译后的结果了,所以,我们可以通过修改用户的语言,获取到指定的翻译文本后,在将用户的语言修改回来,但是,有个问题就是:用Apex给用户修改语言之后,获取到的文本不一定是翻译后的,因为修改用户语言后,系统将语言翻译过来有延迟,所以需要休眠片刻在获取文本,得到想要的文本后再将用户语言修改回来。这个方法实现如下,但也被我弃用了。
User u = [SELECT LanguageLocaleKey from User where Username='xxx'];
u.LanguageLocaleKey = 'en_US';
update u;
System.debug(YoursObject.getSObjectType().getDescribe().fields.getMap().get('YoursObjectName').getDescribe().getLabel());
u.LanguageLocaleKey = 'zh_CN';
update u;