Les applications SAP internationales doivent afficher des textes dans differentes langues. ABAP Cloud offre plusieurs mecanismes pour le multilinguisme : Message Classes pour les messages, Text Elements pour les textes UI et CDS Text Associations pour les textes de base de donnees. Cet article montre comment developper des applications multilingues dans ABAP Cloud.
Apercu des mecanismes de traduction
Dans ABAP Cloud, il existe differentes approches pour le multilinguisme :
| Mecanisme | Utilisation | Emplacement de stockage |
|---|---|---|
| Message Classes | Messages (erreurs, avertissements, succes) | Classe de messages |
| Text Elements | Textes UI dans le code ABAP | Elements de texte de la classe |
| CDS Text Associations | Textes de base de donnees (ex. descriptions d’articles) | Tables de texte |
| Data Elements | Labels de champs | DDIC Data Element |
| CDS Annotations | Textes de metadonnees pour Fiori | @EndUserText, @UI.* |
Message Classes - Traduire les messages
Les Message Classes sont le standard pour les messages d’erreur, avertissements et informations. Dans ABAP Cloud, vous les creez dans ADT sous Other ABAP Repository Objects > Message Class.
Creer une Message Class
" Definition d'une Message Class (dans ADT)" Message Class : ZTRAVEL_MSG" Messages :" 001 - Voyage & cree avec succes" 002 - Voyage & deja reserve" 003 - Dates de voyage invalides : & a &" 004 - Duree maximale de voyage de & jours depasseeLes placeholders & sont remplaces a l’execution par des parametres :
CLASS zcl_travel_validation DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. INTERFACES if_abap_behavior_handler.
ENDCLASS.
CLASS zcl_travel_validation IMPLEMENTATION.
METHOD if_abap_behavior_handler~validate. " Afficher un message avec parametres DATA(ls_travel) = <fs_travel>.
IF ls_travel-begin_date > ls_travel-end_date. " Message 003 : Dates de voyage invalides : & a & APPEND VALUE #( %tky = ls_travel-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Dates de voyage invalides : { ls_travel-begin_date } a { ls_travel-end_date }| ) ) TO reported-travel. ENDIF.
" Alternative : Utiliser Message Class APPEND VALUE #( %tky = ls_travel-%tky %msg = new_message( id = 'ZTRAVEL_MSG" number = '003" severity = if_abap_behv_message=>severity-error v1 = |{ ls_travel-begin_date }| v2 = |{ ls_travel-end_date }| ) ) TO reported-travel. ENDMETHOD.
ENDCLASS.Traduire les messages
Les traductions sont gerees dans ADT via Properties > Translations. La langue originale est typiquement l’anglais (EN), les traductions sont faites dans les langues cibles.
" ZTRAVEL_MSG - Message 003" EN : Invalid travel dates: & to &" DE : Ungueltige Reisedaten: & bis &" FR : Dates de voyage invalides : & a &" ES : Fechas de viaje no validas: & a &Text Elements - Textes de programme
Les Text Elements sont des textes utilises directement dans le code ABAP. Dans ABAP Cloud, ils sont definis comme partie de la classe ABAP.
Text Elements dans les classes
CLASS zcl_travel_report DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. " Les Text Symbols sont definis dans la classe " TEXT-001 : Apercu des voyages " TEXT-002 : Aucun voyage trouve " TEXT-003 : Voyage cree le
METHODS generate_report RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_travel_report IMPLEMENTATION.
METHOD generate_report. " Utiliser les Text Symbols DATA(lv_title) = TEXT-001. " Apercu des voyages
" Alternativement : Texte inline avec traduction DATA(lv_no_data) = 'No travels found'(002).
" Texte avec variables rv_html = |<h1>{ lv_title }</h1>|.
IF lt_travels IS INITIAL. rv_html = rv_html && |<p>{ lv_no_data }</p>|. ENDIF. ENDMETHOD.
ENDCLASS.Gerer le Text Pool
Dans ADT, ouvrez la classe et naviguez vers Text Elements dans la vue Outline. Les textes y sont geres :
| Symbol | Texte (EN) | Texte (FR) |
|---|---|---|
| 001 | Travel Overview | Apercu des voyages |
| 002 | No travels found | Aucun voyage trouve |
| 003 | Travel created on | Voyage cree le |
CDS Text Associations - Textes de base de donnees
Pour les donnees de base dependantes de la langue (ex. descriptions d’articles, noms de pays), ABAP Cloud utilise les CDS Text Associations. Celles-ci lient une table principale a une table de textes.
Creer une table de textes
D’abord, vous creez une table de textes avec cle de langue :
@EndUserText.label : 'Textes produits"@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE@AbapCatalog.tableCategory : #TRANSPARENT@AbapCatalog.deliveryClass : #Adefine table zproduct_text { key client : abap.clnt not null; key product_id: zproduct_id not null; key language : abap.lang not null; name : abap.char(60); description : abap.char(255);}CDS View avec Text Association
Le CDS View connecte les donnees de base avec les textes :
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produit avec textes"define view entity ZI_Product as select from zproduct as Product association [0..*] to zproduct_text as _Text on _Text.product_id = Product.product_id{ key Product.product_id as ProductId, Product.product_type as ProductType, Product.price as Price, Product.currency as Currency,
" Exposer la Text Association _Text}Text Association dans la Projection View
Dans la Projection View, vous utilisez @ObjectModel.text.association :
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produit (Projection)"@Metadata.allowExtensions: truedefine view entity ZC_Product as projection on ZI_Product{ key ProductId, ProductType, Price, Currency,
" Text Association avec filtrage automatique de la langue @ObjectModel.text.association: '_Text" _Text}Filtrage automatique de la langue
Avec @Semantics.language: true, vous marquez le champ de langue :
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Vue texte produit"define view entity ZI_ProductText as select from zproduct_text{ key product_id as ProductId, @Semantics.language: true key language as Language, name as Name, description as Description}Fiori Elements filtre automatiquement sur la langue de connexion de l’utilisateur.
Text Element pour champ d’affichage
Pour un seul champ d’affichage avec traduction automatique :
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Produit avec description"define view entity ZI_ProductWithText as select from zproduct as Product left outer join zproduct_text as Text on Text.product_id = Product.product_id and Text.language = $session.system_language{ key Product.product_id as ProductId, Product.price as Price,
" Texte dans la langue utilisateur Text.name as ProductName, Text.description as ProductDescription}La variable systeme $session.system_language fournit la langue de connexion.
Data Elements - Labels de champs
Les Data Elements definissent les labels de champs qui sont automatiquement affiches dans Fiori et ALV.
Data Element avec traductions
@EndUserText.label : 'ID Produit"@AbapCatalog.enhancement.category : #NOT_EXTENSIBLEdefine type zproduct_id : abap.char(10);Les labels sont geres dans ADT sous Properties > Translations :
| Langue | Texte court | Texte moyen | Texte long |
|---|---|---|---|
| EN | Product ID | Product Identifier | Product Identification Number |
| DE | Produkt-ID | Produktkennung | Produktidentifikationsnummer |
| FR | ID produit | Identifiant produit | Numero d’identification du produit |
Domain avec valeurs fixes
Pour les plages de valeurs fixes (ex. statut), les domains avec valeurs fixes traduites conviennent :
@EndUserText.label : 'Statut voyage"define domain ztravel_status : abap.char(1) { value 'N' : 'New'; " Nouveau value 'O' : 'Open'; " Ouvert value 'A' : 'Approved'; " Approuve value 'X' : 'Rejected'; " Rejete}CDS Annotations pour les textes UI
Fiori Elements utilise les CDS Annotations pour les textes UI. Celles-ci peuvent aussi etre traduites.
Annotation @EndUserText
@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Travel Management"@EndUserText.quickInfo: 'Manage business travels and expenses"define view entity ZI_Travel as select from ztravel{ @EndUserText.label: 'Travel ID" @EndUserText.quickInfo: 'Unique travel identifier" key travel_id as TravelId,
@EndUserText.label: 'Agency" agency_id as AgencyId,
@EndUserText.label: 'Customer" customer_id as CustomerId,
@EndUserText.label: 'Begin Date" begin_date as BeginDate,
@EndUserText.label: 'End Date" end_date as EndDate,
@EndUserText.label: 'Total Price" total_price as TotalPrice}Annotations @UI avec textes
@UI.headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { value: 'TravelId' }, description: { value: 'Description' }}define view entity ZC_Travel as projection on ZI_Travel{ @UI.facet: [ { id: 'GeneralInfo', label: 'General Information', type: #IDENTIFICATION_REFERENCE }, { id: 'Dates', label: 'Travel Dates', type: #FIELDGROUP_REFERENCE, targetQualifier: 'Dates" } ]
@UI.identification: [{ position: 10 }] @UI.lineItem: [{ position: 10, label: 'Travel' }] key TravelId,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 10, label: 'From' }] BeginDate,
@UI.fieldGroup: [{ qualifier: 'Dates', position: 20, label: 'To' }] EndDate}Workflow de traduction
Le processus de traduction dans ABAP Cloud differe de l’ABAP classique (Transaction SE63).
Exporter les objets traduisibles
Dans ADT, vous pouvez exporter les objets traduisibles :
- Selectionner Package > Export Translations
- Choisir les langues cibles
- Un fichier XLIFF est genere
<!-- Exemple export XLIFF --><xliff version="1.2"> <file source-language="en" target-language="fr"> <body> <trans-unit id="ZTRAVEL_MSG.001"> <source>Travel & successfully created</source> <target>Voyage & cree avec succes</target> </trans-unit> <trans-unit id="ZTRAVEL_MSG.002"> <source>Travel & already booked</source> <target>Voyage & deja reserve</target> </trans-unit> </body> </file></xliff>Importer les traductions
Apres la traduction (par des traducteurs ou un bureau de traduction) :
- Selectionner Package > Import Translations
- Choisir le fichier XLIFF traduit
- Les traductions sont importees dans le systeme
Fiori App : Maintain Translations
Pour les environnements BTP, l’application Fiori Maintain Translations est disponible :
- Demarrer l’app dans le Launchpad
- Choisir le Software Component et la langue
- Traduire les textes directement dans l’interface
- Sauvegarder et activer les modifications
Conventions de nommage pour les traductions
| Type d’objet | Convention de nommage | Exemple |
|---|---|---|
| Message Class | Z{PROJET}_MSG | ZTRAVEL_MSG |
| Data Element | z{domaine}_{champ} | ztravel_status |
| Domain | z{domaine}_{domain} | ztravel_status |
| Table de texte | z{master}_text | zproduct_text |
Bonnes pratiques
1. Definir la langue originale
Definissez une langue originale uniforme (typiquement EN) :
" Toujours utiliser des textes originaux en anglais" ZTRAVEL_MSG" 001 - EN: Travel & successfully created" 001 - FR: Voyage & cree avec succes2. Terminologie coherente
Utilisez un glossaire pour des traductions coherentes :
| Terme (EN) | Terme (FR) |
|---|---|
| Travel | Voyage |
| Booking | Reservation |
| Customer | Client |
| Agency | Agence |
| Status | Statut |
3. Utiliser les placeholders judicieusement
" Bien : Texte flexible avec placeholders" & records were processed successfully." & enregistrements traites avec succes.
" Mauvais : La grammaire ne fonctionne pas dans toutes les langues" & record(s) processed.4. Interroger les tables de textes efficacement
" Performant : Join avec fallbackdefine view entity ZI_ProductWithText as select from zproduct as Product left outer join zproduct_text as UserText on UserText.product_id = Product.product_id and UserText.language = $session.system_language left outer join zproduct_text as FallbackText on FallbackText.product_id = Product.product_id and FallbackText.language = 'E' " Anglais comme fallback{ key Product.product_id, " Preferer la langue utilisateur, sinon fallback coalesce( UserText.name, FallbackText.name ) as Name}5. Verifier le statut de traduction
Avant une release, tous les textes doivent etre traduits :
" CDS View pour les traductions manquantesdefine view entity ZI_MissingTranslations as select from zproduct as Product left outer join zproduct_text as Text on Text.product_id = Product.product_id and Text.language = 'F' " Traduction francaise{ key Product.product_id, case when Text.product_id is null then 'X' else '' end as MissingFR}where Text.product_id is nullProblemes frequents et solutions
Probleme : Les textes ne s’affichent pas
Cause : La table de textes n’a pas d’entree pour la langue utilisateur.
Solution : Implementer une logique de fallback :
coalesce( UserText.name, FallbackText.name, cast( Product.product_id as abap.char(60) )) as DisplayNameProbleme : Textes d’annotation non traduits
Cause : Les annotations @EndUserText ne sont pas automatiquement traduites.
Solution : Utiliser les textes des Data Elements ou gerer la traduction manuelle.
Probleme : Textes dynamiques
Cause : Les textes sont assembles a l’execution.
Solution : Utiliser Message Class avec placeholders :
" Message Class au lieu de concatenation de stringsMESSAGE e001(ztravel_msg) WITH lv_travel_id INTO DATA(lv_msg).Resume
Les applications ABAP Cloud multilingues necessitent la bonne combinaison des mecanismes disponibles :
- Message Classes pour tous les messages (erreurs, avertissements, informations)
- Text Elements pour les textes de programme statiques
- CDS Text Associations pour les donnees de base dependantes de la langue
- Data Elements pour les labels de champs
- CDS Annotations pour les metadonnees UI dans Fiori
Le workflow de traduction dans ABAP Cloud utilise l’export/import XLIFF ou l’application Fiori “Maintain Translations”. Une langue originale coherente et un glossaire facilitent considerablement la traduction.
Articles complementaires
- Message Handling dans ABAP Cloud - Messages et gestion des erreurs
- CDS Views - Modelisation de donnees avec Core Data Services
- RAP Basics - Introduction au RESTful ABAP Programming
- CDS Annotations - Annotations UI pour Fiori Elements