-
-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add translation endpoint #345
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2d24746
Implementation and tests of the @translations endpoint to get the tra…
erral 80b0ff5
Documentation about @translations endpoint
erral 59d8c62
add changelog entry
erral 027049f
rework tests, remove ugly if-s and use unittest.skipUnless
erral 6b53e61
properly allign closing brackets
erral 6b377bd
note that this is an only-plone5 feature
erral 8ad85be
improve documentation explaining multilingual capabilities
erral File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
DELETE /plone/en/test-document/@translations HTTP/1.1 | ||
Accept: application/json | ||
Authorization: Basic YWRtaW46c2VjcmV0 | ||
Content-Type: application/json | ||
|
||
{"language": "es"} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
HTTP/1.1 204 No Content | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
GET /plone/en/test-document/@translations HTTP/1.1 | ||
Accept: application/json | ||
Authorization: Basic YWRtaW46c2VjcmV0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
HTTP/1.1 200 OK | ||
Content-Type: application/json | ||
|
||
{ | ||
"@id": "http://localhost:55001/plone/en/test-document", | ||
"language": "en", | ||
"translations": [ | ||
{ | ||
"@id": "http://localhost:55001/plone/es/test-document", | ||
"language": "es" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
POST /plone/en/test-document/@translations HTTP/1.1 | ||
Accept: application/json | ||
Authorization: Basic YWRtaW46c2VjcmV0 | ||
Content-Type: application/json | ||
|
||
{"id": "http://localhost:55001/plone/es/test-document"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
HTTP/1.1 201 Created | ||
Content-Type: application/json | ||
Location: http://localhost:55001/plone/en/test-document | ||
|
||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
Translations | ||
============ | ||
|
||
.. note:: | ||
This is only available on Plone 5. | ||
|
||
Since Plone 5 the product `plone.app.multilingual`_ is included in the base | ||
Plone installation although it is not enabled by default. | ||
|
||
Multilingualism in Plone not only allows the managers of the site to configure | ||
the site interface texts to be in one language or another (such as the | ||
configuration menus, error messages, information messages or other static | ||
text) but also to configure Plone to handle multilingual content. To achieve | ||
that it provides the user interface for managing content translations. | ||
|
||
You can get additional information about the multilingual capabilities of Plone | ||
in the `documentation`_. | ||
|
||
In connection with that capabilities, plone.restapi provides a `@translations` | ||
endpoint to handle the translation information of the content objects. | ||
|
||
Once we have installed `plone.app.multilingual`_ and 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 which should be linked to. The | ||
`id` of the content must be a full URL of the content object: | ||
|
||
|
||
.. http:example:: curl httpie python-requests | ||
:request: _json/translations_post.req | ||
|
||
|
||
.. note:: | ||
"id" is a required field and needs to point to an existing content on the site. | ||
|
||
The API will return a `201 Created` response if the linking was successful. | ||
|
||
|
||
.. literalinclude:: _json/translations_post.resp | ||
:language: http | ||
|
||
|
||
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.: | ||
|
||
.. http:example:: curl httpie python-requests | ||
:request: _json/translations_get.req | ||
|
||
.. literalinclude:: _json/translations_get.resp | ||
:language: http | ||
|
||
|
||
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.: | ||
|
||
|
||
.. http:example:: curl httpie python-requests | ||
:request: _json/translations_delete.req | ||
|
||
.. note:: | ||
"language" is a required field. | ||
|
||
.. literalinclude:: _json/translations_delete.resp | ||
:language: http | ||
|
||
|
||
.. _`plone.app.multilingual`: https://pypi.python.org/pypi/plone.app.multilingual | ||
.. _`Products.LinguaPlone`: https://pypi.python.org/pypi/Products.LinguaPlone. | ||
.. _`documentation`: https://docs.plone.org/develop/plone/i18n/translating_content.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<configure | ||
xmlns="http://namespaces.zope.org/zope" | ||
xmlns:plone="http://namespaces.plone.org/plone" | ||
xmlns:zcml="http://namespaces.zope.org/zcml"> | ||
|
||
<plone:service | ||
method="GET" | ||
name="@translations" | ||
for="Products.CMFCore.interfaces.IContentish" | ||
factory=".pam.TranslationInfo" | ||
permission="zope2.View" | ||
/> | ||
|
||
<plone:service | ||
method="POST" | ||
name="@translations" | ||
for="Products.CMFCore.interfaces.IContentish" | ||
factory=".pam.LinkTranslations" | ||
permission="plone.app.multilingual.ManageTranslations" | ||
/> | ||
|
||
<plone:service | ||
method="DELETE" | ||
name="@translations" | ||
for="Products.CMFCore.interfaces.IContentish" | ||
factory=".pam.UnlinkTranslations" | ||
permission="plone.app.multilingual.ManageTranslations" | ||
/> | ||
|
||
</configure> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# -*- coding: utf-8 -*- | ||
from zope.interface import alsoProvides | ||
from Products.CMFCore.utils import getToolByName | ||
from plone.app.multilingual.interfaces import ITranslationManager | ||
from plone.restapi.services import Service | ||
from plone.restapi.deserializer import json_body | ||
from Products.CMFPlone.interfaces import ILanguage | ||
|
||
import plone.protect.interfaces | ||
|
||
|
||
class TranslationInfo(Service): | ||
""" Get translation information | ||
""" | ||
|
||
def reply(self): | ||
manager = ITranslationManager(self.context) | ||
info = { | ||
'@id': self.context.absolute_url(), | ||
'language': ILanguage(self.context).get_language(), | ||
'translations': []} | ||
for language, translation in manager.get_translations().items(): | ||
if language != ILanguage(self.context).get_language(): | ||
info['translations'].append({ | ||
'@id': translation.absolute_url(), | ||
'language': language, | ||
}) | ||
|
||
return info | ||
|
||
|
||
class LinkTranslations(Service): | ||
""" Link two content objects as translations of each other | ||
""" | ||
|
||
def reply(self): | ||
# Disable CSRF protection | ||
if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): | ||
alsoProvides(self.request, | ||
plone.protect.interfaces.IDisableCSRFProtection) | ||
|
||
data = json_body(self.request) | ||
id_ = data.get('id', None) | ||
if id_ is None: | ||
self.request.response.setStatus(400) | ||
return dict(error=dict( | ||
type='BadRequest', | ||
message='Missing content id to link to')) | ||
|
||
target = self._traverse(id_) | ||
if target is None: | ||
self.request.response.setStatus(400) | ||
return dict(error=dict( | ||
type='BadRequest', | ||
message='Content does not exist')) | ||
|
||
target_language = ILanguage(target).get_language() | ||
manager = ITranslationManager(self.context) | ||
current_translation = manager.get_translation(target_language) | ||
if current_translation is not None: | ||
self.request.response.setStatus(400) | ||
return dict(error=dict( | ||
type='BadRequest', | ||
message='Already translated into language {}'.format( | ||
target_language))) | ||
|
||
manager.register_translation(target_language, target) | ||
self.request.response.setStatus(201) | ||
self.request.response.setHeader( | ||
'Location', self.context.absolute_url()) | ||
return {} | ||
|
||
def _traverse(self, url): | ||
purl = getToolByName(self.context, 'portal_url') | ||
portal = purl.getPortalObject() | ||
portal_url = portal.absolute_url() | ||
if url.startswith(portal_url): | ||
content_path = url[len(portal_url)+1:] | ||
content_path = content_path.split('/') | ||
content_item = portal.restrictedTraverse(content_path) | ||
return content_item | ||
|
||
return None | ||
|
||
|
||
class UnlinkTranslations(Service): | ||
""" Unlink the translations for a content object | ||
""" | ||
|
||
def reply(self): | ||
# Disable CSRF protection | ||
if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): | ||
alsoProvides(self.request, | ||
plone.protect.interfaces.IDisableCSRFProtection) | ||
|
||
data = json_body(self.request) | ||
manager = ITranslationManager(self.context) | ||
language = data.get('language', None) | ||
if language is None: | ||
self.request.response.setStatus(400) | ||
return dict(error=dict( | ||
type='BadRequest', | ||
message='You need to provide the language to unlink')) | ||
|
||
if language not in manager.get_translations().keys(): | ||
self.request.response.setStatus(400) | ||
return dict(error=dict( | ||
type='BadRequest', | ||
message='This objects is not translated into {}'.format( | ||
language))) | ||
|
||
manager.remove_translation(language) | ||
self.request.response.setStatus(204) | ||
return {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erral cmon, you could at least use Basque or Catalan. ;)