Volto - Catalog search for idx_data

I use a function with a catalog search with 'getIndexDataForUID' to get idx_data for an object. I indexed e.g. the category/categories of a project in the portal_catalog.
My function to get this data from the catalog are like the the following example:

`` Python

def projectCategory(self):
    catalog = api.portal.get_tool(name='portal_catalog')
    path = '/'.join(self.context.getPhysicalPath())
    idx_data = catalog.getIndexDataForUID(path)
    category = idx_data.get('getCategories')
    return (r for r in category)

``

I added this function to the view of the content type and displayed it within the view_template of the type.

I'm looking for the way how to create a search for the idx_data in Volto, a replacement for 'getIndexDataForUID' and 'idx_data.get'.

Write a plone.restapi endpoint (or extend the default dexterity serializer and add the information directly in the returned json for an object).

I wrote plone.restapi endpoints to the add-on:

But I wasn't successful getting the data from the endpoint into the
Volto frontend. I tried to follow the documentation on
47. Volto Actions and Component State – Mastering Plone 6 Development — Plone Training 2021 documentation but that
didn't work yet.
I searched for more documentation / information on the net yet, but
without success yet. Thanks in advance for any pointer to an howto for
the way to go.

If you just need the indexed values: use the getVocabulary action of Volto:

const MyCustomComponent = ({ items, linkMore, isEditMode }) => {
  const dispatch = useDispatch();

  const vocabulary = 'plone.app.vocabularies.Keywords';
  const keywords = useSelector((state) => state.vocabularies[vocabulary]);

  React.useEffect(() => {
    dispatch(getVocabulary({ vocabNameOrURL: vocabulary }));
  }, [dispatch]);

  return (
    <>
      <div>keywords: {JSON.stringify(keywords)}</div>

You need to create a Plone vocabulary.
But you can skip creating a plone.restapi endpoint and skip creating a Volto action for your endpoint (the action/reducer construction to fetch data from backend via rest api endpoint).

@kseuss this is good to know about:
In case someone else is wondering... you need to import getVocabulary from @plone/volto/actions
like this:

import { getVocabulary } from '@plone/volto/actions';

@ksuess I tried your hint but I get the error message:

TypeError: vocabNameOrURL.replace is not a function

It points to the line 'dispatch(getVocabulary({ vocabNameOrURL (...)

getVocabulary takes an Object as argument. 'vocabNameOrURL' is one of the keys.

Make sure to use the latest release Volto version, I think the API for getVocabulary was recently changed.

@ksuess with the Volto 14 the getVocabulary function works. But I didn't
get the data for an object, which I want to display yet.

I misunderstood your initial question, sorry. (You are not after the complete set of indexed values.)

Would you provide some more information.
Are you writing a view for a content type?
If yes:
With a KeywordIndex 'abc' in place, writing a content type view, you have the values for the instance of the content type under your fingertips. The argument 'content' of the content type view includes the indexed values of the object.

See browser developer tools for the whole bunch of data provided:


const MyContentTypeView = ({ content }) => (
  <div>
     I am the MyContentTypeView component.
     {console.debug("content", content}
  </div>
)

If no: @tiberiuichim led you to the pro way for complex requests.
The training chapters 46 and 47, explain how to write an endpoint, how to request the REST API endpoint and how to use the fetched data in Plone 6 front end.

1 Like

@ksuess I want to rewrite a replacement in Volto for the views (classic
UI) of three content types. They live in this folder:

I added the restapi part here:

I replaced with this endpoints the functions on the view class of the
Python module:

Will try to follow your hint in your comment.

I already looked into the training material, especially the chapters 46
and 47. I'll read and follow them again during my spare time next days.

Thanks for your hints!

Worked further on the Volto project and made a bit of progress. I created the action file, the component for categories and the reduzer for it. I uploaded the Volto project to my space on Github:

@ksuess with your hint about the console.debug listing in the categories component file I get a listing of the content object of the Dexterity template project instance. I tried the same with the const categories [const categories = useSelector((store) => store.categories);]. The result of this debugging was that only the const initialState seemed to work, but none of the switch cases.
The categories reduzer is here:

If I call the endpoint with Postman, e.g. at:
http://localhost:8080/Plone/templates/test-46/@projectcategories

I get the following get return:
[
"Business",
"Calculation"
]
for the categories of the template project.

In one of your view components you render the releasenumber.
<p>{content.releasenumber}</p>

You could do the same with your custom categories. Instead you write a reusable component for rendering the custom categories. This is a good way to achieve readable and reausable code. So now you have a subcomponent "SpecialCategories".

Subcomponents can be fed with props:
In your View component:
<SpecialCategories mycats={content.mycategories} />

Then you have the value mycats available in your subcomponent 'SpecialCategories' as

const SpecialCategories = ({mycats}) => {
  return (
    mycats.map((item, index) => (
      <div key={index}>{item.title}</div>
    ))
  )
}

@ksuess I could display the categories with your hint yet, but it works only from the field of the project content type directly. I didn't find a solution to connect to the restapi endpoint which I created in the Plone add-on yet.