Translation
Standard UI5 apps handle translations with i18n files stored as frontend artifacts. Since abap2UI5 apps live entirely on the ABAP backend, use ABAP's built-in translation tools instead — text elements, message classes, or data element descriptions.
Which Language
Two locales are in play, and they are set in two places. The backend runs in the SAP logon language, sy-langu: every text element, message class and data element label on this page comes back in it, and the sap-language URL parameter overrides it per start. The UI5 frontend keeps a locale of its own for date and number formatting, the calendar and the built-in control texts (Search, Cancel, the month names), derived from the browser and pinned with sap-ui-language or the bootstrap attribute data-sap-ui-language. The two agree in practice; when they must not be left to the browser, Logon Language is where both are set.
Text Element
ABAP text elements translate messages, so they show up in different languages without code changes:
METHOD z2ui5_if_app~main.
DATA(lv_msg_translated) = 'this is a translatable message in english'(001).
client->message_box_display( lv_msg_translated ).
ENDMETHOD.Messages
Message classes translate messages and unify translation handling, making multi-language maintenance simpler:
METHOD z2ui5_if_app~main.
MESSAGE ID `NET` TYPE `I` NUMBER `001` INTO DATA(lv_msg_translated).
client->message_box_display( lv_msg_translated ).
ENDMETHOD.View Literals
A title, a label or a button text is a literal in the view, and the same sources translate it: a text element or a message is read in ABAP and written into the view with t, which escapes the value, so a translation that happens to carry a brace is shown rather than read as a binding:
)->ele( `Page`
)->a( n = `title` t = 'Invoices'(002)
)->tag( `Label`
)->a( n = `text` t = lcl_help=>get_data_element_text( `PRODUCT` )-short
)->tag( `Button`
)->a( n = `text` t = 'Read'(003)
)->a( n = `press` v = client->_event( `READ` ) ).The view is built per roundtrip, so a user who logs on in another language gets the view in that language without a second artifact anywhere. Z2UI5_CL_SMP_APP_519 is a whole page written this way.
Numbers and Dates
What a formatted amount or date looks like is the frontend locale's decision, not the backend's: a sap.ui.model.type.Currency or Date binding renders 1.234,56 or 1,234.56 and 15.01.2024 or 1/15/2024 according to sap-ui-language, from the same wire value. Bind the raw ABAP value and let the type format it — Formatter has the pattern per ABAP type — rather than formatting in ABAP with sy-langu, which would fix the notation to the backend's language and break the way back for an editable field.
Data Element
You can also read and show the short, medium, or long descriptions of data elements (DD04T). The helper class below reads them programmatically. It uses two approaches for backward compatibility: it first tries classic DDIC introspection via cl_abap_elemdescr and GET_DDIC_FIELD (available on all ABAP releases). If that fails (e.g., in ABAP Cloud, which restricts classic DDIC APIs), it falls back to the XCO library (XCO_CP_ABAP_DICTIONARY). Dynamic method calls (CALL METHOD ... =>( )) keep the code compiling even on systems without XCO installed:
METHOD z2ui5_if_app~main.
DATA(ls_product_label) = lcl_help=>get_data_element_text( `PRODUCT` ).
client->message_box_display( |{ ls_product_label-short }: 100 | ).
ENDMETHOD.CLASS lcl_help DEFINITION
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_s_data_element_text,
header TYPE string,
short TYPE string,
medium TYPE string,
long TYPE string,
END OF ty_s_data_element_text.
CLASS-METHODS get_data_element_text
IMPORTING
i_data_element_name TYPE string
RETURNING
VALUE(result) TYPE ty_s_data_element_text.
ENDCLASS.
CLASS lcl_help IMPLEMENTATION.
METHOD get_data_element_text.
DATA ddic_ref TYPE REF TO data.
DATA data_element TYPE REF TO object.
DATA content TYPE REF TO object.
DATA: BEGIN OF ddic,
reptext TYPE string,
scrtext_s TYPE string,
scrtext_m TYPE string,
scrtext_l TYPE string,
END OF ddic.
DATA exists TYPE abap_bool.
" the shape of if_xco_dtel_content=>ts_field_label - a label is a text
" and its length, not a string
DATA: BEGIN OF label,
text TYPE c LENGTH 60,
length TYPE n LENGTH 2,
END OF label.
" ...and a name is the CHAR30 sxco_ad_object_name, which a dynamic call
" does not convert a string into
DATA object_name TYPE c LENGTH 30.
DATA(data_element_name) = i_data_element_name.
TRY.
cl_abap_typedescr=>describe_by_name( `T100` ).
DATA(struct_descr) = CAST cl_abap_structdescr( cl_abap_structdescr=>describe_by_name( `DFIES` ) ).
CREATE DATA ddic_ref TYPE HANDLE struct_descr.
ASSIGN ddic_ref->* TO FIELD-SYMBOL(<ddic>).
ASSERT sy-subrc = 0.
cl_abap_elemdescr=>describe_by_name( EXPORTING p_name = data_element_name
RECEIVING p_descr_ref = DATA(lo_typedescr)
EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
RETURN.
ENDIF.
DATA(data_descr) = CAST cl_abap_datadescr( lo_typedescr ).
CALL METHOD data_descr->(`GET_DDIC_FIELD`)
RECEIVING
p_flddescr = <ddic>
EXCEPTIONS
not_found = 1
no_ddic_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
RETURN.
ENDIF.
ddic = CORRESPONDING #( <ddic> ).
result-header = ddic-reptext.
result-short = ddic-scrtext_s.
result-medium = ddic-scrtext_m.
result-long = ddic-scrtext_l.
CATCH cx_root.
TRY.
DATA(xco_cp_abap_dictionary) = `XCO_CP_ABAP_DICTIONARY`.
object_name = data_element_name.
CALL METHOD (xco_cp_abap_dictionary)=>(`DATA_ELEMENT`)
EXPORTING
iv_name = object_name
RECEIVING
ro_data_element = data_element.
CALL METHOD data_element->(`IF_XCO_AD_DATA_ELEMENT~EXISTS`)
RECEIVING
rv_exists = exists.
IF exists = abap_false.
RETURN.
ENDIF.
CALL METHOD data_element->(`IF_XCO_AD_DATA_ELEMENT~CONTENT`)
RECEIVING
ro_content = content.
CALL METHOD content->(`IF_XCO_DTEL_CONTENT~GET_HEADING_FIELD_LABEL`)
RECEIVING
rs_heading_field_label = label.
result-header = label-text.
CALL METHOD content->(`IF_XCO_DTEL_CONTENT~GET_SHORT_FIELD_LABEL`)
RECEIVING
rs_short_field_label = label.
result-short = label-text.
CALL METHOD content->(`IF_XCO_DTEL_CONTENT~GET_MEDIUM_FIELD_LABEL`)
RECEIVING
rs_medium_field_label = label.
result-medium = label-text.
CALL METHOD content->(`IF_XCO_DTEL_CONTENT~GET_LONG_FIELD_LABEL`)
RECEIVING
rs_long_field_label = label.
result-long = label-text.
CATCH cx_root.
ENDTRY.
ENDTRY.
ENDMETHOD.
ENDCLASS.Working Samples
Complete apps from the sample catalog that use what this page describes. Each is a single class in abap2UI5/samples unless its row names another of the three sample repositories — pull that repository with abapGit and start the class with ?app_start=<class>.
| Sample | Class |
|---|---|
| Basics VII — Translatable Texts (Text Elements) | Z2UI5_CL_SMP_APP_519 |
