The
data
argument of the
beforeChange
collection hook looks like this:
{
slug: 'slug-in-german',
title: 'Title in German',
excerpt: 'The excerpt goes here.',
_status: 'draft',
}
(ultimately to know whether or not the field is
localized: true
or not).
I went in and used
req.payload.config.collections
, filtered it to get the current collection, and started parsing that to try and reduce it to something that would look like this:
{
slug: false,
title: true,
excerpt: true,
_status: false,
}
But once you start adding Tabs and Groups and Arrays and Blocks and ... into the mix, it start getting a little hairy and feeling grosser and grosser. π
There's got to be a better way, right? π π€
Or I wonder if the
buildStateFromSchema
function might do it for you!
Try passing in the fields array into buildStateFromSchema and see what happens
Oooh you got me excited, let me give that a go! π
Hmmm doesn't seem to be quite what I need, this is what
buildStateFromSchema
returns:
{
title: {
valid: true,
value: 'Title in German',
initialValue: 'Title in German',
validate: [Function (anonymous)],
condition: undefined,
passesCondition: true
},
slug: {
valid: true,
value: 'slug-in-german',
initialValue: 'slug-in-german',
validate: [Function (anonymous)],
condition: undefined,
passesCondition: true
},
...
}
hm
what about
reduceFieldsToValues
?
or wait
the main problem is parsing more complex blocks isn't it?
e.g. blocks with subfields?
You could always just import your collection config directly
But again, you would probably need to still handle nested fields
wouldn't that result in the same data compared to using req.payload.config.collections?
Likely, but you could skip the faff of filtering from the collections array if you want to get the config of a specific static collection
Yeah getting the full config is pretty straightforward here one way or the other, the tricky part is mapping the data to their associated field config... π€
You might have to make a recursive parser to get the output you specifically want
Another to approach the problem I have could be to find a way to emulate the
afterChange
state of the doc with
locale: "all"
.
For example, following my initial example, if I could get:
{
id: '642609c1a7d2bc624df538da',
title: {
en: 'Title in English',
de: 'Title in German'
},
slug: {
en: 'slug-in-english',
de: 'slug-in-german'
},
excerpt: {
de: 'The excerpt goes here.'
},
_status: 'draft',
createdAt: '2023-03-30T22:14:25.318Z',
updatedAt: '2023-04-05T07:02:50.800Z'
}
ie:
findByID
result + the current operation's data, I'd be golden. π
I may have to do more digging into how Payload work on the inside. π
Yeah that's what I started doing and it quickly started feeling a bit "gross". And given that Payload probably already do this somehow somewhere, I figured that I probably shouldn't be reinventing the wheel and that maybe someone would know where the magic happens within Payload - and how to utilize it. π
Haven't had the chance to dig more into this yet today, but giving it a bump in case anyone who knows how Payload works on the inside happens to be around and has thoughts. π
I think the recursive parser is a fine approach, you would just separate your parsing functions into field types and loop over the a collection config and generate this obj/map
What are you trying to achieve, would a fieldHook work better for you?
https://payloadcms.com/docs/hooks/fieldsAh thanks Jarrod! The fieldHook approach could work indeed, although I'd then need to loop over every field in my plugin where I extend the config and add a hook to them. And I'll probably have to go through the same kind of recursive parser to achieve that. π€
That being said, both @thompsonsj (
https://github.com/payloadcms/payload/discussions/1508) and @Exo (
https://discord.com/channels/967097582721572934/967097582721572937/1093593337954574386) might have already solved this in their own plugins, so I'm gonna check their work and learn from it before trying to reinvent the wheel. π
I'll try to remember to close the loop on this thread once I have. π
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.