Translating Files

Placeholders in Resource Files

Strings in your Resource files often use placeholders that represent dynamic variables whose values are set at run time. These placeholder words shouldn't be translated, rather they should be included in the translation using the exact same syntax but in a position in the string as determined by the translator. Smartling's string placeholder feature allows translators to position them as needed in the translated string without having to manually enter the often complex syntax. This helps translators produce an accurate translation that will be linguistically correct at runtime and have no syntax errors when your application is being built or is executing. Placeholders are also known as “formatting strings”, “format specifiers” or just “specifiers”.

Here is  an example of a string with placeholders: Welcome %{username}, you have $%{balance} in your account

Formatting tags such as HTML and markdown are NOT considered placeholders. Smartling provides features to help translators work with formatting tags as well. Please review Standard behavior and customization for localization resource files for more information. Do not use placeholder directives to capture formatting tags.

Standard placeholders and customization

For most file formats Smartling will automatically capture standard placeholders. The standard named placeholder captured by default depends on the file format. In most cases you do not need to customize this behavior if you are using standard placeholders that correspond to the file format.

Smartling offers two directives to customize the placeholder behavior:

  • The placeholder_format directive lets you specify that your placeholders are in a common well known syntax. Options are C, IOS, PYTHON, JAVA, YAML, QT, or RESX.
  • The placeholder_format_custom directive lets you specify custom placeholders using a regular expression. Anything in a string matching the regular expression will be captured as a placeholder.

If your strings use the syntax that is standard for the file format then no customization with directives is needed.  If your strings use a different standard or you are using custom placeholder syntax then you can customize the behavior with these directives.

The standard placeholders will always apply to a given file format unless you explicitly turn it off. This means that in a single file strings can be processed with multiple placeholder formatting directives depending on the integration and the location of the string in the file. If needed you can usually turn off the standard behavior with a directive of placeholder_format = NONE.

Customers using the Strings API can also integrate their strings using placeholder directives. All the information here applies to Strings created via API.

Named placeholder_format directives are better and easier to use than custom placeholder_format_custom directives when they are applicable to your strings.  You won't have to write a regular expression and some of them will automatically apply positional location (see below) which can be critical for proper translation.

Positional Information

For some standard placeholder formats, Smartling automatically adds positional information.

A n example of a string with positional information in its placeholders: A room at %1$s is reserved for %2$s.

Positional information is important because in these formatting syntaxes if a string has multiple placeholders, the order of placeholders could be ambiguous. If a translator needs to switch the order of placeholders for proper translation, the positional information will make sure the right variable is used at run time. For example, if you upload the string: "A room at %s is reserved for %s." Smartling will capture "A room at %1$s is reserved for %2$s." Smartling will always add positional data to the placeholders for the formats that support it to ensure there is no ambiguity in the translation. Even if your original string didn't have positional data it will be added by Smartling if the string is being captured with one of those named placeholder directives. This positional information is always supported by the underling string formatting APIs for all programming languages. Positional data is not applied to custom placeholder formats, so if you have more than one custom placeholder in a string, make sure that a translator can tell them apart. For example: "A room at #[hotel] has been reserved for #[user]." is safer than "A room at #[var] has been reserved for #[var].".

Named placeholder formats

The following table gives examples of text that will be converted to a placeholder using the standard named placeholders.  The examples are not exhaustive; please refer to the corresponding linked documentation for complete description of the formatter.

Named Placeholder (placeholder_format) Example of text that will be
converted to a placeholder
File types using as default
C

Printf formatter

%s, %1$s, %2$s

%d, %1$d, %2$d

%0.1d 

Positional automatically applied

Gettext c-format

JAVA 

Java Util Formatter

%s, %1$s, %2$s

%d, %1$d, %2$d

%0.1d

Positional automatically applied

Android XML

Gettext java-format

Java Properties*

IOS

iOS strings formatter

%s, %1$s, %2$s

%@, %1$@, %2$@

%d, %1$d, %2$d

Positional automatically applied

iOS

iOS Stringsdict

Gettext ios-format

PYTHON Python "old" string formatting (< 2.7) 

%(firstName)s

%(count)d

Gettext python-format
QT

QT string arguments

%1

%2

QT Linguist
RESX

.Net string formatter

{0}

{1}

Resx/Resw

YAML

Ruby on Rails i18N

%{firstName}

%{count}

Yaml

Some files support a string_format directive. This directive can also cause placeholders to be captured. Only the files listed below can support string_format directives for placeholders.

The string_format directive can be used in other file formats for controlling HTML parsing behavior. Please check the documentation for the individual file for supported directives and uses cases.

Named string format (string_format) Example of text that will be
converted to a placeholder
Supported File Types
ICU See ICU MessageFormat article

 

JSON
MESSAGE_FORMAT

Java Text MessageFormat

{0}

{1}

Java Properties*

*Java properties use both the placeholder_format=JAVA and and the string_format=MESSAGE_FORMAT directives by default; both generate placeholders.  See the Java Properties documentation for more information on how these two formats interact and how to customize the behavior of string parsing in your file.

The default behavior for JSON files in Smartling is to use a default custom placeholder directive to captures multiple placeholder syntaxes that are common in various localization frameworks. You can customize your JSON file with a named or custom placeholder if the Smartling default custom placeholder doesn't capture your strings with placeholders. See the JSON file format article for more information and examples of the text patterns that are captured by the default behavior.

 

Specifying Standard and Custom Formats

These two directives work in tandem. For example if you were specifying placeholder behavior inside of a custom XML file you could specify both:

<!-- smartling.placeholder_format = PYTHON -->

and

<!-- smartling.placeholder_format_custom = \[\[.+?\]\] -->

Both the standard Python style placeholders, and a custom placeholder will be recognized when found in a string. In this example the custom placeholder is delineated by having two open and closed square bracket characters with text in between them: [[firstName]].

Here is a list of some of the example placeholders and a custom placeholder format directive to capture the text as a placeholder in the string.

Placeholder

Directive*

{{...}} # smartling.placeholder_format_custom=\{\{.+?\}\}
[[...]] # smartling.placeholder_format_custom=\[\[.+?\]\]
${...} # smartling.placeholder_format_custom=\$\{.+?\}
%{...}  # smartling.placeholder_format_custom=%\{.+?\}
#...#  # smartling.placeholder_format_custom=#.+?#

The syntax for declaring the a placeholder_format_custom directive and its regular expression value may differ for different file types or integrations methods such as the API.  See the documentation of the file format for details on how to format inline directives and the API documentation for API directives. The context (inside the file or via API integration) will determine the exact syntax of the directive and its value and wether or not you need have any special escaping in addition to the escaping that is required to generate a valid regular expression.

If you are using a custom file format, have custom placeholder syntax, or use non-standard placeholders you can integrate to get the behavior you want. Integration can be performed either in the file or via the API. So-called “file inline” integration gives you extra customization options - for example, you may be able to change placeholder behavior throughout the file - but requires you to customize the file for Smartling. API-based integration allows you to avoid adding Smartling specific code to your file but will affect all the strings in the file.

Escaping

When defining the regular expression for a custom placeholder you may need to escape characters that are part of the expression to account for the environment (file or shell). After escaping is accounted for the expression will be evaluated as a Perl compatible regular expression (PCRE).

So, in the above example, because brackets have special meaning for PCRE they must be escaped with a backslash for the regular expression engine. However, in another context the backslash itself may need to be escaped.

Verify Placeholders

To check that your placeholders are being captured as expected, check the string in the Strings View in the Smartling Dashboard. Placeholders will be highlighted. A common mistake is to create a custom placeholder that is too aggressive and captures the entire string or excessive parts of the string as the placeholder. Make sure only the placeholder is highlighted and the translatable text appears as normal.

A common example is seen in JSON where the backslash character in the value of name/value pair already has special meaning for JSON, and so must be escaped to be valid a character in JSON. Also note when defining a custom placeholder inline of a JSON file we require the expressions to be listed in an array. So the above directives modified to be inside of a JSON file would be:

JSON

"smartling": {
   
"placeholder_format" : "PYTHON",
   "placeholder_format_custom" : ["\\[\\[.*?\\]\\]"]
}

Not Specifying Placeholder Formats

If your file has non-standard placeholders and you do not integrate to define them Smartling will capture the string with the placeholder as ‘plain text’; they will typically be counted as “words” for translation, translators will have to manually enter the placeholder using the correct syntax, and the Smartling CAT tool will not be able to warn the translators about missing placeholders or incorrect syntax.

Was this article helpful?