Pick-list item not translated. I have a controller in an email template to translate dynamically the items in a picklist:


Savepoint sp = Database.setSavepoint();

User currentUser = [SELECT LanguageLocaleKey FROM User WHERE Id =: UserInfo.getUserId()];
currentUser.LanguageLocaleKey = languageToTranslate;
update currentUser;

Opportunity opp = [SELECT toLabel(Phase__c) FROM Opportunity WHERE Id = 'e4u8E6jt00wcgMqQope'];


The code shows that I am changing the language of the current user according to the specified language, after that, I run a query on the opportunity object to get the Phase__c picklist value but the result is not translated.

What am I doing wrong?

Note that I have translated the pick-list items by using the translation workbench.

  • I think problem is with updating user. If you update user in same context then it might not get reflected. can you query opportunity in future method? Commented Nov 19, 2017 at 5:03

2 Answers 2


I ran a piece of anonymous Apex based on the code you provided. The strange thing is that it indeed does change the language correctly and even reflects this in the UserInfo class, but the toLabel() function of SOQL doesn't use the new language.


User currentUser = [SELECT LanguageLocaleKey FROM User WHERE Id =: UserInfo.getUserId()];
currentUser.LanguageLocaleKey = 'NL_nl';
update currentUser;


Opportunity opp = [SELECT toLabel(StageName) FROM Opportunity Limit 1];

First time I run it (I started with English as language), the debug logs show: enter image description here

But the second time I run (so after the language is changed by the first run), it does translate the label: enter image description here

So either the SOQL engine doesn't look at the current UserInfo values, but at the values at the start of the execution context, or this is a bug.

Have you contacted Salesforce support about this?


What you could also do, is use the Schema Describe info to get the labels that correspond to the picklist values you query from your Opportunity record.

Schema.DescribeFieldResult field = Opportunity.Phase__c.getDescribe();
List<Schema.PicklistEntry> picklistValues = field.getPicklistValues();

Go through this list of picklist values and use getLabel() to get the translated value.

  • 1
    I get the same issue using getLabel() :( Commented Nov 22, 2017 at 13:21

I can see that you need to get the translation of a Picklist using Apex

I don't have a solution to your apporoach but I can suggest another workaround to get the translation using PageReference getContent() BUT BE CAREFULL ! "PageReference getContent() and getContentAsPDF() Methods Treated as Callouts", You cannot use it in a Trigger.

I had the same issue with CustomLabel but I found a workaround in this blog post.

I tried implementing the same idea but for picklistValue.

You need to create a VisualForce page like below:

<apex:page controller="PicklistTranslatorController"
    contentType="application/json" showHeader="false" sidebar="false"
    language = "{!lang}"      
     <apex:inputfield value="{!opp.Phase__c}"/>

The VFController:

public class PicklistTranslatorController {
    public String lang {get;set;}
    public String picklistValueToTranslate {get;set;}
    public Opportunity opp {get;set;} 
    public  PicklistTranslatorController(){
       Map<String, String> reqParams = ApexPages.currentPage().getParameters(); 
       lang = reqParams.get('lang');
       picklistValueToTranslate = reqParams.get('picklistValueToTranslate');
       opp = new Opportunity(Phase__c=picklistValueToTranslate);

Now, The idea the is to get the output of the page, as displayed to a user in a web browser using the PageReference.getContent(), you have also to extract the selected value, I used Regular Expressions to extract the selected <option>. Below is an Utilty method to deal with the output:

public static String translatePhasePicklistValue (String picklistValue, String language){
    String translatedPicklistValue=picklistValue;
    Pagereference r = Page.PicklistTranslator;
    r.getParameters().put('picklistValueToTranslate', picklistValue); 
    r.getParameters().put('lang', language); 
    String visualForcePage = r.getContent().toString();
    //Regex to be reviewed, quickly done for test   
    Pattern myPattern = Pattern.compile('<option value="[^"]+.*?(?:selected="selected")>(.*)</option>');
    Matcher myMatcher = myPattern.matcher(visualForcePage);
    if(myMatcher.find  ()){

       System.debug(myMatcher.group(0)); //group 0 is always the whole pattern
       System.debug(myMatcher.group(1)); //group 1 is the second captured group between ()
       translatedPicklistValue = myMatcher.group(1); //It should be the translation of the picklist
        System.debug('##DO NOT MATCH'); //throw exception? or return the untranslated value?
    return translatedPicklistValue;

and finally call it from your code in this way:

String translation = translatePhasePicklistValue(#YOUR_VALUE_HERE,languageToTranslate);

Note that my code can be evolved to deal dynamically with other fields. The drawback is that it will require to call describe API that will eventually take time.

Hope it helps! Akram

  • I am translation inside an email template which counts as a call-out, using PageReference.getContent() will count as a call-out too. That is not allowed. Commented Nov 24, 2017 at 11:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .