Extension | .xcstrings |
Smartling Identifier | xcstrings |
Resources | Localizing and varying text with a string catalog | Apple Developer Documentation |
String Catalog files can be used to translate text, manage plurals, and adapt the text displayed in your app for specific devices.
These files are multilingual, whereby all target languages are included in the same file along with the source. The format is JSON-based, with string records that can be generated automatically or added manually using an editor.
Each string in this format is represented by a unique key, with a structure that includes translations for one or more locales.
Example File
Here is an example of a String Catalog file that contains strings and their translations.
{
"sourceLanguage" : "en",
"strings" : {
"Hello world" : {
"localizations" : {
"uk-UA" : {
"stringUnit" : {
"state" : "translated",
"value" : "Привіт світ"
}
},
"fr-FR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bonjour le monde"
}
}
} }, "How are you doing?" : {
"localizations" : {
"uk-UA" : {
"stringUnit" : {
"state" : "translated",
"value" : "Як справи?"
}
},
"fr-FR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Comment allez-vous?"
}
}
}
}
}
}
Each record has a localizations
section that contains the record for each locale. Each locale record has a stringUnit
node with a value
field that is the actual translation and a state
field.
The state
field can have the following values: new
, needs_review
, translated
.
In this example, the text "Hello world" and "How are you doing?" would be ingested as source strings for translation in Smartling.
If a translation exists for a string, the state
field will automatically be set to translated
when the translated file is downloaded from Smartling.
Below is another example of how a String Catalog file can be structured. In this scenario, the strings include translations for the source language. These translations will be ingested as source strings instead of keys. For instance, the text “Hi there!” will be ingested for translation instead of “Hello world!”.
{
"sourceLanguage" : "en",
"strings" : {
"Hello world!" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hi there!"
}
}
}
}
}, "version" : "1.0"
}
String Instructions
If a string record contains a comment attribute, Smartling will capture the comment value as a string instruction for translators. In the example below, the string "Item list" will have the instruction "Visible items".
Example:
{
"sourceLanguage" : "en",
"strings" : {
"Item list" : {
"comment" : "Visible items" } }, "version" : "1.0"
}
Plurals and String Catalog Variations
Smartling complies strictly with CLDR, which defines English as having two forms; “one” (singular) and “other” (plural). If you upload a source file with Zero form strings, the zero-plural form will not be shown in the Smartling dashboard.
There are two types of string variations in String Catalog files: variations by plurals and variations by device. They can also be combined to have variations by device and plurals.
Variations by plurals
In the example below, there is a plural structure for the English source text. The following pluralized string will be ingested in Smartling.
ONE FORM: one item in the list
OTHER FORM: {0} items in the list
{ "sourceLanguage" : "en", "strings" : { "%lld items in the list" : { "localizations" : { "en" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : { "state" : "translated",
"value" : "one item in the list"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld items in the list"
}
}
}
}
}
}
}
}, "version" : "1.0" }
Variations by device
In the example below, the source string has three variations based on the device: for iPhone, for Mac, and for other devices. When the content is ingested into Smartling, the strings are assigned variants for each device, allowing each string to be translated separately.
The following strings will be ingested for translation.
String 1 - Source text: "Hello world!" Variant: "Hello world - iphone"
String 2 - Source text: "Hello world!" Variant: "Hello world - mac"
String 3 - Source text: "Hello world!" Variant: "Hello world - other"
{ "sourceLanguage" : "en", "strings" : { "Hello world" : { "localizations" : { "en" : { "variations" : { "device" : { "iphone" : { "stringUnit" : { "state" : "translated", "value" : "Hello world!" } }, "mac" : { "stringUnit" : { "state" : "translated", "value" : "Hello world!" } }, "other" : { "stringUnit" : { "state" : "new", "value" : "Hello world!" } } } } } } } }, "version" : "1.0" }
Variations by device and plurals
Each variation by device can also have variation by plurals. For the example below, the following strings will be ingested for translation.
String 1
variant: %lld items in the list - iphone
ONE FORM: {0} item in the list (iPhone)
OTHER FORM: {0} items in the list (iPhone)
String 2
variant:%lld items in the list - mac
ONE FORM: one item in the list (Mac)
OTHER FORM: {0} items in the list (Mac)
String 3
(non-plural string)
{0} items in the list
{
"sourceLanguage" : "en",
"strings" : {
"%lld items in the list" : {
"localizations" : {
"en" : {
"variations" : {
"device" : {
"iphone" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld item in the list (iPhone)"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld items in the list (iPhone)"
}
}
}
}
},
"mac" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "one items in the list (Mac)"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld items in the list (Mac)"
}
}
}
}
},
"other" : {
"stringUnit" : {
"state" : "new",
"value" : "%lld items in the list"
}
}
}
}
}
}
}
},
"version" : "1.0"
}
Translated Files
If the original file uploaded to Smartling for translation already contains translations for some locales, those translations will remain in the translated file when you download translations for additional locales.
For instance if the original file has translations for de-DE
.
{
"sourceLanguage" : "en",
"strings" : {
"Hello world" : {
"localizations" : {
"de-DE" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hallo Welt"
}
}
}
}
}
}
And you download translations for fr-FR
and uk-UA
, the downloaded file will look like this:
{
"sourceLanguage" : "en",
"strings" : {
"Hello world" : {
"localizations" : {
"uk-UA" : {
"stringUnit" : {
"state" : "translated",
"value" : "Привіт світ"
}
},
"fr-FR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Bonjour le monde"
}
},
"de-DE" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hallo Welt"
}
}
}
}
}
}
The de-DE
translations will be preserved in the translated file downloaded from Smartling.
However, if you upload this same file for translation into de-DE
, the de-DE
translations completed in Smartling will overwrite the existing translations in the source file. For example, if the de-DE
translation in Smartling is "Moin, Welt!", the translated file downloaded from Smartling for de-DE
will appear as follows:
{ "sourceLanguage" : "en", "strings" : { "Hello world" : { "localizations" : { "de-DE" : { "stringUnit" : { "state" : "translated", "value" : "Moin, Welt!" } } } } }
}
Standard Placeholder Format
By default, Smartling recognizes iOS-style placeholders in String Catalog files.
For more information, please see Placeholders in Resource Files.
Directives
File directives are supported via our API (inline is not supported). Directives are specified in the following format:
API Parameter
smartling.[directive_name] = [value]
Here are examples of supported directives for iOS String Catalog files:
Escape Characters the Same as Source
Directive | entity_escaping_strategy |
Values | propagate | none (default) |
Description |
Used to retain entity escaping for all non-base entities. For example, normally we turn © into © but if we use this new directive the translation will automatically update to use escaping from the source. For each entity character, we'll check to see if it was escaped in the source and try to match (propagate) it in the target. The default is none which is the current behavior, which recognizes HTML4 entities only - if HTML5 entities are required as well, you must use the entity_escaping_type=propagate directive. propagate will only affect non-base entities - all named entities except & , ", <, > . Base entities continue to be controlled by HTML detection and the entity_escaping directive. If the same character is both escaped and unescaped in the same string, propagate will return the characters in the translation escaped in the same order as they were in the source. However, if there are a different number of characters in the translation where the translation process removed or added some and the escaping is inconsistent among them, propagate will escape all entities for that character. This does not affect source content at all - so using it will not result in new strings. Numerical entities are not considered at all with this directive, and are treated normally. |
Example |
smartling.entity_escaping_strategy=propagate |
Standard Placeholder Format
By default, smartling.placeholder_format = IOS
.
Directive |
placeholder_format |
Values | NONE; C; IOS; PYTHON; JAVA; YAML; QT, RESX |
Description | Used to specify a standard placeholder format. |
Example |
smartling.placeholder_format = IOS
Specifies iOS-style placeholders for the file. |
Custom Placeholder Format
Directive | placeholder_format_custom |
Values | 1) Custom Java regular expression. 2) NONE - disables any current custom placeholders |
Description | Specifies a custom placeholder format. Any text in your file matching the regular expression you provide will be captured as a placeholder. |
Example |
smartling.placeholder_format_custom = REGEX smartling.placeholder_format_custom=\{([^}]+)\} Any characters surrounded by curly brackets, e.g., {first name}, will be treated as a placeholder. |
See Placeholders in Resource Files for more on placeholders.
Trim Whitespace
Directive |
whitespace_trim |
Values |
on|yes|true or off|no|false or leading|trailing The default value is on. |
Description |
A whitespace is any character or series of characters that represent horizontal or vertical space in typography. When rendered, a whitespace character is not a visible mark, but does occupy an area or space on a page. Although whitespaces are necessary within a string (typically to separate words), unnecessary whitespaces can be found at the start of a string (leading) and at the end of a string (trailing). With this directive, you can trim whitespaces, as it enables or disables whitespace trim management for the ingested strings. Whitespace is optionally trimmed from content then re-inserted on download for convenience so that translators do not have to manage the extra spaces. However, content owners may want to retain surrounding whitespace so that translators can By default, the leading and trailing whitespaces are trimmed. You can choose to disable trimming or specify trimming for leading or trailing whitespaces. The directive can only be used as the API request parameter. |
Example |
smartling.whitespace_trim=on Smartling will trim leading and trailing whitespaces (default) smartling.whitespace_trim=off Smartling will not trim leading or trailing whitespaces smartling.whitespace_trim=leading Smartling will trim only leading whitespaces smartling.whitespace_trim=trailing Smartling will trim only trailing whitespaces |
Translation Locale Identifier (map)
Directive | locales_map |
Values | Alternative labels for Smartling locales in JSON format. |
Description | Defines how languages are labeled in downloaded files. The default label is the Smartling locale code, such as “fr-FR”, but you may wish to choose a different label, such as “French” to make the file easier to read or to match the labels used in your application. |
Example |
smartling.locales_map={"es-ES":"Spanish","de-DE":"German"} Downloaded translations will be labeled as Spanish for es-ES and German for de-DE. |