Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Microsoft Dataverse oferece suporte a vários idiomas. Se desejar que a solução seja instalada para organizações que incluam diferentes idiomas base ou que tenham vários idiomas provisionados, leve isto em conta ao planejar a sua solução. A tabela a seguir lista as táticas para uso em conjunto com os componentes da solução que podem ser incluídos em uma solução que oferece suporte a vários idiomas.
| Tática | Tipo de componente da solução |
|---|---|
| Recursos da web de string (RESX) | Recursos da Web |
| Etiquetas incorporadas | Navegação de Aplicativo (SiteMap) Faixas de opções |
| Exportar e importar traduções | Atributos Gráficos Painéis Entity Relacionamentos da Entidade Formulários Mensagens Conjuntos de Opções Visualizações |
| Localização em strings de idioma base | Modelos de Contrato Funções de Conexão Processos (Fluxo de trabalho) Direitos de Acesso Perfis de Segurança de Campo |
| Localização não necessária | Etapas de Processamento de Mensagens do SDK Pontos de Extremidade de Serviço |
| Componente separado para cada idioma | Modelos de Artigo Modelos de Email Modelos de Mala Direta Relatórios Caixas de Diálogo |
| Use recursos da web XML como recursos de linguagem | Assemblies de Plug-in |
As seções a seguir fornecem detalhes adicionais de cada tática.
Recursos da Web de cadeia de caracteres (RESX)
Com recursos da Web de cadeia de caracteres (RESX) adicionados ao Dataverse, os desenvolvedores têm uma opção mais robusta para criar recursos da Web que ofereçam suporte a vários idiomas. Mais informações Recursos da Web de cadeia de caracteres (RESX).
Rótulos inseridos
Cada um dos componentes da solução que usa esta tática exige que todo o texto localizado esteja incluído no componente da solução.
Faixas de opções
Quando o pacote de idiomas é instalado, a faixa de opções do aplicativo exibe automaticamente o texto localizado para todo o texto padrão na faixa de opções. Os rótulos do sistema são definidos em um valor do atributo ResourceId, que serve apenas para uso interno.
Ao adicionar seu próprio texto, use o elemento <LocLabels> para fornecer o texto localizado nos idiomas para os quais você oferece suporte. Mais informações: Usar Rótulos Localizados com Faixas de Opções
SiteMap
Quando o pacote de idiomas é instalado, o texto padrão da barra de navegação do aplicativo exibe automaticamente o texto localizado.
Para substituir o texto padrão ou fornecer o seu próprio texto, use o elemento <Titles>.
O elemento Titles deve conter um elemento <Title>, que contenha o texto localizado em todos os idiomas com suporte pela solução.
Se um elemento Title não estiver disponível no idioma preferido do usuário, o título que corresponde ao idioma base da organização é exibido.
O elemento <SubArea> permite transmitir a preferência de idioma do usuário com o parâmetro userlcid, para que o conteúdo que é o destino do atributo SubArea.Url possa saber a preferência de idioma do usuário e ajustar de acordo.
Mais informações: Passando Parâmetros para uma URL Usando o SiteMap
Importar e exportar traduções
Os rótulos localizáveis dos componentes da solução apresentados na tabela a seguir podem ser exportados para localização.
| Entidades | Atributos | Relações |
| Conjuntos de opções globais | Mensagens de Entidade | Formulários de entidade |
| Exibições de entidade (SavedQuery) | Gráficos | Painéis |
Como traduzir rótulos e cadeias de exibição
Somente é possível realizar personalizações no aplicativo usando o idioma base. Portanto, quando desejar fornecer rótulos e cadeias de exibição localizados para essas personalizações, será necessário exportar o texto dos rótulos, para que eles possam ser localizados em todos os outros idiomas habilitados para a organização. Use as seguintes etapas:
Verifique se a organização para a qual você está trabalhando tem todos os pacotes multilíngues instalados e idiomas provisionados para os idiomas nos quais você deseja fornecer traduções.
Crie a solução e modifique os componentes.
Ao concluir o desenvolvimento da solução, use a funcionalidade “Exportar traduções”. Isso gera uma planilha do Office Excel (CrmTranslations.xml) que contém todos os rótulos que precisam de tradução.
Na planilha, forneça as traduções correspondentes.
Importe as traduções de volta para a mesma organização do Dataverse usando a funcionalidade “Importar traduções” e publique suas alterações.
Na próxima vez em que a solução for exportada, ela levará todas as traduções fornecidas.
Quando uma solução é importada, os rótulos para os idiomas que não estão disponíveis no sistema de destino são descartados e um aviso é registrado.
Se os rótulos do idioma base do sistema de destino não forem fornecidos no pacote da solução, os rótulos do idioma base da origem serão usados em seu lugar. Por exemplo, se você importar uma solução que contenha rótulos em inglês e francês, com inglês como o idioma base, mas o sistema de destino tiver japonês e francês, com japonês como o idioma base, os rótulos em inglês serão usados em vez dos rótulos em japonês. Os rótulos dos idiomas base não podem ser nulos ou vazios.
Como exportar traduções
Antes de exportar traduções, é necessário instalar primeiro os pacotes de idiomas e provisionar todos os idiomas que você deseja localizar. É possível exportar as traduções no aplicativo Web ou usando a mensagem ExportTranslationRequest. Para obter mais informações, consulte Exportar uma entidade personalizada e um texto de campo para tradução.
Como traduzir um texto
Ao abrir o arquivo CrmTranslations.xml no Office Excel, você verá as três planilhas listadas na tabela a seguir.
| Planilha | Descrição |
|---|---|
| Informações | Exibe informações sobre a organização e a solução das quais os rótulos e as cadeias de caracteres foram exportados. |
| Cadeias de Exibição | Exibe as cadeias de caracteres que representam o texto das mensagens associadas a um componente dos metadados. Esta tabela inclui as mensagens de erro e as cadeias de caracteres usadas para os elementos da faixa de opções do sistema. |
| Rótulos Localizados | Exibe todo o texto de todos os rótulos do componentes dos metadados. |
É possível enviar este arquivo para um especialista em idiomas, agência de tradução ou empresa de localização. Eles precisarão fornecer cadeias de caracteres localizadas para as células vazias.
Nota
Para as entidades personalizadas, existem alguns rótulos comuns que são compartilhados com as entidades do sistema, como Data de criação ou Criado por. Como você já instalou e provisionou os idiomas, se você exportar os idiomas para a solução padrão, é possível fazer a correspondência de alguns rótulos das entidades personalizadas com o texto localizado dos rótulos idênticos usados por outras entidades. Isso pode reduzir o custo da localização e melhorar a consistência.
Após a localização do texto das planilhas, adicione os arquivos CrmTranslations.xml e [Content_Types].xml a um único arquivo .zip compactado. Agora você pode importar este arquivo.
Se preferir trabalhar com os arquivos exportados de forma programática, como um documento XML, consulte Suporte a Padrões do Word, Excel e PowerPoint para obter informações sobre os esquemas usados por esses arquivos.
Como importar o texto traduzido
Importante
Só é possível importar o texto traduzido de volta para a mesma organização da qual ele foi exportado.
Depois de exportar e traduzir o texto personalizado da entidade ou do atributo, é possível importar as cadeias de texto traduzidas no aplicativo Web usando a mensagem ImportTranslationRequest. O arquivo que você importar deve ser um arquivo compactado que contém o arquivo CrmTranslations.xml e [Content_Types].xml na raiz. Para obter mais informações, consulte Importar uma entidade e um texto de campo traduzidos.
Após a importação das traduções concluídas, o texto personalizado será exibido para os usuários que trabalham nos idiomas para os quais você traduziu o texto.
Nota
O Dataverse não pode importar texto traduzido que possua mais de 500 caracteres. Se algum dos itens do arquivo de tradução ultrapassar 500 caracteres, haverá uma falha no processo de importação. Se isso acontecer, revise a linha do arquivo que causou a falha, reduza a quantidade de caracteres e tente importar novamente.
Como há suporte para a personalização somente no idioma base, talvez você esteja trabalhando no Dataverse com o idioma base definido como sua preferência de idioma. Para verificar se o texto traduzido é exibido, é necessário alterar sua preferência de idioma para a interface do usuário do Dataverse. Para executar trabalho adicional de personalização, você deve retornar para o idioma base.
Localização nas cadeias de caracteres do idioma base
Alguns componentes da solução não oferecem suporte a vários idiomas. Esses componentes incluem nomes ou textos que podem ser significativos em um idioma específico. Se você criar uma solução em um idioma específico, defina estes componentes da solução para o idioma base da organização pretendida.
Se você precisar oferecer suporte a vários idiomas, uma das táticas é incluir a localização nas cadeias de caracteres do idioma base. Por exemplo, se você tiver a Função de conexão chamada “Amigo” e precisar oferecer suporte para inglês, espanhol e alemão, é possível usar o texto “Friend (Amigo/Freund)” como o nome da função de conexão. Devido a problemas de tamanho de texto, existem limitações no número de idiomas que podem ter suporte com esta tática.
Alguns componentes da solução deste grupo só serão visíveis pelos administradores. Como a personalização do sistema só pode ser feita no idioma base da organização, não é necessário fornecer versões com vários idiomas. Funções de segurança e Perfil de Segurança de Campo componentes pertencem a este grupo.
Modelos de Contrato fornecer uma descrição de um tipo de contrato de serviço. Eles exigem um texto para os campos Nome e Abreviação. Considere usar nomes e abreviações que sejam exclusivos e adequados para todos os usuários da organização.
Funções de conexão dependem de uma pessoa selecionando categorias e nomes descritivos de Função de Conexão. Como eles podem ser relativamente curtos, é recomendável incluir a localização nas cadeias de caracteres do idioma base.
Processos (Fluxos de Trabalho) que são iniciados para eventos podem funcionar bem, desde que não precisem atualizar registros com texto a ser localizado. É possível usar um assembly de fluxos de trabalho, para que a lógica que pode ser aplicada ao texto localizado possa usar a mesma estratégia que os assemblies de plug-ins (Usar os Recursos da Web em XML como Recursos de Idiomas).
Fluxos de trabalho sob demanda exigem um nome para que as pessoas possam selecioná-los. Além de incluir a localização no nome do fluxo de trabalho sob demanda, outra tática é criar vários fluxos de trabalho com nomes localizados para cada um deles chamar o mesmo processo secundário. No entanto, todos os usuários visualizarão a lista completa de fluxos de trabalho sob demanda, não somente os que estiverem no idioma de interface preferido do usuário.
Localização não necessária
Etapa de processamento de mensagens do SDK e Ponto final do serviço os componentes da solução não expõem texto localizável aos usuários. Se for necessário que esses componentes tenham nomes e descrições que correspondam ao idioma base da organização, você poderá criar e exportar uma solução gerenciada com nomes e descrições nesse idioma.
Componente separado para cada idioma
Os seguintes componentes da solução podem incluir uma quantidade considerável de texto que precisará ser localizado:
Modelos de Artigo
Modelos de Email
Modelos de Mala Direta
Relatórios
Caixas de Diálogo
Para estes tipos de componentes da solução, a tática recomendável é criar componentes separados para cada idioma. Isso significa criar geralmente uma solução gerenciada base que contenha os componentes básicos da solução e, em seguida, uma solução gerenciada separada que contenha esses componentes da solução para cada idioma. Após a instalação da solução base, os clientes podem instalar as soluções gerenciadas para os idiomas provisionados para a organização.
Diferentemente dos Processos (Fluxos de trabalho), é possível criar Diálogos que refletirão as configurações atuais do idioma preferido do usuário e exibirão os diálogos somente aos usuários desse idioma.
Crie uma caixa de diálogo localizada
Instale o pacote de idiomas correto e provisione o idioma.
Para obter mais informações, consulte Instruções de instalação do pacote de idiomas.
Altere suas opções pessoais para especificar o Idioma de interface do usuário do idioma desejado para o diálogo.
Acesse Configurações e no grupo Centro de Processos selecione Processos.
Clique em Novo e crie o diálogo no idioma especificado.
Depois de criar o diálogo, altere suas opções pessoais para especificar o idioma base da organização.
Ao usar o idioma base da organização, é possível acessar a área Soluções em Configurações e adicionar o diálogo localizado como parte de uma solução.
O diálogo criado em outro idioma é exibido somente para usuários que exibem o Dataverse nesse idioma.
Usar os recursos da Web em XML como recursos de idiomas
Os componentes da solução do assembly de plug-ins podem enviar mensagens para um usuário final acionando uma InvalidPluginExecutionException, além de criar e atualizar registros. Diferentemente dos recursos da Web do Silverlight, os plug-ins não podem usar os arquivos de recursos.
Quando um plug-in exigir o texto localizado, é possível usar um recurso da Web em XML para armazenar as cadeias de caracteres localizadas, para que o plug-in possa acessá-las quando necessário. A estrutura do XML é opção sua, mas talvez você queira acompanhar a estrutura usada por arquivos de Recursos do ASP.NET (.resx) para criar recursos da Web em XML separados para cada idioma. Por exemplo, a seguir, temos um recurso da Web em XML chamado localizedString.en_US, que acompanha o padrão usado por arquivos . resx.
<root>
<data name="ErrorMessage">
<value>There was an error completing this action. Please try again.</value>
</data>
<data name="Welcome">
<value>Welcome</value>
</data>
</root>
O código a seguir mostra como uma mensagem localizada pode ser transmitida de volta em um plug-in para exibir uma mensagem para um usuário. Ele serve para o estágio de pré-validação de um evento Delete da entidade Account:
protected void ExecutePreValidateAccountDelete(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
int OrgLanguage = RetrieveOrganizationBaseLanguageCode(localContext.OrganizationService);
int UserLanguage = RetrieveUserUILanguageCode(localContext.OrganizationService,
localContext.PluginExecutionContext.InitiatingUserId);
String fallBackResourceFile = "";
switch (OrgLanguage)
{
case 1033:
fallBackResourceFile = "new_localizedStrings.en_US";
break;
case 1041:
fallBackResourceFile = "new_localizedStrings.ja_JP";
break;
case 1031:
fallBackResourceFile = "new_localizedStrings.de_DE";
break;
case 1036:
fallBackResourceFile = "new_localizedStrings.fr_FR";
break;
case 1034:
fallBackResourceFile = "new_localizedStrings.es_ES";
break;
case 1049:
fallBackResourceFile = "new_localizedStrings.ru_RU";
break;
default:
fallBackResourceFile = "new_localizedStrings.en_US";
break;
}
String ResourceFile = "";
switch (UserLanguage)
{
case 1033:
ResourceFile = "new_localizedStrings.en_US";
break;
case 1041:
ResourceFile = "new_localizedStrings.ja_JP";
break;
case 1031:
ResourceFile = "new_localizedStrings.de_DE";
break;
case 1036:
ResourceFile = "new_localizedStrings.fr_FR";
break;
case 1034:
ResourceFile = "new_localizedStrings.es_ES";
break;
case 1049:
ResourceFile = "new_localizedStrings.ru_RU";
break;
default:
ResourceFile = fallBackResourceFile;
break;
}
XmlDocument messages = RetrieveXmlWebResourceByName(localContext, ResourceFile);
String message = RetrieveLocalizedStringFromWebResource(localContext, messages, "ErrorMessage");
throw new InvalidPluginExecutionException(message);
}
protected static int RetrieveOrganizationBaseLanguageCode(IOrganizationService service)
{
QueryExpression organizationEntityQuery = new QueryExpression("organization");
organizationEntityQuery.ColumnSet.AddColumn("languagecode");
EntityCollection organizationEntities = service.RetrieveMultiple(organizationEntityQuery);
return (int)organizationEntities[0].Attributes["languagecode"];
}
protected static int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)
{
QueryExpression userSettingsQuery = new QueryExpression("usersettings");
userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);
if (userSettings.Entities.Count > 0)
{
return (int)userSettings.Entities[0]["uilanguageid"];
}
return 0;
}
protected static XmlDocument RetrieveXmlWebResourceByName(LocalPluginContext context, string webresourceSchemaName)
{
context.TracingService.Trace("Begin:RetrieveXmlWebResourceByName, webresourceSchemaName={0}", webresourceSchemaName);
QueryExpression webresourceQuery = new QueryExpression("webresource");
webresourceQuery.ColumnSet.AddColumn("content");
webresourceQuery.Criteria.AddCondition("name", ConditionOperator.Equal, webresourceSchemaName);
EntityCollection webresources = context.OrganizationService.RetrieveMultiple(webresourceQuery);
context.TracingService.Trace("Webresources Returned from server. Count={0}", webresources.Entities.Count);
if (webresources.Entities.Count > 0)
{
byte[] bytes = Convert.FromBase64String((string)webresources.Entities[0]["content"]);
// The bytes would contain the ByteOrderMask. Encoding.UTF8.GetString() does not remove the BOM.
// Stream Reader auto detects the BOM and removes it on the text
XmlDocument document = new XmlDocument();
document.XmlResolver = null;
using (MemoryStream ms = new MemoryStream(bytes))
{
using (StreamReader sr = new StreamReader(ms))
{
document.Load(sr);
}
}
context.TracingService.Trace("End:RetrieveXmlWebResourceByName , webresourceSchemaName={0}", webresourceSchemaName);
return document;
}
else
{
context.TracingService.Trace("{0} Webresource missing. Reinstall the solution", webresourceSchemaName);
throw new InvalidPluginExecutionException(String.Format("Unable to locate the web resource {0}.", webresourceSchemaName));
return null;
// This line never reached
}
}
protected static string RetrieveLocalizedStringFromWebResource(LocalPluginContext context, XmlDocument resource, string resourceId)
{
XmlNode valueNode = resource.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "./root/data[@name='{0}']/value", resourceId));
if (valueNode != null)
{
return valueNode.InnerText;
}
else
{
context.TracingService.Trace("No Node Found for {0} ", resourceId);
throw new InvalidPluginExecutionException(String.Format("ResourceID {0} was not found.", resourceId));
}
}