reference an entire collection (relationship to all docs)

default discord avatar
unonweb
9 months ago
1 1

I don't understand how I can reference an entire collection from within a block.

I would like to build a block that enables the user to reference a collection that will be included in the block.
For example: The user wants to build a "Shop" page. She includes some layout blocks. Now she wants to include all docs from the "Products" collection into the block, so that they're going to show up on the "Shop" page at the place she selected within the overall layout.

What I've tried:

  1. Use a "relationship" field. Problem: I can't select an entire collection.
  2. Use a "select" field which has options for the available collections. Problem: I can query for the collection data but I don't know where to save it.

This question follows #1516 in my process to understand the architecture of payload (how it is meant to be used). Thank you.

  • discord user avatar
    jmikrut
    Payload Team
    9 months ago

    Hey @unonweb

    I would go with your second option but I think you're thinking about this a bit incorrectly.

    I can query for the collection data but I don't know where to save it.

    The collection data is saved in the separate collection. I think you're trying to duplicate it or similar, which would not be a good idea.

    Here's a use case that we come up against a lot.

    Say you're building a Next site on a layout-builder mentality, and you have a few blocks. One is Archive or similar that allows a user to choose a collection to render an archive for, and then the frontend component should output the most recent 10 posts in the collection that was selected.

    The way we'd do this would be either one of two ways:

    1. in getStaticProps or wherever, check to see if you have any Archive blocks and then automatically make fetches to the /api/whatever-collection endpoint, and then send back the results from getStaticProps.
    2. Just have the frontend React component go and fetch the docs that it should. This is not ideal because the frontend will have to make another fetch, and you'll need to have some type of "loading" state or similar, but it could work just fine.

    In either case, your block itself would only store blockType: 'archive' and then collection: 'posts' or whatever. It would not store any data.

    1 reply
  • default discord avatar
    unonweb
    9 months ago

    In my case I want the fronted to be complety independent of my PayloadCMS. That's why everything's exported as json data after change.
    I would like to give my users the possibility to include a collection when building a page.
    Ideally they would be able to select like "On this page I want to include all products that are cheaper than 50€" or "On that page I want to include all blog posts that are tagged with 'traveling'".
    So in the frontend I would have the corresponding data as json for the corresponding page.

    I can use a select field and further fields that enable the user to specify the desired data.
    I can query this data in a afterRead hook and export it as json.
    But I don't know how to give the user feedback in the admin UI showing which docs are included.
    The only field related to this is relationship and it would work great if I could reference an entire collection with it.
    It would also work if I could do something like:

    const relationField = [
    	{
    		type: 'select',
    		name: 'selectedCollection',
    		options: ['shop-products', 'shop-categories'],
    	},
    	{
    
    		type: 'relationship',
    		relationTo: (args) => args.siblingData.selectedCollection, // doesn't work
    		hooks: {
    			afterRead: async (args) => {
            // populate relationship with entire collection
    				const collection = args?.siblingData?.selectedCollection // works
    				const result = await payload.find({
    					collection: collection,
    				})
    				return result
    			}
    		}
    	}
    ]

    Well, then I'd still have the issue that the admin UI requires that the relationship field contains just an array of IDs.
    Don't know how to solve this.
    Custom UI field?

Open the post
Continue the discussion in GitHub
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.