Skip to content

Commit

Permalink
Merge 91c74ef into 4daffd2
Browse files Browse the repository at this point in the history
  • Loading branch information
avoinea committed Aug 21, 2020
2 parents 4daffd2 + 91c74ef commit c6ee760
Show file tree
Hide file tree
Showing 55 changed files with 2,372 additions and 52 deletions.
2 changes: 1 addition & 1 deletion docs/source/addons.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ An individual addon can be installed by issuing a ``POST`` to the given URL:


Uninstalling an addon
-------------------
---------------------

An individual addon can be uninstalled by issuing a ``POST`` to the given URL:

Expand Down
2 changes: 2 additions & 0 deletions docs/source/controlpanels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ Control Panels not based on plone.registry

Control panel which are not based on plone.registry have a custom ``@controlpanels/:panel`` endpoint implementation.

.. _dexterity-types:

Dexterity Types
^^^^^^^^^^^^^^^

Expand Down
165 changes: 164 additions & 1 deletion docs/source/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,72 @@ Available content types in a Plone site can be listed and queried by accessing t
:language: http


The API consumer can create, read, update, and delete a content-types schema.

======= =============================================== =====================================================================
Verb URL Action
======= =============================================== =====================================================================
POST ``/@types/{type}`` Add field/fieldset to content type schema
GET ``/@types/{type}`` Get the schema of a content type
PATCH ``/@types/{type}`` Update existing schema fields/fieldsets properties
PUT ``/@types/{type}`` Replace content-type schema
======= =============================================== =====================================================================

In addition to the above methods we can also do:

======= =============================================== =====================================================================
Verb URL Action
======= =============================================== =====================================================================
GET ``/@type/{type}/{field/fieldset}`` Get field/fieldset properties
PATCH ``/@type/{type}/{field/fieldset}`` Update field/fieldset properties
DELETE ``/@type/{type}/{field/fieldset}`` Remove field/fieldset from schema
======= =============================================== =====================================================================

To get the schema of a content type, access the ``/@types`` endpoint with the name of the content type, e.g. '/plone/@types/Document':
.. note::

Schema fields/fieldsets defined by `behaviors <https://docs.plone.org/external/plone.app.dexterity/docs/behaviors/index.html>`_
are immutable and can NOT be changed via this RestAPI endpoint. See :ref:`dexterity-types` controlpanel RestAPI endpoint
for enabling/disabling behaviors.


Add schema fieldset/field with POST
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To create a new **fieldset**, send a POST request to the ``/@types/Document`` endpoint.

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_post_fieldset.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_post_fieldset.resp
:language: http


To create a new **field**, send a POST request to the ``/@types/Document`` endpoint.

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_post_field.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_post_field.resp
:language: http

For a complete list of available field **@types** you can access **/@vocabularies/Fields** endpoint.

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/vocabularies_get_fields.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/vocabularies_get_fields.resp
:language: http

Get the schema with GET
~~~~~~~~~~~~~~~~~~~~~~~

To get the schema of a content type, access the ``/@types`` endpoint with the name of the content type, e.g. ``plone/@types/Document``:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document.req
Expand All @@ -39,3 +103,102 @@ For ``Choice`` fields, their vocabulary or source will be linked to in a ``vocab
See :ref:`vocabularies` for details on these endpoints.

See :ref:`types-schema` for a detailed documentation about the available field types.

To get one schema **fieldset** properties, access ``@types/Document/{fieldset}`` endpoint:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_get_fieldset.req

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_get_fieldset.resp
:language: http

To get one schema **field** properties, access ``@types/Document/{field}`` endpoint:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_get_field.req

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_get_field.resp
:language: http


Update schema with PATCH
~~~~~~~~~~~~~~~~~~~~~~~~

To update content type schema defaults we send a PATCH request to the server.
PATCH allows to provide just a subset of the resource (the values you actually want to change).

To update one or more schema **field** properties:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_patch_properites.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_patch_properites.resp
:language: http

To change one or more **fieldsets** properties:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_patch_fieldsets.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_patch_fieldsets.resp
:language: http


To update one **fieldset** settings, we can also send a PATCH request to ``@types/Document/{fieldset}`` endpoint:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_patch_fieldset.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_patch_fieldset.resp
:language: http

To update one **field** settings, we can also send a PATCH request to ``@types/Document/{field}`` endpoint:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_patch_field.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_patch_field.resp
:language: http

Update schema with PUT
~~~~~~~~~~~~~~~~~~~~~~

Use PUT when more changes are needed in one call, like create new fields/fieldsets, move fields to fieldset, remove multiple fields, etc.

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_put.req

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_put.resp
:language: http

Removing schema field/fieldset with DELETE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Delete an existing schema **field** by sending a DELETE request to the URL of an existing schema field:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_delete_field.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_delete_field.resp
:language: http


Delete an existing schema **fieldset** by sending a DELETE request to the URL of an existing schema fieldset:

.. http:example:: curl httpie python-requests
:request: ../../src/plone/restapi/tests/http-examples/types_document_delete_fieldset.req

Response:

.. literalinclude:: ../../src/plone/restapi/tests/http-examples/types_document_delete_fieldset.resp
:language: http
1 change: 1 addition & 0 deletions news/951.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Finish @types endpoint to be able to add/edit/delete CT schema [Petchesi-Iulian, avoinea]
1 change: 1 addition & 0 deletions plone-4.3.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ extends =

[versions]
plone.restapi =
plone.schema = 1.2.1
pytz = 2017.3
zope.interface = 4.1.0
# fixes zlib failure: https://stackoverflow.com/questions/34631806/fail-during-installation-of-pillow-python-module-in-linux
Expand Down
1 change: 1 addition & 0 deletions plone-5.0.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ extends =

[versions]
plone.restapi =
plone.schema = 1.2.1
pytz = 2017.3
zope.interface = 4.1.0
2 changes: 1 addition & 1 deletion plone-5.1.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plone.restapi =
zipp = 0.5.2

# plone.restapi specific
plone.schema = 1.2.0
plone.schema = 1.2.1

# zest.releaser
zest.releaser = 6.20.1
Expand Down
12 changes: 11 additions & 1 deletion plone-5.2.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ find-links += https://dist.plone.org/thirdparty/
versions=versions

[versions]
plone.restapi =
plone.restapi =
plone.namedfile = 5.3.1
astunparse = 1.6.2

# requirement for jsonfield
plone.schema = 1.2.1

# requirement for the @types endpoint enhancements
# https://github.com/plone/plone.restapi/pull/951
# https://github.com/plone/plone.schemaeditor/pull/77
plone.schemaeditor = 3.0.1
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def read(filename):
"python-dateutil",
"plone.behavior>=1.1", # adds name to behavior directive
"plone.rest >= 1.0a6", # json renderer moved to plone.restapi
"plone.schema >= 1.2.0", # new json field
"plone.schema >= 1.2.1", # new/fixed json field
"PyJWT",
"pytz",
],
Expand Down
60 changes: 60 additions & 0 deletions src/plone/restapi/services/types/add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
from plone.restapi.deserializer import json_body
from plone.restapi.interfaces import IPloneRestapiLayer
from plone.restapi.services import Service
from plone.restapi.types.utils import add_field
from plone.restapi.types.utils import add_fieldset
from zExceptions import BadRequest
from zope.component import queryMultiAdapter
from zope.interface import alsoProvides
from zope.interface import implementer
from zope.interface import noLongerProvides
from zope.publisher.interfaces import IPublishTraverse
import plone.protect.interfaces


@implementer(IPublishTraverse)
class TypesPost(Service):
""" Creates a new field/fieldset
"""

def __init__(self, context, request):
super(TypesPost, self).__init__(context, request)
self.params = []

def publishTraverse(self, request, name):
# Treat any path segments after /@types as parameters
self.params.append(name)
return self

def reply(self):
if not self.params:
raise BadRequest("Missing parameter typename")

data = json_body(self.request)

# Disable CSRF protection
if "IDisableCSRFProtection" in dir(plone.protect.interfaces):
alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection)

# Make sure we get the right dexterity-types adapter
if IPloneRestapiLayer.providedBy(self.request):
noLongerProvides(self.request, IPloneRestapiLayer)

name = self.params.pop()
context = queryMultiAdapter(
(self.context, self.request), name="dexterity-types"
)
context = context.publishTraverse(self.request, name)

factory = data.get("factory", None)
if not factory:
raise BadRequest("Missing parameter: 'factory'")

if factory == "fieldset":
res = add_fieldset(context, self.request, data)
else:
res = add_field(context, self.request, data)

self.request.response.setStatus(201)
return res
33 changes: 33 additions & 0 deletions src/plone/restapi/services/types/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,39 @@
permission="zope2.View"
/>

<plone:service
method="PATCH"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
factory=".update.TypesUpdate"
name="@types"
permission="plone.app.controlpanel.Overview"
/>

<plone:service
method="POST"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
factory=".add.TypesPost"
name="@types"
permission="plone.app.controlpanel.Overview"
/>

<plone:service
method="DELETE"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
factory=".delete.TypesDelete"
name="@types"
permission="plone.app.controlpanel.Overview"
/>

<plone:service
method="PUT"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
factory=".put.TypesPut"
name="@types"
permission="plone.app.controlpanel.Overview"
/>


<adapter factory=".get.TypesInfo" name="types"/>

</configure>
Loading

0 comments on commit c6ee760

Please sign in to comment.