Translations
Multilingual is included in Nick. It is not enabled by default.
You can enable the multilingual support by adding the multilingual
profile to your configuration file. You can also replace the default
profile with the multilingualcontent
profile if you want to your initial content to be multilingual.
Nick provides a @translations
endpoint to handle the translation information of the content objects.
Once we enabled more than one language, we can link two content items of different languages to be the translation of each other issuing a POST
query to the @translations
endpoint, including the id
of the content to which it should be linked. The id
of the content must be a full URL of the content object:
POST /en/events/@translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
Content-Type: application/json
{
"id": "http://localhost:8080/nl/evenementen"
}
The API will return a 201 Created response, if the linking was successful:
HTTP/1.1 204 No Content
We can also use the object’s path to link the translation instead of the full URL:
POST /en/events/@translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
Content-Type: application/json
{
"id": "/nl/evenementen"
}
HTTP/1.1 204 No Content
We can also use the object’s UID to link the translation:
POST /en/events/@translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
Content-Type: application/json
{
"id": "495efb73-cbdd-4bef-935a-a56f70a20854"
}
HTTP/1.1 204 No Content
After linking the contents, we can get the list of the translations of that content item by issuing a GET
request on the @translations
endpoint of that content item:
GET /en/events/@translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:8080/en/events/@translations",
"items": [
{
"@id": "http://localhost:8080/nl/evenementen",
"language": "nl"
}
],
"root": {
"en": "http://localhost:8080/en",
"nl": "http://localhost:8080/nl"
}
}
To unlink the content, issue a DELETE
request on the @translations
endpoint of the content item, and provide the language code you want to unlink:
DELETE /en/events/@translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
{
"language": "nl"
}
HTTP/1.1 204 No Content
Creating a translation from an existing content
The POST
content endpoint to a folder is also capable of linking this new content with an existing translation using two parameters: translationOf
and language
.
POST /nl HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
Content-Type: application/json
{
"@type": "Page",
"id": "evenementen",
"language": "nl",
"title": "Evenementen",
"translation_of": "495efb73-cbdd-4bef-935a-a56f70a20854"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"title": "Evenementen",
"@components": {
"actions": {
"@id": "http://localhost:8080/nl/evenementen/@actions"
},
"breadcrumbs": {
"@id": "http://localhost:8080/nl/evenementen/@breadcrumbs"
},
"catalog": {
"@id": "http://localhost:8080/nl/evenementen/@catalog"
},
"navigation": {
"@id": "http://localhost:8080/nl/evenementen/@navigation"
},
"navroot": {
"@id": "http://localhost:8080/nl/evenementen/@navroot"
},
"translations": {
"@id": "http://localhost:8080/nl/evenementen/@translations"
},
"types": {
"@id": "http://localhost:8080/nl/evenementen/@types"
},
"workflow": {
"@id": "http://localhost:8080/nl/evenementen/@workflow"
}
},
"@id": "http://localhost:8080/nl/evenementen/my-news-item",
"@type": "Page",
"id": "evenementen",
"created": "2022-04-08T16:00:00.000Z",
"modified": "2022-04-08T16:00:00.000Z",
"UID": "a95388f2-e4b3-4292-98aa-62656cbd5b9c",
"is_folderish": true,
"layout": "view",
"owner": "admin",
"review_state": "private",
"language": {
"title": "Nederlands",
"token": "nl"
},
"lock": {
"locked": false,
"stealable": true
}
}
Get location in the tree for new translations
When you create a translation in Plone, there are policies in place for finding a suitable placement for it. This endpoint returns the proper placement for the newly created translation:
GET /en/events/@translation-locator?target_language=nl HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:8080/nl"
}
Expansion
This service can be used with the Expansion mechanism which allows getting additional information about a content item in one query, avoiding additional requests.
Translation information can be provided by the API expansion for translatable content items.
If a simple GET
request is done on the content item, a new entry will be shown on the @components
entry, with the URL of the @translations
endpoint:
GET /en/events HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
HTTP/1.1 201 Created
Content-Type: application/json
{
"title": "Events",
"@components": {
"actions": {
"@id": "http://localhost:8080/en/events/@actions"
},
"breadcrumbs": {
"@id": "http://localhost:8080/en/events/@breadcrumbs"
},
"catalog": {
"@id": "http://localhost:8080/en/events/@catalog"
},
"navigation": {
"@id": "http://localhost:8080/en/events/@navigation"
},
"navroot": {
"@id": "http://localhost:8080/en/events/@navroot"
},
"translations": {
"@id": "http://localhost:8080/en/events/@translations"
},
"types": {
"@id": "http://localhost:8080/en/events/@types"
},
"workflow": {
"@id": "http://localhost:8080/en/events/@workflow"
}
},
"@id": "http://localhost:8080/en/events/my-news-item",
"@type": "Page",
"id": "events",
"created": "2022-04-08T16:00:00.000Z",
"modified": "2022-04-08T16:00:00.000Z",
"UID": "a95388f2-e4b3-4292-98aa-62656cbd5b9c",
"is_folderish": true,
"layout": "view",
"owner": "admin",
"review_state": "private",
"language": {
"title": "English",
"token": "en"
},
"lock": {
"locked": false,
"stealable": true
}
}
In order to expand and embed the translations component, use the GET parameter expand with the value translations.
GET /en/events/?expand=translations HTTP/1.1
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImZ1bGxuYW1lIjoiQWRtaW4iLCJpYXQiOjE2NDkzMTI0NDl9.RS1Ny_r0v7vIylFfK6q0JVJrkiDuTOh9iG9IL8xbzAk
HTTP/1.1 201 Created
Content-Type: application/json
{
"title": "Events",
"@components": {
"actions": {
"@id": "http://localhost:8080/en/events/@actions"
},
"breadcrumbs": {
"@id": "http://localhost:8080/en/events/@breadcrumbs"
},
"catalog": {
"@id": "http://localhost:8080/en/events/@catalog"
},
"navigation": {
"@id": "http://localhost:8080/en/events/@navigation"
},
"navroot": {
"@id": "http://localhost:8080/en/events/@navroot"
},
"translations": {
"@id": "http://localhost:8080/en/events/@translations",
"items": [
{
"@id": "http://localhost:8080/nl/evenementen",
"language": "nl"
}
],
"root": {
"en": "http://localhost:8080/en",
"nl": "http://localhost:8080/nl"
}
},
"types": {
"@id": "http://localhost:8080/en/events/@types"
},
"workflow": {
"@id": "http://localhost:8080/en/events/@workflow"
}
},
"@id": "http://localhost:8080/en/events/my-news-item",
"@type": "Page",
"id": "events",
"created": "2022-04-08T16:00:00.000Z",
"modified": "2022-04-08T16:00:00.000Z",
"UID": "a95388f2-e4b3-4292-98aa-62656cbd5b9c",
"is_folderish": true,
"layout": "view",
"owner": "admin",
"review_state": "private",
"language": {
"title": "English",
"token": "en"
},
"lock": {
"locked": false,
"stealable": true
}
}