Skip to main content

Compartilhar páginas do Visualforce entre os ambientes Classic e Lightning Experience

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:
  • Citar dois benefícios do compartilhamento de páginas entre o Salesforce Classic e o Lightning Experience.
  • Descrever a diferença entre o contexto de interface de usuário solicitado pelo usuário e o contexto de interface de usuário em que o usuário realmente está.
  • Descrever três maneiras diferentes de testar e determinar o contexto de interface de usuário do usuário atual.

Como compartilhar páginas do Visualforce entre os ambientes Classic e Lightning Experience

Recomendamos que, sempre que possível, crie páginas do Visualforce que se comportem corretamente quer sejam executadas no Salesforce Classic ou no Lightning Experience. São óbvios os benefícios em termos de redução de complexidade no código e na configuração de sua organização. E há uma série de contextos, tais como substituições do Visualforce das ações padrão, para os quais você não tem escolha. Uma substituição de ação sempre usa a mesma página, quer esteja executando no Salesforce Classic, no Lightning Experience ou no aplicativo Salesforce.

No entanto, é perfeitamente razoável querer um comportamento ligeira ou significativamente diferente ou um estilo que seja baseado no contexto da experiência de usuário em que a página é executada. Nesta unidade, veremos diversas formas de criar páginas que funcionem corretamente em todas as experiências de usuário e como seu código pode detectar e fazer alterações para contextos específicos.

Detectar o contexto da experiência de usuário na marcação Visualforce e responder ao mesmo

Utilize as variáveis globais $User.UITheme e $User.UIThemeDisplayed para determinar o contexto da experiência de usuário atual. Você pode usar essas variáveis em expressões do Visualforce para adaptar suas páginas ao Lightning Experience, ao Salesforce Classic e ao aplicativo Salesforce.
Essas variáveis globais retornam uma string que identifica de maneira única o contexto da interface de usuário atual. Os possíveis valores para $User.UITheme e $User.UIThemeDisplayed são os mesmos:
  • Theme1 – Tema obsoleto do Salesforce
  • Theme2 – Tema da interface de usuário do Salesforce Classic 2005
  • Theme3 – Tema da interface de usuário do Salesforce Classic 2010
  • Theme4d – Tema do Salesforce “Lightning Experience” moderno
  • Theme4t – Tema do aplicativo móvel Salesforce
  • Theme4u – Tema de console do Lightning
  • PortalDefault – Tema do Portal de clientes do Salesforce
  • Webstore – Tema do Salesforce AppExchange
A diferença entre as duas variáveis é que $User.UITheme retorna a aparência que o usuário deveria ver, enquanto $User.UIThemeDisplayed retorna a aparência que o usuário realmente vê. Por exemplo, um usuário pode preferir e ter permissões para visualizar a aparência do Lightning Experience, mas se estiver usando um navegador que não dê suporte a essa aparência, por exemplo, versões mais antigas do Internet Explorer, $User.UIThemeDisplayed retornará um valor diferente. Em geral, seu código deve usar $User.UIThemeDisplayed.
A maneira mais simples de se utilizar essas variáveis globais de tema é usá-las em uma expressão booleana, como {! $User.UIThemeDisplayed == "Theme3" }, no atributo rendered de um componente. O componente só será exibido se a página aparecer no contexto da interface de usuário desejado.
<apex:outputText value="This is Salesforce Classic."
    rendered="{! $User.UIThemeDisplayed() == 'Theme3' }"/>
Embora você possa usar essa técnica em elementos da interface de usuário individuais, ela é mais eficiente se você encapsular porções maiores de marcação em um componente <apex:outputPanel> ou um componente em nível de bloco similar e depois criar blocos separados para cada interface de usuário diferente que quiser apresentar. Coloque então o teste de tema no atributo rendered dos blocos, em vez de o colocar nos componentes individuais. Isso não apenas funciona melhor, mas seu código também será menos complicado.
<apex:outputPanel rendered="{! $User.UIThemeDisplayed == 'Theme3' }">
    <apex:outputText value="This is Salesforce Classic."/>
    <apex:outputText value="These are multiple components wrapped by an outputPanel."/>
</apex:outputPanel>
<apex:outputPanel rendered="{! $User.UIThemeDisplayed == 'Theme4d' }">
    <apex:outputText value="Everything is simpler in Lightning Experience."/>
</apex:outputPanel>
Outra estratégia com a qual você pode usar isso é selecionar dinamicamente uma folha de estilo para incluir em sua página e fornecer uma folha de estilo diferente para cada tema. Isso é um pouco mais complicado do que você poderia imaginar, porque a marca <apex:stylesheet> não possui um atributo rendered próprio. Nesse caso, você deve encapsular os componentes da folha de estilo dentro de outro componente que possua um atributo rendered. Aqui está um exemplo de como fornecer uma folha de estilo diferente para cada um dos três temas modernos para os quais o Salesforce oferece suporte.
<apex:page standardController="Account">
    <!-- Salesforce Classic "Aloha" theme -->
    <apex:variable var="uiTheme" value="classic2010Theme"
        rendered="{!$User.UIThemeDisplayed == 'Theme3'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles,
                                         'classic-styling.css')}" />
    </apex:variable>
    <!-- Lightning Desktop theme -->
    <apex:variable var="uiTheme" value="lightningDesktop"
        rendered="{!$User.UIThemeDisplayed == 'Theme4d'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles,
                                         'lightning-styling.css')}" />
    </apex:variable>
    <!-- Salesforce mobile theme -->
    <apex:variable var="uiTheme" value="SalesforceApp"
        rendered="{!$User.UIThemeDisplayed == 'Theme4t'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles,
                                         'mobile-styling.css')}" />
    </apex:variable>
    <!-- Rest of your page -->
    <p>
        Value of $User.UIThemeDisplayed: {! $User.UIThemeDisplayed }
    </p>
</apex:page>

Ir além das noções básicas

Esta é uma maneira incomum de usar <apex:variable>, pois, na verdade, não estamos interessados no valor da variável criada. O que queremos é apenas um componente que não renderize nenhuma saída própria para encapsular o componente <apex:stylesheet>. Você pode pensar nisso como um “empréstimo” de <apex:variable>, de seu atributo rendered, ao componente <apex:stylesheet> encapsulado.

O fato de não estarmos interessados na própria variável é uma boa coisa, pois outro aspecto incomum de se usar o componente <apex:variable> para encapsular outra coisa é que a variável não é criada de fato! Recurso ou bug? Vamos chamá-lo apenas de... comportamento indefinido e evitar usar a variável uiTheme em outros lugares.

Detectando o contexto da experiência de usuário no JavaScript e respondendo ao mesmo

Detectar o contexto da experiência de usuário atual no código JavaScript é importante se você estiver usando muito o JavaScript em suas páginas e em seus aplicativos. É especialmente importante para utilizar a técnica correta para gerenciar a navegação em seu código JavaScript.

Para detectar o que o usuário vê no JavaScript, usamos um método similar para determinar o contexto da experiência do usuário atual no Visualforce. Chame a variável global UITheme.getUITheme() para retornar um valor que identifique o tema da interface do usuário atual.

Aqui o código verifica se o contexto da experiência do usuário atual é o tema do Lightning Experience.

function isLightningDesktop() {
  return UITheme.getUITheme === "Theme4d";
}

Determinando o contexto da experiência de usuário no Apex

Use os métodos de sistema UserInfo.getUiTheme() e UserInfo.getUiThemeDisplayed() para determinar o contexto da experiência de usuário atual no código do Apex. Você pode usá-los quando for necessário que as propriedades ou métodos de ação do seu controlador se comportem de forma diferente em diferentes contextos.
O exemplo a seguir ilustra como usar esses métodos, tornando-os disponíveis pelos métodos getter em uma extensão do controlador.
public with sharing class ForceUIExtension {
    // Empty constructor, required for Visualforce controller extension
    public ForceUIExtension(ApexPages.StandardController controller) { }
    // Simple accessors for the System.UserInfo theme methods
    public String getContextUserUiTheme() {
        return UserInfo.getUiTheme();
    }
    public String getContextUserUiThemeDisplayed() {
        return UserInfo.getUiThemeDisplayed();
    }
}
Obviamente, você poderia trabalhar com os valores do seu código do Apex, em vez de retornar diretamente os resultados de chamadas de método.
Esses métodos do sistema Apex retornam uma string que identifica de maneira única o contexto da interface de usuário atual. Os possíveis valores retornados por esses métodos são os mesmos que os retornados pelas variáveis globais $User.UITheme e $User.UIThemeDisplayed.
  • Theme1 – Tema obsoleto do Salesforce
  • Theme2 – Tema da interface de usuário do Salesforce Classic 2005
  • Theme3 – Tema da interface de usuário do Salesforce Classic 2010
  • Theme4d – Tema do Salesforce “Lightning Experience” moderno
  • Theme4t – Tema do aplicativo móvel Salesforce
  • Theme4u – Tema de console do Lightning
  • PortalDefault – Tema do Portal de clientes do Salesforce
  • Webstore – Tema do Salesforce AppExchange

Usar estes métodos no código do controlador do lado do servidor deve ser raro, pelo menos em comparação a fornecer uma marcação Visualforce ou código JavaScript diferente. Recomenda-se que o código do seu controlador e extensão do controlador seja neutro em termos de contexto UX. Deixe que seu código front-end, quer no Visualforce quer no JavaScript, lide com as diferenças de interface de usuário.

Consultando no Lightning Experience via SOQL e API Access

Embora não recomendemos essa técnica, você pode consultar a experiência de usuário preferencial do usuário atual usando diretamente o SOQL.
A consulta SOQL básica é apresentada a seguir.
SELECT UserPreferencesLightningExperiencePreferred FROM User WHERE Id = 'CurrentUserId'
O resultado é um valor de preferência bruto, que você precisa converter em algo utilizável.
Temos aqui a página mais simples possível do Visualforce que executa a consulta SOQL acima e exibe o resultado na página.
<apex:page>
<script src="/soap/ajax/36.0/connection.js" type="text/javascript"></script>
<script type="text/javascript">
    // Query for the preference value
    sforce.connection.sessionId = '{! $Api.Session_ID }';
    var uiPrefQuery = "SELECT Id, UserPreferencesLightningExperiencePreferred " +
                      "FROM User WHERE Id = '{! $User.Id }'";
    var userThemePreferenceResult = sforce.connection.query(uiPrefQuery);
    // Display the returned result on the page
    document.addEventListener('DOMContentLoaded', function(event){
        document.getElementById('userThemePreferenceResult').innerHTML =
            userThemePreferenceResult;
    });
</script>
<h1>userThemePreferenceResult (JSON)</h1>
<pre><span id="userThemePreferenceResult"/></pre>
</apex:page>

Não recomendamos consultar a preferência de Lightning Experience do usuário de forma direta. O resultado diz qual é a configuração preferida atual do usuário, e não qual experiência de usuário realmente está em sua tela. Há vários casos de uso em que o valor de preferência pode não refletir a experiência de usuário que realmente está sendo fornecida. Para determinar a experiência de usuário real que é fornecida na solicitação atual, utilize $User.UIThemeDisplayed ou UserInfo.getUiThemeDisplayed().

Compartilhe seu feedback do Trailhead usando a Ajuda do Salesforce.

Queremos saber sobre sua experiência com o Trailhead. Agora você pode acessar o novo formulário de feedback, a qualquer momento, no site Ajuda do Salesforce.

Saiba mais Continue compartilhando feedback