Partager via


Créer des solutions qui prennent en charge différentes langues.

Cette rubrique s’applique à Dynamics 365 Customer Engagement (on-premises). Pour la version Power Apps de cette rubrique, consultez : Créer des solutions qui prennent en charge différentes langues.

Dynamics 365 for Customer Engagement prend en charge plusieurs langues. Pour installer votre solution pour les organisations qui incluent différentes langues de base ou qui ont plusieurs langues, tenez-en compte lorsque vous planifiez votre solution. Le tableau suivant répertorie la tactique à utiliser avec des composants de solution à inclure dans une solution qui accepte plusieurs langues.

Tactique Type de composant de solution
Ressources web de chaîne (RESX) Ressources web
Étiquettes imbriquées Navigation dans l’application (SiteMap)
Rubans
Exporter et importer des traductions Attributs
Graphiques
Tableau de bord
Entité
Entité-relation
Formulaires
Messages
Groupes d’options
Vues
Localisation en chaînes de la langue de base Modèles de contrats
Rôles de connexion
Processus (Workflow)
Rôles de sécurité
Profils de sécurité de champ
Localisation facultative Étapes de traitement du message SDK
Points de terminaison de service
Composant distinct pour chaque langue Modèles d’article
Modèles de courr. électr.
Modèles de publipostage
Rapports
Boîtes de dialogue
Utiliser des ressources web XML comme ressources linguistiques Assemblys du plug-in

Les sections suivantes fournissent des informations supplémentaires pour chaque tactique.

Ressources web de chaîne (RESX)

Lorsque les ressources web de chaîne (RESX) sont ajoutées avec les applications Dynamics 365 for Customer Engagement version 9.0, les développeurs ont une option plus robuste pour créer des ressources web qui prennent en charge plusieurs langues. Pour plus d’informations, voir Ressources web de chaîne (RESX).

Pour les versions antérieures, voir Option développeur

Étiquettes imbriquées

Chaque composant de solution qui utilise cette tactique nécessite que tout texte localisé soit inclus dans le composant de solution.

Rubans

Lorsqu’un module linguistique est installé, le ruban de l’application affiche automatiquement le texte traduit pour tout le texte par défaut dans le ruban. Les étiquettes système sont définies dans une valeur d’attribut ResourceId destinée uniquement à une utilisation interne. Lorsque vous ajoutez votre propre texte, vous devez utiliser l’élément <LocLabels> pour fournir du texte localisé pour les langues que vous prenez en charge. Pour plus d’informations : Utiliser les étiquettes localisées avec des rubans

SiteMap

Lorsqu’un module linguistique est installé, le texte par défaut dans la barre de navigation de l’application affiche automatiquement le texte localisé. Pour remplacer le texte par défaut ou fournir votre propre texte, utilisez l’élément <Titles>. L’élément Titles doit contenir un élément <Title> contenant le texte localisé pour toutes les langues prises en charge par votre solution. Si un élément Title n’est pas disponible pour la langue par défaut de l’utilisateur, le titre correspondant à la langue de base de l’organisation est affiché.

L’élément <SubArea> permet de passer la préférence de langue de l’utilisateur à l’aide du paramètre userlcid afin que le contenu qui est la cible de l’attribut SubArea.Url puisse être informé de la préférence de langue de l’utilisateur et ajuster en conséquence. Pour plus d’informations, voir Transmission de paramètres à une URL à l’aide de SiteMap.

Exporter et importer des traductions

Les étiquettes localisables pour les composants de solution du tableau suivant peuvent être exportées en vue de leur localisation.

  • Entités
  • Attributs
  • Relations
  • Groupe d’options généraux
  • Messages de l’entité
  • Formulaires d’entités
  • Vues d’entités (SavedQuery)
  • Graphiques
  • Tableau de bord

Traduction des étiquettes et des chaînes d’affichage

Vous ne pouvez effectuer de personnalisations dans l’application qu’en utilisant la langue de base. Par conséquent, si vous souhaitez fournir les étiquettes et les chaînes d’affichage localisées correspondant à ces personnalisations, vous devez exporter le texte des étiquettes pour qu’elles puissent être localisées pour les autres langues activées pour l’organisation. Effectuez les opérations suivantes :

  1. Assurez-vous que l’organisation sur laquelle vous travaillez a tous les packs d’interface utilisateur multilingue installés et les langues approvisionnées pour lesquelles vous souhaitez fournir des traductions.

  2. Créez votre solution et modifiez les composants.

  3. Après avoir terminé de développer votre solution, utilisez la fonctionnalité « Exporter les traductions ». Cette opération génère une feuille de calcul Office Excel (CrmTranslations.xml) qui contient toutes les étiquettes qui doivent être traduites.

  4. Dans la feuille de calcul, fournissez les traductions correspondantes.

  5. Réimportez les traductions dans la même organisation Dynamics 365 Customer Engagement (on-premises) à l’aide de la fonctionnalité « Importer les traductions » et publiez vos modifications.

  6. La prochaine fois que la solution sera exportée, elle conservera toutes les traductions que vous avez fournies.

    Lorsqu’une solution est importée, les étiquettes pour les langues non disponibles dans le système cible sont ignorées et un avertissement est consigné.

    Si les étiquettes pour la langue de base du système cible ne sont pas disponibles dans le package de solution, les étiquettes de la langue de base de la source sont utilisées à la place. Par exemple, si vous importez une solution contenant les étiquettes pour l’anglais et le français avec l’anglais comme langue de base mais que le système cible a le japonais et le français avec le japonais comme langue de base, les étiquettes anglaises sont utilisées au lieu des étiquettes japonaises. Les étiquettes des langues de base ne peuvent pas être null ou vides.

Exportation des traductions

Avant d’exporter des traductions, vous devez commencer par installer les modules linguistiques et regrouper toutes les langues que vous voulez localiser. Vous pouvez exporter les traductions dans l’application web ou en utilisant le message ExportTranslationRequest. Pour plus d’informations, voir Exportation d’une entité personnalisée et d’un texte de champ à convertir.

Traduction d’un texte

Lorsque vous ouvrez le fichier CrmTranslations.xml dans Excel, vous voyez les trois feuilles de calcul répertoriées dans le tableau suivant.

Feuille de calcul Description
Informations Affiche les informations sur l’organisation et la solution depuis lesquelles les étiquettes et chaînes ont été exportées.
Chaînes d’affichage Chaînes d’affichage représentant le texte de tous les messages associés à un composant métadonnées. Ce tableau contient des messages d’erreur et des chaînes qui sont utilisés pour les éléments de ruban système.
Étiquettes localisées Affiche le texte intégral des étiquettes de composant métadonnées.

Vous pouvez envoyer ce fichier à un linguiste, à une agence de traduction ou à une société de localisation. Ils doivent fournir des chaînes localisées pour les cellules vides.

Note

Pour les entités personnalisées, certaines étiquettes courantes sont partagées avec les entités système, comme Créé le ou Créé par. Comme vous avez déjà installé et mis en service les langues, si vous exportez des langues pour la solution par défaut, vous pouvez probablement mettre en correspondance certaines étiquettes de vos entités personnalisées avec le texte traduit pour les étiquettes identiques utilisées par d’autres entités. Cela peut réduire les coûts de localisation et améliorer la cohérence.

Une fois que le texte présent dans les feuilles de calcul a été localisé, ajoutez les fichiers CrmTranslations.xml et [Content_Types].xml à un même fichier .zip compressé. Vous pouvez maintenant importer ce fichier.

Si vous préférez utiliser les fichiers exportés par programme comme document XML, consultez Schémas de référence XML Office 2003 pour plus d’informations sur les schémas utilisés par ces fichiers.

Importation d’un texte traduit

Important

Vous pouvez uniquement réimporter du texte traduit dans la même organisation d’où il a été exporté.

Après avoir exporté le texte d’entité ou d’attribut personnalisé et l’avoir fait traduire, vous pouvez importer les chaînes de texte traduites dans l’application web en utilisant le message ImportTranslationRequest. Le fichier à importer doit être un dossier compressé contenant le fichier CrmTranslations.xml et le fichier [Content_Types].xml à la racine. Pour plus d’informations, consultez Importation d’un texte de champ et d’entité traduit.

Après avoir importé les traductions terminées, le texte personnalisé s’affiche pour les utilisateurs qui travaillent dans les langues dans lesquelles le texte a été traduit.

Note

Dynamics 365 Customer Engagement (on-premises) ne peut pas importer du texte traduit dépassant 500 caractères. Si un des éléments de votre fichier de traductions dépasse 500 caractères, le processus d’importation échoue. Dans ce cas, vérifiez la ligne du fichier à l’origine de l’échec, réduisez le nombre de caractères et réessayez.

La personnalisation n’étant possible que dans la langue de base, vous serez peut-être amené à travailler dans Dynamics 365 Customer Engagement (on-premises) avec la langue de base définie comme préférence de langue. Pour vérifier que le texte traduit s’affiche, vous devez changer de préférence de langue pour l’interface utilisateur de Dynamics 365 Customer Engagement (on-premises). Si vous souhaitez effectuer des personnalisations supplémentaires, vous devez revenir dans la langue de base.

Localisation en chaînes de la langue de base

Certains composants de solution ne prennent pas en charge plusieurs langues. Ces composants comprennent les noms ou le texte qui ne peuvent avoir de sens que dans une langue spécifique. Si vous créez une solution pour une langue spécifique, définissez ces composants de solution pour la langue de base prévue pour l’organisation.

Si vous devez prendre en charge plusieurs langues, une tactique consiste à inclure la localisation dans les chaînes de la langue de base. Par exemple, si vous avez un rôle de connexion nommé « Ami » et que vous devez prendre en charge l’anglais, l’espagnol et l’allemand, vous pouvez utiliser le texte « Ami (Amigo/Freund) » comme nom du rôle de connexion. En raison des problèmes de longueur de texte, il existe des limitations quant au nombre de langues qui peuvent être prises en charge avec cette tactique.

Certains composants de solution appartenant à ce groupe sont uniquement visibles par les administrateurs. Comme la personnalisation du système ne peut être effectuée que dans la langue de base de l’organisation, il n’est pas nécessaire de fournir plusieurs versions linguistiques. Les composants Rôles de sécurité et Profil de sécurité de champ appartiennent à ce groupe.

Les Modèles de contrat fournissent une description du type de contrat de service. Ils nécessitent du texte pour les champs Nom et Abréviation. Vous devez penser à utiliser des noms et abréviations uniques et appropriés pour tous les utilisateurs de l’organisation.

Les rôles de connexion dépendent d’une personne qui sélectionne des catégories et noms de rôle de connexion descriptifs. Étant donné que ceux-ci peuvent être relativement courts, il est recommandé d’inclure la localisation dans les chaînes en langue de base.

Les processus (workflows) qui sont initialisés pour les événements peuvent bien fonctionner tant qu’ils n’ont pas besoin de mettre à jour des enregistrements avec du texte qui doit être localisé. Il est possible d’utiliser un assembly de workflow afin que la logique qui peut s’appliquer au texte localisé puisse utiliser la même stratégie que les assemblys de plug-in (Utiliser des ressources web XML comme ressources linguistiques).

Les workflows à la demande ont besoin d’avoir un nom pour pouvoir être sélectionnés. En plus d’inclure la traduction dans le nom du workflow à la demande, une autre tactique consiste à créer plusieurs workflows avec des noms localisés qui appellent tous le même processus enfant. Toutefois, tous les utilisateurs verront la liste complète des workflows à la demande, pas simplement ceux de leur langue d’interface par défaut de l’utilisateur.

Localisation facultative

Les composants de solution Étape de traitement du message SDK et Point de terminaison de service n’exposent pas le texte localisable aux utilisateurs. S’il est important que ces composants aient des noms et des descriptions qui correspondent à la langue de base de l’organisation, vous pouvez créer et exporter une solution gérée avec des noms et des descriptions dans cette langue.

Composant distinct pour chaque langue

Les composants de solution suivants peuvent contenir chacun une quantité considérable de texte à localiser :

  • Modèles d’article

  • Modèles de courr. électr.

  • Modèles de publipostage

  • Rapports

  • Boîtes de dialogue

    Pour ces types de composants de solution, la tactique recommandée consiste à créer des composants distincts pour chaque langue. Cela signifie que vous créez généralement une solution gérée de base qui contient vos composants de solution principales puis une solution gérée distincte qui contient ces composants de solution pour chaque langue. Une fois que les clients ont installé la solution de base, ils peuvent installer les solutions gérées pour les langues qu’ils ont mis en service pour l’organisation.

    Contrairement à Processus (workflows), vous pouvez créer des Boîtes de dialogue qui reflètent les paramètres existants de préférence de la langue de l’utilisateur et qui n’affichent les boîtes de dialogue qu’aux utilisateurs de cette langue.

Création d’une boîte de dialogue localisée

  1. Installez le module linguistique approprié et mettez la langue en service.

    Pour plus d’informations, voir Instructions d’installation du module linguistique.

  2. Modifiez vos options personnelles pour spécifier la Langue de l’interface utilisateur pour la langue souhaitée pour la boîte de dialogue.

  3. Accédez à Paramètres et, dans le groupe Centre de traitement, sélectionnez Processus.

  4. Cliquez sur Nouveau et créez la boîte de dialogue dans la langue que vous avez spécifiée.

  5. Après avoir créé la boîte de dialogue, modifiez vos options personnelles pour spécifier la langue de base de l’organisation.

  6. Lorsque vous utilisez la langue de base de l’organisation, vous pouvez accéder à la zone Solutions dans Paramètres et ajouter la boîte de dialogue localisée dans le cadre d’une solution.

    La boîte de dialogue créée dans l’autre langue ne sera affichée qu’aux utilisateurs qui affichent Dynamics 365 Customer Engagement (on-premises) avec cette langue.

Utiliser des ressources web XML comme ressources linguistiques

Les composants de solution d’assembly de plug-in peuvent envoyer des messages à un utilisateur final en levant une exception InvalidPluginExecutionException ainsi qu’en créant et en mettant à jour des enregistrements. Contrairement aux ressources web Silverlight, les plug-ins ne peuvent pas utiliser de fichiers de ressources.

Lorsqu’un plug-in nécessite du texte localisé, vous pouvez utiliser une ressource web XML pour stocker les chaînes localisées pour permettre au plug-in d’y accéder si nécessaire. La structure du fichier XML est votre option, mais vous pouvez suivre la structure utilisée par les fichiers de ressource ASP.NET (.resx) pour créer des ressources web XML distinctes pour chaque langue. Par exemple, la ressource suivante est une ressource web XML nommée localizedString.en_US qui suit le modèle utilisé par les fichiers . 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>  

Le code suivant montre comment un message localisé peut être retransmis dans un plug-in pour afficher un message à un utilisateur. Il concerne la phase de prévalidation d’un événement Delete pour l’entité 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));  
   }  
  }  

Voir aussi

Empaqueter et distribuer les extensions à l’aide de la solution Dynamics 365 Customer Engagement (on-premises)
Présentation des solutions
Plan de développement de solutions
Suivi de dépendance pour les composants de solution
Créer, exporter ou importer une solution non gérée
Créer, installer et mettre à jour une solution gérée
Désinstaller ou supprimer une solution
Entités de solution
Recherchez les valeurs de propriété de produit