Summary
Aurora fetches the current page's content once per request, in the fetchPloneContent middleware, with a fixed list of expansions:
const expand = ['navroot', 'breadcrumbs', 'navigation', 'actions'];
// ...
if (userId) expand.push('types');
// ...
cli.getContent({ path, expand }),
(apps/aurora/app/middleware.server.ts#L140-L175)
An add-on that publishes an expandable plone.restapi component cannot add it to that list. It has to make a request of its own, and the obvious place, a rootLoaderData utility, runs on every page. Volto solves this with config.settings.apiExpanders: add-ons declare, by path, which components ride along on the content request.
The use case
pas.plugins.identity, ported to Aurora in collective/pas-plugins-identity#132, has a profile gate: a signed-in user whose profile is missing required fields is held until it is complete.
To decide, it needs the user's @my-profile on every page. The backend offers my-profile as an expandable component for exactly this reason. In Volto, the add-on adds it to apiExpanders, so it costs nothing:
config.settings.apiExpanders = [
...config.settings.apiExpanders,
{ match: '', GET_CONTENT: ['my-profile'] },
];
In Aurora it is a rootLoaderData utility making one extra request per signed-in page view:
config.registerUtility({
name: 'IdentityProfileGate',
type: 'rootLoaderData',
method: async ({ request }) => {
const token = await getAuthFromRequest(request);
if (!token) return { status: 200, data: {} };
const answer = await callBackend(request, endpoints.myProfile(), { token });
return { status: 200, data: { identityProfile: await answer.json() } };
},
});
(source)
A rootContentSubRequest utility (apps/aurora/app/config/server.server.ts#L25) cannot help either: it runs after the content request and can only add requests of its own.
Proposal
A declarative way for add-ons to add expansions to the content request. Either a setting shaped like Volto's:
config.settings.apiExpanders = [
...(config.settings.apiExpanders ?? []),
{ match: '', GET_CONTENT: ['my-profile'], authenticated: true },
];
or a utility type, contentExpanders, whose method receives { request, path, userId } and returns the names to add.
fetchPloneContent then merges them into expand, and the result is available to loaders and slots as content['@components'][name], as it already is for navigation or breadcrumbs.
Details worth deciding:
- Signed-in only. Volto's
apiExpanders cannot say "signed-in users only": the anonymous request carries the parameter too, and the backend answers it with nothing. Since the middleware already knows userId (it uses it for types), an authenticated flag would keep anonymous URLs, and so their cache keys, unchanged.
- Matched by path, like Volto's
match, so an add-on can expand only below a section.
- The 401 retry. The anonymous retry already filters out
types. Signed-in-only expansions should be dropped there too.
Related
Summary
Aurora fetches the current page's content once per request, in the
fetchPloneContentmiddleware, with a fixed list of expansions:(
apps/aurora/app/middleware.server.ts#L140-L175)An add-on that publishes an expandable
plone.restapicomponent cannot add it to that list. It has to make a request of its own, and the obvious place, arootLoaderDatautility, runs on every page. Volto solves this withconfig.settings.apiExpanders: add-ons declare, by path, which components ride along on the content request.The use case
pas.plugins.identity, ported to Aurora in collective/pas-plugins-identity#132, has a profile gate: a signed-in user whose profile is missing required fields is held until it is complete.To decide, it needs the user's
@my-profileon every page. The backend offersmy-profileas an expandable component for exactly this reason. In Volto, the add-on adds it toapiExpanders, so it costs nothing:In Aurora it is a
rootLoaderDatautility making one extra request per signed-in page view:(source)
A
rootContentSubRequestutility (apps/aurora/app/config/server.server.ts#L25) cannot help either: it runs after the content request and can only add requests of its own.Proposal
A declarative way for add-ons to add expansions to the content request. Either a setting shaped like Volto's:
or a utility type,
contentExpanders, whose method receives{ request, path, userId }and returns the names to add.fetchPloneContentthen merges them intoexpand, and the result is available to loaders and slots ascontent['@components'][name], as it already is fornavigationorbreadcrumbs.Details worth deciding:
apiExpanderscannot say "signed-in users only": the anonymous request carries the parameter too, and the backend answers it with nothing. Since the middleware already knowsuserId(it uses it fortypes), anauthenticatedflag would keep anonymous URLs, and so their cache keys, unchanged.match, so an add-on can expand only below a section.types. Signed-in-only expansions should be dropped there too.Related
@plone/clientendpoints for add-ons.getContentwould still be the core method; this issue is about what it is asked for.