contextual vocabularies
Fixes #3216
When there is a contextualized vocabulary url in the schema, Volto must call it with the full path and not return it to the site root.
There is a risk, however, that this change may bring out problems hidden by the anomaly it solves.
Deploy Preview for plone-components canceled.
| Name | Link |
|---|---|
| Latest commit | beaa89a7cb68c657101db4bb3463481475ab8547 |
| Latest deploy log | https://app.netlify.com/sites/plone-components/deploys/67ebcb77853ff80008fd791a |
I've run into this problem on one project, but I decided it was too risky to load all vocabularies with a context-sensitive path. For one thing, this means the results can't be HTTP-cached in cases when they are not context-dependent.
For that project, I customized this action to check a setting with a list of vocabularies that are context-dependent. That way it's possible to opt in where it's needed.
const vocabulary = getVocabName(vocabNameOrURL);
let vocabPath;
if (config.settings.contextualVocabularies.includes(vocabulary)) {
vocabPath = flattenToAppURL(vocabNameOrURL);
} else {
vocabPath = `/@vocabularies/${vocabulary}`;
}
let queryString = `b_start=${start}${size ? '&b_size=' + size : ''}`;
if (query) {
queryString = `${queryString}&title=${query}`;
}
return {
type: GET_VOCABULARY,
vocabulary: vocabNameOrURL,
start,
request: {
op: 'get',
path: `${vocabPath}?${queryString}`,
},
subrequest,
};
I've run into this problem on one project, but I decided it was too risky to load all vocabularies with a context-sensitive path. For one thing, this means the results can't be HTTP-cached in cases when they are not context-dependent.
@davisagli, Good point! Do you think your solution might be in Volto?
With config.settings.contextualVocabularies defaulting to []
@mamico I think that would be okay, and fully backward-compatible.
On the other hand, it might be nice if there were a way to mark a vocabulary as context-dependent when it is defined, and have plone.restapi & volto use that information. There would be a lot more details and moving parts to figure out for this, though.
@davisagli can you help me with the unit test? thanks in advance.
@mamico @davisagli
Maintaining the list might suck, and not obvious for front-end/integrators that do not know about which vocabularies are contextual and which not.
Agree
Can we provide a default list of vocabularies at least? or defaulting to
[]is for backwards compatibilities concerns? Maybe suggest a good known list of them for new projects? o
We can look into the default vocabularies of plone.restapi, but if we set a default other than [], this change will be breaking. Is this acceptable for version 18.* ?
or the other way around, suggest the list by default, warn about it in the upgrade guide and suggest people to use
[]if they want to be conservative.
I had set the needs: docs label from the beginning for that purpose, just needed time to do it. :)
@mamico @sneridagh So a different and maybe easier to use approach here would be:
- If a vocab name is passed, get it from the root (same as now)
- If a vocab URL is passed, get it from the URL as written, instead of extracting the name and fetching it from the root. This is a breaking change, it makes these vocabularies contextual.
- Make sure that when plone.restapi generates a vocabulary URL, it uses an appropriate context. This might require inventing a way to mark on the vocabulary factory whether it is context-dependent or not.
We need to keep in mind that there might be a core vocabulary which never varies based on the context, but an integrator needs to replace it with a custom version that is context-dependent.
@davisagli @sneridagh
We need to keep in mind that there might be a core vocabulary which never varies based on the context, but an integrator needs to replace it with a custom version that is context-dependent.
IMHO we are talking about acting in the serializer of schemes, like here:
https://github.com/plone/plone.restapi/blob/f68fab7ea3209a096423d8567fa7f70a93786c7a/src/plone/restapi/types/adapters.py#L110
in other cases the developer has complete control of the vocabulary url.
My plan:
-
We change the serializer to return the full vocabulary url for contextual vocabularies, and only the vocabulary_name (or the vocabulary url pointing to the portal root?) for non-contextual vocabularies.
-
change (like my original proposal) to use the vocabulary url as is, if it is a url, or a vocabulary url, based on the portal root, if it is a vocabulary name.
I think both changes could be independent, without major breaking, and there are no needs for a new configuration.
thoughts?
@davisagli @mamico this is an interesting PR, how can we keep this going?
@pnicolli @mamico Sorry, I'll come back to this, but I've been busy getting ready for the conference.
@davisagli Let's work on this?
@ericof @davisagli @mamico As discussed in the Volto Team Meeting today, we would like to keep this alive, this is interesting. Can we resurrect this?
I have proposed a plan here https://github.com/plone/volto/pull/6236#issuecomment-2397412286, if it is acceptable to all of you, I will gladly open the necessary pull requests.
@mamico Your plan makes sense and is more or less what I had in mind also.
We also need to change the querystring action in Volto to get the @querystring endpoint in the current context, so that the choices for criteria in the search block are loaded in the correct context. We have done this in an override for 2 projects and it seems to work fine.
We change the serializer to return the full vocabulary url for contextual vocabularies, and only the vocabulary_name (or the vocabulary url pointing to the portal root?) for non-contextual vocabularies.
How will the serializer determine whether or not the vocabulary is contextual? If there isn't an existing obvious way to do it, we can add a marker interface or attribute on the vocabulary to mark this distinction.
@davisagli @mamico can we do a final push for this?
If I understand correctly, this can now be closed becaused it's superseded by #6935 right? @davisagli @mamico
Yeah that's right.