Volto: Return additional fields for listing views

I'm now working on a custom listing view. I'm trying to figure out the pattern for providing additional fields to listing items.
Out of the box, Volto retrieves listings that return @id, @type, description, title and url
Like this:

{
 @id: "http://localhost:3000/myfolder",
@type: "folder",
description: "This is my folder",
review_state: "open",
title: "My folder",
url: "/myfolder",
}

I'd like to also return the tags associated with each listing item.
So something like this:

{
 @id: "http://localhost:3000/myfolder",
@type: "folder",
description: "This is my folder",
review_state: "open",
title: "My folder",
url: "/myfolder",
tags: ["interesting","stimulating","last one"]
}

I don't know if this is the best approach, but I know it can work.
This example: 26. Volto View Components: A Listing View for Talks – Mastering Plone 6 Development — Plone Training 2021 documentation ... showcases the use of Volto's searchContent helper.

I feel there's a nicer way* to do this but this way is documented and I know it will work.
The searchContent helper provides a way to send a custom query to the api. More important is the ability to request the fullobjects when doing the query, so I'll get my tags.

*I could be wrong about the nicer way.

React.useEffect(() => {
    dispatch(
      searchContent(
        '/',
        {
          portal_type: ['talk'],
          fullobjects: true,
        },
        'conferencetalks',
      ),
    );
  }, [dispatch]);

There's a nice new utlity that @ericof introduced in plone.volto, you need to register a utility and it can provide a list of portal catalog column names, see how the image_field is handled here: plone.volto/configure.zcml at main · plone/plone.volto · GitHub and plone.volto/summary.py at main · plone/plone.volto · GitHub

1 Like

Thanks @tiberiuichim so either (1) use the searchContent helper or (2) solve it on the backend with the 'JSONSummarySerializerMetadata'. If we're playing to the skills of a frontend developer then (1) is the better option.

Avoiding full_objects is better, though. Reducing the problem, we're basically talking about "waking zodb objects for listing vs just reading their metadata from the catalog", but it goes even further: content serialization can get quite large (it includes the blocks, information about children, etc) and that type of info gets repeated across all the items in the listing.

Agreed, but may be out of the reach of a frontend dev (at least with the available patterns).

Yes, indeed, it's not in the reach of frontend developers (although I have a colleague who started as a frontend dev exclusively with React and now he's all over, poking through the backend stack).

On the other hand, outside Volto, we didn't really have a "frontend stack only" developer role with Plone.

"frontend only" solution would require this: Listing variation templates should be able to control retrieved fields · Issue #2714 · plone/volto · GitHub and the plone.restapi counterpart. But we need a champion for this.

1 Like

@tiberiuichim Is it possible to simply overwrite the summary.py and thus expand the list of fields in JSONSummarySerializerMetadata? I found a dark hint that you should create an overrides folder in your addon and save a summary.py with changed content there, but unfortunately this has no effect

OK, I have already found the solution.
I just have to register the utility in the context of my addon then it also works with the changed summary.py

Hmm, I have now activated a RichText field as a behavior in the content-type News Item. This field is simply called "text" . If I try to enter this field in default_metadata_fields of the JSONSummarySerializerMetadata class in order to be able to see the field in the listing (summary), the following error occurs

 test-backend-1  |   Module plone.restapi.serializer.converters, line 80, in default_converter 
 test-backend-1  | TypeError: No converter for making RichTextValue object. (Did you mean <attribute>.raw or <attribute>.output?) (<class 'plone.app.textfield.value.RichTextValue'>) JSON compatible.

If I now set a field_accessors for text based on the example from summary.py, the error in the listing is gone.

def field_accessors(self):
        return {
            ...
            "text": "Text",
        }

I then also see the "text" field in the listing in the React Developer Tools... but it is zero instead of the entered test string.

How can I correctly call the converter for rich text in the serializer?

Your code probably goes through this line:

It means there's no default simple adaptor for RichTextValue. The existing one is a multi-adaptor:

You need to register a simple adaptor for RichTextValue, similar to: