Skip to content
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

It should be possible to list the content type of items in a container/collection #76

Closed
pigeonflight opened this issue Apr 17, 2016 · 4 comments · Fixed by #77
Closed
Assignees

Comments

@pigeonflight
Copy link
Member

pigeonflight commented Apr 17, 2016

Current behaviour

If I do an http get on a collection (which I have called "hey") with two items. It returns information about the two items in the "member" array. However for each member I only get somethign like this:

 "member": [
    {
      "@id": "https://mysite.example.com/hello",
      "description": "is it me you're looking for (upspeak)",
      "title": "hello"
    },
    {
      "@id": "https://mysite.example.com/front-page",
      "description": "Congratulations! You have successfully installed Plone.",
      "title": "Welcome to Plone"
    }
  ],

Suggested (Improved behaviour)

I would want the content type added as @type to the metadata.

  "member": [
    {
      "@id": "https://mysite.example.com/hello",
     "@type":"News Item",
      "description": "is it me you're looking for (upspeak)",
      "title": "hello"
    },
    {
      "@id": "https://mysite.example.com/front-page",
      "@type":"Document",
      "description": "Congratulations! You have successfully installed Plone.",
      "title": "Welcome to Plone"
    }
  ],

Full JSON output (for reference)

For completeness I've included the full JSON output below

{
  "@context": "http://www.w3.org/ns/hydra/context.jsonld",
  "@id": "https://mysite.example.com/hey",
  "@type": "Collection",
  "UID": "c650b8b9a05343abaa65cade44150c1f",
  "allow_discussion": null,
  "contributors": [],
  "created": "2016-04-17T14:23:01+00:00",
  "creators": [
    "manager"
  ],
  "customViewFields": [
    "Title",
    "Creator",
    "Type",
    "ModificationDate"
  ],
  "description": "",
  "effective": "2016-04-17T14:23:00",
  "exclude_from_nav": false,
  "expires": null,
  "id": "hey",
  "item_count": 30,
  "language": "en-gb",
  "limit": 1000,
  "member": [
    {
      "@id": "https://mysite.example.com/hello",
      "description": "is it me you're looking for (upspeak)",
      "title": "hello"
    },
    {
      "@id": "https://mysite.example.com/front-page",
      "description": "Congratulations! You have successfully installed Plone.",
      "title": "Welcome to Plone"
    }
  ],
  "modified": "2016-04-17T14:51:22+00:00",
  "parent": {
    "@id": "https://mysite.example.com",
    "description": "",
    "title": "Site"
  },
  "query": [
    {
      "i": "portal_type",
      "o": "plone.app.querystring.operation.selection.any",
      "v": [
        "Document"
      ]
    }
  ],
  "relatedItems": [],
  "rights": null,
  "sort_on": null,
  "sort_reversed": false,
  "subjects": [],
  "text": {
    "content-type": "text/html",
    "data": "<p>here<strong> is</strong> some <em>tect</em> for you</p>",
    "encoding": "utf-8"
  },
  "title": "hey"
}
@pigeonflight pigeonflight changed the title It should be possible to list the content type of members on a container/collection It should be possible to list the content type of items in a container/collection Apr 17, 2016
@lukasgraf
Copy link
Member

lukasgraf commented Apr 17, 2016

I recently did this in our own project integration of plone.restapi.

I would propose to include @type in the default summary (and maybe drop description while we're at it). @tisto any thoughts regarding this?


@pigeonflight for now, this can be done by registering your own ISerializeToJsonSummary adapter for your project's browser layer:

from my.project import IMyProjectLayer
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.serializer.summary import DefaultJSONSummarySerializer
from zope.component import adapter
from zope.interface import implementer
from zope.interface import Interface


@implementer(ISerializeToJsonSummary)
@adapter(Interface, IMyProjectLayer)
class MyJSONSummarySerializer(DefaultJSONSummarySerializer):
    """Customize summary representations to include the object's portal_type.
    """

    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self):
        # Get the default summary first, then modify it as needed
        summary = super(MyJSONSummarySerializer, self).__call__()

        # Include portal_type
        summary['@type'] = self.context.portal_type

        return summary
    <adapter factory=".summary.MyJSONSummarySerializer" />

Note that this will override the DefaultJSONSummarySerializer and therefore affect summary representations for items other than the site root in all places (not just collections, but also relation lists, folder contents, parent pointers (and eventually search results)).

Also note that plone.restapi is still in pre-alpha state: This behavior might still change in the future.

@pigeonflight
Copy link
Member Author

pigeonflight commented Apr 17, 2016

@lukasgraf thanks for the pointer, will look into that.

Definitely keep description. plone.restapi advertises itself as an "out of the box" restful api for Plone. In that context the description is important.

Having the type will allow me to filter the json results based on content type.

BTW.. I'm on a project now where we're using Plone as an API.

update:
@lukasgraf I just tested the workaround. Works very well. I needed to swap out the "IMyProjectLayer" of course for my own, apart from that, it works as advertised! Thanks again.

@tisto
Copy link
Sponsor Member

tisto commented Apr 18, 2016

@lukasgraf +1 for adding a type to listing (and keep the description). I wasn't 100% sure if we should use "@type" or just "type" since "@type" has a very specifig meaning in JSON-LD/Hydra. Though, I think "@type" is the correct key to use. See:

https://www.w3.org/TR/json-ld/#typed-values
https://www.hydra-cg.com/spec/latest/core/#collections
http://stackoverflow.com/a/25306010/644831 (first answer by the main author of hydra)

@lukasgraf
Copy link
Member

I also believe @type is correct - the way I understand it, it should be a term in one of the document's vocabularies. Eventually, that term should be derefenceable (be an URI that can actually be fetched), but it may very well be a relative URI, as described in the StackOverflow example above.

The way I understand it, we would eventually be building our own dynamic JSON-LD contexts, vocabularies and types, based on information from FTIs, (probably annotated) schema interfaces, and field types. Related: #11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants