Custom File Format Module
Ce contenu n’est pas encore disponible dans votre langue.
Translate in CrowdinUse this module to add support of new custom file formats. Crowdin delegates source file parsing to an app that has a custom file format module. When translations are completed, Crowdin passes a source file and a string array with translations to the Custom file format app for translation files generation.
You can grant access to this module to one of the following user categories:
For Crowdin:
- Only me (i.e., project owner)
- All project members
- Selected users
For Crowdin Enterprise:
- Only organization admins
- All users in the organization projects
- Selected users
{ "modules": { "custom-file-format": [ { "key": "your-module-key-type-xyz", "type": "type-xyz", "url": "/process", "multilingual": true, "customSrxSupported": true, "signaturePatterns": { "fileName": "^.+\\.xyz$", "fileContent": "<properties>\\s*<property\\s+name=.*value=.*/>" } } ] }}key | Type: Required: yes Description: Module identifier within the Crowdin app. |
type | Type: Required: yes Description: The custom file format identifier. Can be used in API to force the processing of the files by the Custom file format app. If the |
url | Type: Required: yes Description: The relative URL triggered on file import, update, translation upload, and export. |
multilingual | Type: Required: no Allowed values: Description: This parameter is used to combine the content of multiple languages into one request when uploading and downloading translations in your Crowdin project. |
customSrxSupported | Type: Required: no Allowed values: Description: Defines whether the app supports custom segmentation rules (SRX 2.0) for its file format. When enabled, segmentation rules can be defined for the files processed by this module, and Crowdin passes them to the app in the |
signaturePatterns | Type: Description: Contains |
Communication between Custom File Format App and Crowdin
Section titled “Communication between Custom File Format App and Crowdin”On the initial file import, Crowdin detects custom file format using the signaturePatterns or type parameters and makes an HTTP request to the app’s URL ($baseUrl . $url) for further processing. The app then processes the file and responds to Crowdin. The requests and responses to and from the custom file format apps have two-minute timeouts. The maximum request and response payload size is limited to 5 MB.
Request payload example:
// max request payload - 5 MB// wait timeout - 2 minutes{ "jobType": "parse-file | build-file", "organization": { "id": 1, "domain": "{domain}", "baseUrl": "https://{domain}.crowdin.com", "apiBaseUrl": "https://{domain}.api.crowdin.com" }, "project": { "id": 1, "identifier": "your-project-identifier", "name": "Your Project Name" }, "file": { "id": 1, "name": "file.xml", "content": "VGhpcyBpcyBmaWxlIGNvbnRlbnQ=", // base64 encoded source file content "contentUrl": "https://crowdin-tmp.downloads.crowdin.com/1/file.xml?aws-signature=..." // source file public URL }, "sourceLanguage": { "id": "es", "name": "Spanish", "editorCode": "es", "twoLettersCode": "es", "threeLettersCode": "spa", "locale": "es-ES", "androidCode": "es-rES", "osxCode": "es.lproj", "osxLocale": "es", "pluralCategoryNames": ["one"], "pluralRules": "(n != 1)" }, "targetLanguages": [ { // same structure as for sourceLanguage, empty when uploading a new source file, one element for import_translations & export, can be more for multilingual files } ], "strings": [...], // for the build-file jobs, array of segments "stringsUrl": "https://tmp.downloads.crowdin.com/strings.ndjson", // for the build-file jobs, file with segments, in new-line delimited json format "customSrxContents": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..." // segmentation rules defined for the file, null if there are none}Properties:
jobType | Type: Possible values: Description: Specifies the action that should be executed by the app. |
file.content, file.contentUrl | Type: Description: Parameters used to pass the base64 encoded source file content ( |
strings, stringsUrl | Type(strings): Type(stringsUrl): Description: Parameters used for translations download (for |
customSrxContents | Type: Description: Content of the SRX 2.0 segmentation rules file defined for the source file. Passed for both |
Expected Response from the App for the parse-file Job Type
Section titled “Expected Response from the App for the parse-file Job Type”Response payload example:
// max response payload - 5 MB// wait timeout - 2 minutes{ "data": { "strings": [...], // segments array "stringsUrl": "https://app.example.com/jKe8ujs7a-segments.ndjson", // new-line delimited json file with parsed strings "preview": "VGhpbmdzIGFyZSBvbmx5IGltcG9zc2libGUgdW50aWwgdGhleSdyZSBub3Qu", // optional, base64 encoded content of preview html file, not supported if there are plural strings "previewUrl": "https://app.example.com/LN3km2K6M-preview.html", // optional, URL of preview html file, not supported if there are plural strings }, "error": { "message": "Your error message" }}Properties:
data.strings, data.stringsUrl | Type(data.strings): Type(data.stringsUrl): Description: Parameters used to pass the parsed strings content. |
data.preview, data.previewUrl | Type(data.preview): Type(data.previewUrl): Description: Parameters used to pass the optional HTML preview of the parsed strings content, which can be generated by the app. The generated HTML preview will be displayed in the Editor. See the HTML Preview file example. |
error.message | Type: Description: An error message that can be passed from the app to Crowdin and will be visible to a user in the UI. |
Expected Response from the App for the build-file Job Type
Section titled “Expected Response from the App for the build-file Job Type”Response payload example:
// max response payload - 5 MB// wait timeout - 2 minutes{ "data": { "content": "TWF5IHRoZSBGb3JjZSBiZSB3aXRoIHlvdS4=", // base64 encoded translation file content "contentUrl": "https://app.example.com/p5uLEpq8p-result.xml", // translation file public URL }, "error": { "message": "Your error message" }}Properties:
data.content, data.contentUrl | Type(data.content): Type(data.contentUrl): Description: Parameters used to pass the base64 encoded translation file content ( |
error.message | Type: Description: An error message that can be passed from the app to Crowdin and will be visible to a user in the UI. |
Below you can see an example of the strings structure expected from the app for parse-file job type and passed to the app for build-file job type.
Payload example:
// strings should be in "new-line delimited json" format if they passed by URL[ { // non plural string "previewId": 1, // only for "parse-file" jobType, required when the HTML preview of the file is generated "id": 1, // only for "build-file" jobType "identifier": "string-key-1", // required "context": "Some context", // optional "customData": "max 4 KB of custom data", // optional "maxLength": 10, // optional, default null "isHidden": false, // optional, default null "hasPlurals": false, // optional, default false "labels": ["label-one", "label-two"], // optional, default [] "attributes": { // optional "crowdinType": "html" // the string content is re-parsed with the HTML parser }, "text": "String source text", // required "translations": { // optional "uk": { // targetLanguage.id "text": "Переклад стрічки", // required "status": "untranslated | translated | approved" // optional, default "translated" }, // can be other languages for multilingual, check "targetLanguages" in the request payload } }, { // plural string "previewId": 2, "id": 2, "identifier": "string-key-2", "context": "Some optional context", "customData": "max 4 KB of custom data", "maxLength": 15, "isHidden": false, "hasPlurals": true, "labels": [], "text": { // keys from sourceLanguage.pluralCategoryNames "one": "One file", "other": "%d files", }, "translations": { "uk": { "text": { // keys from targetLanguage.pluralCategoryNames "one": "One file", "few": "%d файла", "many": "%d файлів", }, "status": { "one": "untranslated", "few": "translated", "many": "approved", } } } }]Properties:
previewId | Type: Required: yes (only for the Description: Unique identifier that links the string to its element in the HTML Preview file. Its value must exactly match the |
id | Type: Description: Numeric identifier of the string in your Crowdin project. Used for |
identifier | Type: Description: Unique string key within the file. |
customData | Type: Description: Any custom data that needs to be linked to the string. Added custom data will be exported along the corresponding strings on translation export. |
attributes.crowdinType | Type: Allowed values: Mostly match the Description: Used to specify the file format type for a string when post-processing is needed. For example, if a string returned by the app contains embedded HTML, setting |
The content of a custom file format can be split into smaller segments in two ways: your app segments the content itself with the rules that Crowdin passes to it, or Crowdin segments the content with one of its own parsers. Segment it in the app when only your app can parse the content, and leave it to a Crowdin parser when a string contains content in a format that Crowdin already supports, such as HTML or Markdown.
Set the customSrxSupported property to true in the module configuration. Segmentation rules (SRX 2.0) can then be set for the files processed by this module, for example via the importOptions.srxStorageId parameter of the Add File and Update File API methods.
Crowdin passes the content of the rules defined for a file in the customSrxContents parameter of both parse-file and build-file requests. The app does the segmentation itself:
- For the
parse-filejob, the app splits the text by those rules and returns each segment as a separate string with its ownidentifier(and its ownpreviewIdif the app generates the HTML preview of the file). - For the
build-filejob, the app receives those segments with their translations and joins them back when generating the translation file.
If no rules are defined for a file, customSrxContents is null.
Translation upload uses the parse-file job as well, so return the same per-segment identifiers when parsing a translation file. Otherwise the uploaded translations won’t match the existing segments.
Set the attributes.crowdinType attribute of a string to the format of its content. Crowdin then parses such a string the same way as a file of that format, so the content is segmented by the project’s settings for that format, or by that format’s default segmentation.
Each segment becomes a separate string in the project. For the build-file job, Crowdin merges the translations back into the original string, so the app receives the same string it returned during file parsing.
Strings with plurals aren’t re-parsed, and in string-based projects the attribute has no effect.
The HTML preview renders a WYSIWYG view of the file in the Editor. Wrap each translatable string in an element that carries both of the following:
id="string_preview_id_{previewId}", where{previewId}matches thepreviewIdof the corresponding string from theparse-fileresponse. Use double quotes and make the value match exactly.class="crowdin_phrase", so the Editor can highlight the string in the preview and edit it inline. Without this class, the string is highlighted only when selected from the strings list, and inline editing in the preview doesn’t work.
If the app splits a string into several segments, give each segment its own previewId and element in the preview. If several segments share a previewId, only the last one is linked to the element.
The HTML preview is generated only during source file import. It’s not produced when uploading translations (including multilingual uploads), and it’s not displayed when the app passes strings with plurals.
HTML Preview of the file example:
<html lang="en"> <head> <title>Optional Title</title> <style> table, th, td { border: 1px solid #aaa; } </style> </head> <body> <h1 style="text-align: center">HTML preview of the file</h1> <table style="width: 100%"> <tr> <th>Key:</th> <th>Text:</th> </tr> <tr> <td>Key 1</td> <td><span id="string_preview_id_1" class="crowdin_phrase">Source Text 1</span></td> <!-- 1 is previewId in strings json --> </tr> <tr> <td>Key 2</td> <td><span id="string_preview_id_2" class="crowdin_phrase">Source Text 2</span></td> <!-- 2 is previewId in strings json --> </tr> </table> </body></html>