Repository: plone/plone.restapi (language: python)

Issue:
Missing code example on Translations - Expansion?
At https://6.docs.plone.org/plone.restapi/docs/source/endpoints/translations.html#expansion it implies that there should be a code example by virtue of a colon at the end of the final sentence, but there is none.

Should there be a code sample?


Discussion / hints:
https://6.docs.plone.org/plone.restapi/docs/source/translations.html#expansion page not found
@stevepiercy 
Is this issue still open?
Link updated. The page moved to https://6.docs.plone.org/plone.restapi/docs/source/endpoints/translations.html#expansion. This is still an open issue.
```
{
  "@id": "http://localhost:55001/plone/content-item",
  "@type": "Document",
  "@components": [
    {
      "@id": "http://localhost:55001/plone/content-item/@actions"
    },
    {
      "@id": "http://localhost:55001/plone/content-item/@breadcrumbs"
    },
    {
      "@id": "http://localhost:55001/plone/content-item/@translations"  <---- The @translations endpoint URL is added here.
    },
    {
      "@id": "http://localhost:55001/plone/content-item/@workflow"
    }
    ...
  ],
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "title": "Sample Content Item",
  ...
}
```
is this code okay to show the `@translations`?
@stevepiercy 

@Akshat2Jain the best way to find out is to write a test, as described in [Contributing to plone.restapi](https://6.docs.plone.org/plone.restapi/docs/source/contributing/index.html). This will give you immediate feedback. Then when you submit a pull request, the docs will be built and tests will run in the CI that maintainers can review.

Fix patch:
diff --git a/docs/source/endpoints/translations.md b/docs/source/endpoints/translations.md
index 767efe880d..da145a805a 100644
--- a/docs/source/endpoints/translations.md
+++ b/docs/source/endpoints/translations.md
@@ -96,7 +96,7 @@ To unlink the content, issue a `DELETE` request on the `@translations` endpoint
 ## Creating a translation from an existing content
 
 The `POST` content endpoint to a folder is also capable of linking this new content with an
-exising translation using two parameters: `translationOf` and `language`.
+existing translation using two parameters: `translationOf` and `language`.
 
 ```{eval-rst}
 ..  http:example:: curl httpie python-requests
@@ -125,6 +125,32 @@ This endpoint returns the proper placement for the newly created translation:
 
 ## Expansion
 
-This endpoint can be used with the {doc}`../usage/expansion` mechanism which allows getting additional information about a content item in one query, avoiding unnecessary requests.
+This service can be used with the {doc}`../usage/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.
+A content type is translatable if it has the `plone.translatable` behavior enabled. 
+`plone.app.multilingual` enables this behavior for all content types at the time that it is installed.
+For other content types added later, it would be necessary to enable the behavior for them also.
 
 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:
+
+```{eval-rst}
+..  http:example:: curl httpie python-requests
+    :request: ../../../src/plone/restapi/tests/http-examples/translations_unexpanded_get.req
+```
+
+```{literalinclude} ../../../src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp
+:language: http
+```
+
+In order to expand and embed the translations component, use the GET parameter `expand` with the value `translations`.
+
+```{eval-rst}
+..  http:example:: curl httpie python-requests
+    :request: ../../../src/plone/restapi/tests/http-examples/translations_expand_get.req
+```
+
+```{literalinclude} ../../../src/plone/restapi/tests/http-examples/translations_expand_get.resp
+:language: http
+```
+
diff --git a/news/1374.documentation b/news/1374.documentation
new file mode 100644
index 0000000000..2d4bcd0a05
--- /dev/null
+++ b/news/1374.documentation
@@ -0,0 +1,1 @@
+Added translation code through expansion. @Akshat2Jain
\ No newline at end of file


Test patch:
diff --git a/src/plone/restapi/tests/http-examples/translations_expand_get.req b/src/plone/restapi/tests/http-examples/translations_expand_get.req
new file mode 100644
index 0000000000..d92b4f23c6
--- /dev/null
+++ b/src/plone/restapi/tests/http-examples/translations_expand_get.req
@@ -0,0 +1,3 @@
+GET /plone/en/test-document?expand=translations HTTP/1.1
+Accept: application/json
+Authorization: Basic YWRtaW46c2VjcmV0
diff --git a/src/plone/restapi/tests/http-examples/translations_expand_get.resp b/src/plone/restapi/tests/http-examples/translations_expand_get.resp
new file mode 100644
index 0000000000..010dce733e
--- /dev/null
+++ b/src/plone/restapi/tests/http-examples/translations_expand_get.resp
@@ -0,0 +1,100 @@
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+    "@components": {
+        "actions": {
+            "@id": "http://localhost:55001/plone/en/test-document/@actions"
+        },
+        "aliases": {
+            "@id": "http://localhost:55001/plone/en/test-document/@aliases"
+        },
+        "breadcrumbs": {
+            "@id": "http://localhost:55001/plone/en/test-document/@breadcrumbs"
+        },
+        "contextnavigation": {
+            "@id": "http://localhost:55001/plone/en/test-document/@contextnavigation"
+        },
+        "navigation": {
+            "@id": "http://localhost:55001/plone/en/test-document/@navigation"
+        },
+        "navroot": {
+            "@id": "http://localhost:55001/plone/en/test-document/@navroot"
+        },
+        "translations": {
+            "@id": "http://localhost:55001/plone/en/test-document/@translations",
+            "items": [
+                {
+                    "@id": "http://localhost:55001/plone/es/test-document",
+                    "language": "es"
+                }
+            ],
+            "root": {
+                "de": "http://localhost:55001/plone/de",
+                "en": "http://localhost:55001/plone/en",
+                "es": "http://localhost:55001/plone/es",
+                "fr": "http://localhost:55001/plone/fr"
+            }
+        },
+        "types": {
+            "@id": "http://localhost:55001/plone/en/test-document/@types"
+        },
+        "workflow": {
+            "@id": "http://localhost:55001/plone/en/test-document/@workflow"
+        }
+    },
+    "@id": "http://localhost:55001/plone/en/test-document",
+    "@type": "Document",
+    "UID": "SomeUUID000000000000000000000001",
+    "allow_discussion": false,
+    "changeNote": "",
+    "contributors": [],
+    "created": "1995-07-31T13:45:00+00:00",
+    "creators": [
+        "test_user_1_"
+    ],
+    "description": "",
+    "effective": null,
+    "exclude_from_nav": false,
+    "expires": null,
+    "id": "test-document",
+    "is_folderish": false,
+    "language": {
+        "title": "English",
+        "token": "en"
+    },
+    "layout": "document_view",
+    "lock": {
+        "locked": false,
+        "stealable": true
+    },
+    "modified": "1995-07-31T17:30:00+00:00",
+    "next_item": {},
+    "parent": {
+        "@id": "http://localhost:55001/plone/en",
+        "@type": "LRF",
+        "description": "",
+        "review_state": "published",
+        "title": "English",
+        "type_title": "Language Root Folder"
+    },
+    "previous_item": {
+        "@id": "http://localhost:55001/plone/en/assets",
+        "@type": "LIF",
+        "description": "",
+        "title": "Assets",
+        "type_title": "Language Independent Folder"
+    },
+    "relatedItems": [],
+    "review_state": "private",
+    "rights": "",
+    "subjects": [],
+    "table_of_contents": null,
+    "text": null,
+    "title": "Test document",
+    "type_title": "Page",
+    "version": "current",
+    "versioning_enabled": true,
+    "working_copy": null,
+    "working_copy_of": null
+}
diff --git a/src/plone/restapi/tests/http-examples/translations_unexpanded_get.req b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.req
new file mode 100644
index 0000000000..fea765b3d3
--- /dev/null
+++ b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.req
@@ -0,0 +1,3 @@
+GET /plone/en/test-document HTTP/1.1
+Accept: application/json
+Authorization: Basic YWRtaW46c2VjcmV0
diff --git a/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp
new file mode 100644
index 0000000000..7b0e674242
--- /dev/null
+++ b/src/plone/restapi/tests/http-examples/translations_unexpanded_get.resp
@@ -0,0 +1,88 @@
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+    "@components": {
+        "actions": {
+            "@id": "http://localhost:55001/plone/en/test-document/@actions"
+        },
+        "aliases": {
+            "@id": "http://localhost:55001/plone/en/test-document/@aliases"
+        },
+        "breadcrumbs": {
+            "@id": "http://localhost:55001/plone/en/test-document/@breadcrumbs"
+        },
+        "contextnavigation": {
+            "@id": "http://localhost:55001/plone/en/test-document/@contextnavigation"
+        },
+        "navigation": {
+            "@id": "http://localhost:55001/plone/en/test-document/@navigation"
+        },
+        "navroot": {
+            "@id": "http://localhost:55001/plone/en/test-document/@navroot"
+        },
+        "translations": {
+            "@id": "http://localhost:55001/plone/en/test-document/@translations"
+        },
+        "types": {
+            "@id": "http://localhost:55001/plone/en/test-document/@types"
+        },
+        "workflow": {
+            "@id": "http://localhost:55001/plone/en/test-document/@workflow"
+        }
+    },
+    "@id": "http://localhost:55001/plone/en/test-document",
+    "@type": "Document",
+    "UID": "SomeUUID000000000000000000000001",
+    "allow_discussion": false,
+    "changeNote": "",
+    "contributors": [],
+    "created": "1995-07-31T13:45:00+00:00",
+    "creators": [
+        "test_user_1_"
+    ],
+    "description": "",
+    "effective": null,
+    "exclude_from_nav": false,
+    "expires": null,
+    "id": "test-document",
+    "is_folderish": false,
+    "language": {
+        "title": "English",
+        "token": "en"
+    },
+    "layout": "document_view",
+    "lock": {
+        "locked": false,
+        "stealable": true
+    },
+    "modified": "1995-07-31T17:30:00+00:00",
+    "next_item": {},
+    "parent": {
+        "@id": "http://localhost:55001/plone/en",
+        "@type": "LRF",
+        "description": "",
+        "review_state": "published",
+        "title": "English",
+        "type_title": "Language Root Folder"
+    },
+    "previous_item": {
+        "@id": "http://localhost:55001/plone/en/assets",
+        "@type": "LIF",
+        "description": "",
+        "title": "Assets",
+        "type_title": "Language Independent Folder"
+    },
+    "relatedItems": [],
+    "review_state": "private",
+    "rights": "",
+    "subjects": [],
+    "table_of_contents": null,
+    "text": null,
+    "title": "Test document",
+    "type_title": "Page",
+    "version": "current",
+    "versioning_enabled": true,
+    "working_copy": null,
+    "working_copy_of": null
+}
diff --git a/src/plone/restapi/tests/test_documentation.py b/src/plone/restapi/tests/test_documentation.py
index df5f8aef5b..6f4a62329d 100644
--- a/src/plone/restapi/tests/test_documentation.py
+++ b/src/plone/restapi/tests/test_documentation.py
@@ -2267,6 +2267,22 @@ def test_documentation_translation_locator(self):
         )
         save_request_and_response_for_docs("translation_locator", response)
 
+    def test_documentation_translations_unexpanded_get(self):
+        response = self.api_session.get(
+            f"{self.en_content.absolute_url()}",
+        )
+        save_request_and_response_for_docs("translations_unexpanded_get", response)
+
+    def test_documentation_translations_expand_get(self):
+        self.api_session.post(
+            f"{self.en_content.absolute_url()}/@translations",
+            json={"id": self.es_content.absolute_url()},
+        )
+        response = self.api_session.get(
+            f"{self.en_content.absolute_url()}?expand=translations",
+        )
+        save_request_and_response_for_docs("translations_expand_get", response)
+
     def test_site_navroot_get(self):
         response = self.api_session.get("/@navroot")
         save_request_and_response_for_docs("navroot_site_get", response)