Expansion

Expansion is a mechanism in plone.restapi to embed additional “components”, such as navigation, breadcrumbs, schema, or workflow within the main content response. This helps the API consumers to avoid unneccesary request.

Say you want to show a document in Plone together with the breadcrumbs and a workflow switcher. Instead of doing three individual requests, you can just expand the breadcrumbs and the workflow “components” within the document GET request.

The list of expandable components is listed in the “@components” attribute in the reponse of any content GET request:

GET /plone/front-page HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

{
  "@id": "http://localhost:55001/plone/front-page",
  "@type": "Document",
  "@components": [
      {"@id": "http://localhost:55001/plone/front-page/@actions"},
      {"@id": "http://localhost:55001/plone/front-page/@breadcrumbs"},
      {"@id": "http://localhost:55001/plone/front-page/@navigation"},
      {"@id": "http://localhost:55001/plone/front-page/@schema"},
      {"@id": "http://localhost:55001/plone/front-page/@workflow"},
      ...
  },
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "title": "Welcome to Plone",
  ...
}

Request Unexpanded:

http

GET /plone/front-page HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i http://nohost/plone/front-page -H 'Accept: application/json' --user admin:secret

httpie

http http://nohost/plone/front-page Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/front-page', headers={
    'Accept': 'application/json',
}, auth=('admin', 'secret'))

Response Unexpanded:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "@components": {
    "actions": {
      "@id": "http://localhost:55001/plone/front-page/@actions"
    }, 
    "breadcrumbs": {
      "@id": "http://localhost:55001/plone/front-page/@breadcrumbs"
    }, 
    "navigation": {
      "@id": "http://localhost:55001/plone/front-page/@navigation"
    }, 
    "workflow": {
      "@id": "http://localhost:55001/plone/front-page/@workflow"
    }
  }, 
  "@id": "http://localhost:55001/plone/front-page", 
  "@type": "Document", 
  "UID": "SomeUUID000000000000000000000001", 
  "allow_discussion": false, 
  "changeNote": "", 
  "contributors": [], 
  "created": "2016-01-21T01:14:48+00:00", 
  "creators": [
    "test_user_1_"
  ], 
  "description": "Congratulations! You have successfully installed Plone.", 
  "effective": null, 
  "exclude_from_nav": false, 
  "expires": null, 
  "id": "front-page", 
  "is_folderish": false, 
  "language": "", 
  "layout": "document_view", 
  "modified": "2016-01-21T01:24:11+00:00", 
  "parent": {
    "@id": "http://localhost:55001/plone", 
    "@type": "Plone Site", 
    "description": "", 
    "title": "Plone site"
  }, 
  "relatedItems": [], 
  "review_state": "private", 
  "rights": "", 
  "subjects": [], 
  "table_of_contents": null, 
  "text": {
    "content-type": "text/plain", 
    "data": "<p>If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.</p>", 
    "encoding": "utf-8"
  }, 
  "title": "Welcome to Plone", 
  "version": "current", 
  "versioning_enabled": true
}

In order to expand and embed one or more components, use the “expand” GET parameter and provide either a single component or a comma-separated list of the components you want to embed. Say you want to expand the “breadcrumbs” component:

GET /plone/front-page?expand=breadcrumbs HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

{
  "@id": "http://localhost:55001/plone/front-page",
  "@type": "Document",
  "@components": {
    "actions": {
      "@id": "http://localhost:55001/plone/front-page/@actions"
    },
    "breadcrumbs": {
      "@id": "http://localhost:55001/plone/front-page/@components/breadcrumbs",
      "items": [
        {
          "title": "Welcome to Plone",
          "url": "http://localhost:55001/plone/front-page"
        }
      ]
    },
    "navigation": {
      "@id": "http://localhost:55001/plone/front-page/@navigation"
    },
    "schema": {
      "@id": "http://localhost:55001/plone/front-page/@schema"
    },
    "workflow": {
      "@id": http://localhost:55001/plone/front-page/@workflow"
    },
  },
  "UID": "1f699ffa110e45afb1ba502f75f7ec33",
  "title": "Welcome to Plone"
}

Request Expanded:

http

GET /plone/front-page?expand=breadcrumbs HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i 'http://nohost/plone/front-page?expand=breadcrumbs' -H 'Accept: application/json' --user admin:secret

httpie

http 'http://nohost/plone/front-page?expand=breadcrumbs' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/front-page?expand=breadcrumbs', headers={
    'Accept': 'application/json',
}, auth=('admin', 'secret'))

Response Expanded:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "@components": {
    "actions": {
      "@id": "http://localhost:55001/plone/front-page/@actions"
    }, 
    "breadcrumbs": {
      "@id": "http://localhost:55001/plone/front-page/@breadcrumbs", 
      "items": [
        {
          "@id": "http://localhost:55001/plone/front-page", 
          "title": "Welcome to Plone"
        }
      ]
    }, 
    "navigation": {
      "@id": "http://localhost:55001/plone/front-page/@navigation"
    }, 
    "workflow": {
      "@id": "http://localhost:55001/plone/front-page/@workflow"
    }
  }, 
  "@id": "http://localhost:55001/plone/front-page", 
  "@type": "Document", 
  "UID": "SomeUUID000000000000000000000001", 
  "allow_discussion": false, 
  "changeNote": "", 
  "contributors": [], 
  "created": "2016-01-21T01:14:48+00:00", 
  "creators": [
    "test_user_1_"
  ], 
  "description": "Congratulations! You have successfully installed Plone.", 
  "effective": null, 
  "exclude_from_nav": false, 
  "expires": null, 
  "id": "front-page", 
  "is_folderish": false, 
  "language": "", 
  "layout": "document_view", 
  "modified": "2016-01-21T01:24:11+00:00", 
  "parent": {
    "@id": "http://localhost:55001/plone", 
    "@type": "Plone Site", 
    "description": "", 
    "title": "Plone site"
  }, 
  "relatedItems": [], 
  "review_state": "private", 
  "rights": "", 
  "subjects": [], 
  "table_of_contents": null, 
  "text": {
    "content-type": "text/plain", 
    "data": "<p>If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.</p>", 
    "encoding": "utf-8"
  }, 
  "title": "Welcome to Plone", 
  "version": "current", 
  "versioning_enabled": true
}

Here is an exaxmple of a request that expands all possible expansions:

http

GET /plone/front-page?expand=actions,breadcrumbs,navigation,schema,workflow HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i 'http://nohost/plone/front-page?expand=actions,breadcrumbs,navigation,schema,workflow' -H 'Accept: application/json' --user admin:secret

httpie

http 'http://nohost/plone/front-page?expand=actions,breadcrumbs,navigation,schema,workflow' Accept:application/json -a admin:secret

python-requests

requests.get('http://nohost/plone/front-page?expand=actions,breadcrumbs,navigation,schema,workflow', headers={
    'Accept': 'application/json',
}, auth=('admin', 'secret'))

And the response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "@components": {
    "actions": {
      "document_actions": [], 
      "object": [
        {
          "icon": "", 
          "id": "view", 
          "title": "View"
        }, 
        {
          "icon": "", 
          "id": "edit", 
          "title": "Edit"
        }, 
        {
          "icon": "", 
          "id": "folderContents", 
          "title": "Contents"
        }, 
        {
          "icon": "", 
          "id": "history", 
          "title": "History"
        }, 
        {
          "icon": "", 
          "id": "local_roles", 
          "title": "Sharing"
        }
      ], 
      "object_buttons": [
        {
          "icon": "", 
          "id": "cut", 
          "title": "Cut"
        }, 
        {
          "icon": "", 
          "id": "copy", 
          "title": "Copy"
        }, 
        {
          "icon": "", 
          "id": "delete", 
          "title": "Delete"
        }, 
        {
          "icon": "", 
          "id": "rename", 
          "title": "Rename"
        }
      ], 
      "portal_tabs": [
        {
          "icon": "", 
          "id": "index_html", 
          "title": "Home"
        }
      ], 
      "site_actions": [
        {
          "icon": "", 
          "id": "sitemap", 
          "title": "Site Map"
        }, 
        {
          "icon": "", 
          "id": "accessibility", 
          "title": "Accessibility"
        }, 
        {
          "icon": "", 
          "id": "contact", 
          "title": "Contact"
        }
      ], 
      "user": [
        {
          "icon": "", 
          "id": "preferences", 
          "title": "Preferences"
        }, 
        {
          "icon": "", 
          "id": "dashboard", 
          "title": "Dashboard"
        }, 
        {
          "icon": "", 
          "id": "plone_setup", 
          "title": "Site Setup"
        }, 
        {
          "icon": "", 
          "id": "logout", 
          "title": "Log out"
        }
      ]
    }, 
    "breadcrumbs": {
      "@id": "http://localhost:55001/plone/front-page/@breadcrumbs", 
      "items": [
        {
          "@id": "http://localhost:55001/plone/front-page", 
          "title": "Welcome to Plone"
        }
      ]
    }, 
    "navigation": {
      "@id": "http://localhost:55001/plone/front-page/@navigation", 
      "items": [
        {
          "@id": "http://localhost:55001/plone", 
          "description": "", 
          "title": "Home"
        }, 
        {
          "@id": "http://localhost:55001/plone/front-page", 
          "description": "Congratulations! You have successfully installed Plone.", 
          "title": "Welcome to Plone"
        }
      ]
    }, 
    "workflow": {
      "@id": "http://localhost:55001/plone/front-page/@workflow", 
      "history": [
        {
          "action": null, 
          "actor": "test_user_1_", 
          "comments": "", 
          "review_state": "private", 
          "time": "2016-10-21T19:00:00+00:00", 
          "title": "Private"
        }
      ], 
      "transitions": [
        {
          "@id": "http://localhost:55001/plone/front-page/@workflow/publish", 
          "title": "Publish"
        }, 
        {
          "@id": "http://localhost:55001/plone/front-page/@workflow/submit", 
          "title": "Submit for publication"
        }
      ]
    }
  }, 
  "@id": "http://localhost:55001/plone/front-page", 
  "@type": "Document", 
  "UID": "SomeUUID000000000000000000000001", 
  "allow_discussion": false, 
  "changeNote": "", 
  "contributors": [], 
  "created": "2016-01-21T01:14:48+00:00", 
  "creators": [
    "test_user_1_"
  ], 
  "description": "Congratulations! You have successfully installed Plone.", 
  "effective": null, 
  "exclude_from_nav": false, 
  "expires": null, 
  "id": "front-page", 
  "is_folderish": false, 
  "language": "", 
  "layout": "document_view", 
  "modified": "2016-01-21T01:24:11+00:00", 
  "parent": {
    "@id": "http://localhost:55001/plone", 
    "@type": "Plone Site", 
    "description": "", 
    "title": "Plone site"
  }, 
  "relatedItems": [], 
  "review_state": "private", 
  "rights": "", 
  "subjects": [], 
  "table_of_contents": null, 
  "text": {
    "content-type": "text/plain", 
    "data": "<p>If you're seeing this instead of the web site you were expecting, the owner of this web site has just installed Plone. Do not contact the Plone Team or the Plone mailing lists about this.</p>", 
    "encoding": "utf-8"
  }, 
  "title": "Welcome to Plone", 
  "version": "current", 
  "versioning_enabled": true
}