- Release notes
- Getting started
- Installation
- Configuration
- Integrations
- Authentication
- Working with Apps and Discovery Accelerators
- AppOne menus and dashboards
- AppOne setup
- TemplateOne 1.0.0 menus and dashboards
- TemplateOne 1.0.0 setup
- TemplateOne menus and fashboards
- TemplateOne 2021.4.0 setup
- Purchase to Pay Discovery Accelerator menus and dashboards
- Purchase to Pay Discovery Accelerator Setup
- Order to Cash Discovery Accelerator menus and dashboards
- Order to Cash Discovery Accelerator Setup
- Basic Connector for AppOne
- SAP Connectors
- Introduction to SAP Connector
- SAP input
- Checking the data in the SAP Connector
- Adding process specific tags to the SAP Connector for AppOne
- Adding process specific Due dates to the SAP Connector for AppOne
- Adding automation estimates to the SAP Connector for AppOne
- Adding attributes to the SAP Connector for AppOne
- Adding activities to the SAP Connector for AppOne
- Adding entities to the SAP Connector for AppOne
- SAP Order to Cash Connector for AppOne
- SAP Purchase to Pay Connector for AppOne
- SAP Connector for Purchase to Pay Discovery Accelerator
- SAP Connector for Order-to-Cash Discovery Accelerator
- Superadmin
- Dashboards and charts
- Tables and table items
- Application integrity
- How to ....
- Rebrand and restyle Apps and Discovery Accelerators
- Updating the Application Settings
- Preparing your app for translation
- Generating Translation files
- Completing the translations
- Use sharding in your applications
- Create an anonymized dataset
- Set up automated data refreshes
- Use an access matrix to enable role-based access to data
- Working with SQL connectors
- Introduction to SQL connectors
- Setting up a SQL connector
- CData Sync extractions
- Running a SQL connector
- Editing transformations
- Releasing a SQL Connector
- Scheduling data extraction
- Structure of transformations
- Using SQL connectors for released apps
- Generating a cache with scripts
- Setting up a local test environment
- Separate development and production environments
- Useful resources
Preparing your app for translation
translate()
function for any text in expressions that end users will see such as labels, info texts, and dashboard-item display names,
as well as some expression functions.
translate()
function.
For expressions you need to add translate calls around strings that you want to be translatable. Using this on a string will cause it to be marked for translation. In order to have a maintainable translatable app, follow the guidelines described below.
To prevent errors that are locale dependent as well as to reduce performance impact of translations, translated strings should never be used for logic, only for displaying. For example:
- Put the
translate
call as close to ‘displaying’ as possible which is in the dashboard itself. -
Do not compare with a translated string inside of an if.
Note:Aside from the translate function, there also exist other functions returning translated strings:
applicationname
,dashboarditemname
,levelattributename
,dashboardpath
;displayname
,selectedlabels
(useselecteduids
for logic instead).Use these functions only for displaying translated text. Do not use them in application logic, as that could lead to unwanted side effects.
Theoverlayname
function does not return translated text, it only returns the internal name. Only use this function in the logic of your expression, do not present this to end-users.
Naming convention
const_tr_
as a prefix for translated constants, and const_internal_
for logic constants).
Guideline 2 Always translate entire sentences and use variables to add values
({{records}} of {{total}})
instead of small parts of a sentence will help translators in several ways:
- The names of the variables will give information about context;
-
Using variables in a string allows the translators to change the order, which is required for certain languages (e.g. in Japanese 2 out of 6 is translated into 6のうち2)
Example: Display a string containing metrics and constant text. Use:
<code>translate(
"({{records}} of {{total}})",
"records", displaytext(metric(Metric_case_count, filter(records, activeperiodfilter))),
"total", displaytext(any(records).Number_of_filtered_cases_current_period)
)</code>
<code>translate(
"({{records}} of {{total}})",
"records", displaytext(metric(Metric_case_count, filter(records, activeperiodfilter))),
"total", displaytext(any(records).Number_of_filtered_cases_current_period)
)</code>
Instead of:
<code>"(" +
displaytext(metric(Metric_case_count, filter(records, activeperiodfilter))) +
translate(" of ") +
displaytext(any(records).Number_of_filtered_cases_current_period) +
")"</code>
<code>"(" +
displaytext(metric(Metric_case_count, filter(records, activeperiodfilter))) +
translate(" of ") +
displaytext(any(records).Number_of_filtered_cases_current_period) +
")"</code>
sizemethod
andaggregatedsizemethod
: These functions always return English text, except for the attribute’s name, which is translated.-
data values are not translated.
- Strings like Open/Closed filter must be implemented comparing translated values, which is an exception to the general guideline, and will cause favorites to only work correctly when opened in the same language. If opened in a different language the message “filter value not found” will be presented to the user. This exception also applies to the Variant attribute, since it is derived from the data.
value
function;displaytext
function.
-
Values expression for filters.
- Use a selector instead of a values expression, possibly with artificial created (global) attributes for the selector options.
-
The
displayname
function only marks an attribute’s display name for translation when using the following construct (Hereattribute_name
must be a direct reference to an attribute.)displayname(uid(attribute_name))
It will also return the correctly translated string if the attribute is marked for translation in another way. (automatic or otherwise).