Customizing filtering for references in Sanity Studio V2

5 replies
Last updated: Dec 13, 2022
Passing properties to Document / Dynamic reference filterI have some document that I sometimes want to behave a bit different. I want to pass parameters/properties to that document so that I can adapt to those.

In my case I have a case where I only want the user to be able to select a
multipurposeCardV1 that has some “tags” (the
tag
array should not be empty)
This is how it looks like now:

export default {
  name: 'multipurposeCardContainerV1',
  title: 'Multipurpose Card container',
  type: 'document',
  fields: [
    {
      name: 'cards',
      type: 'array',
      title: 'Cards',
      of: [{ type: 'reference', to: [{ type: 'multipurposeCardV1' }] }],
    },
  ],
}
I want to be able to do something like

export default (props) => ({
  name: 'multipurposeCardContainerV1',
  title: 'Multipurpose Card container',
  type: 'document',
  fields: [
    {
      name: 'cards',
      type: 'array',
      title: 'Cards',
      of: [
        {
          type: 'reference',
          to: [{ type: 'multipurposeCardV1' }],
          options: {
            filter: props.onlyAllowTaggedCards ? 'count(general.tags) > 0' : '',
          },
        },
      ],
    },
  ],
})
In the containing document I’m looking to do something like:

// Document definition ...
{
      name: 'multiPurposeCardContainer',
      type: 'multipurposeCardContainerV1',
      options: { onlyAllowTaggedCards: true },
    },
I tried using the function form of filter but the passed
document
is not the document that I want to check - in this case it’s the document’s parent
_type
I want to assert.

options: {
        filter: ({ document }: { document: SanityDocument }) => {
          // This is not the document I'm interested in. I'd like document._parent._type or something.
          if (document._type !== 'discoverPageV1') {
            return ''
          }

          return 'count(general.tags) > 0'
        },
      },
This is in sanity studio V2. How do I customise the filtering?
Dec 12, 2022, 3:19 PM
Hey
user B
! Is the document that you're receiving referencing the parent document? If so, what's the name of that field and what does the parent document look like?
Dec 12, 2022, 7:23 PM
Thanks for the reply
user M
!I
think that the parent that I’m getting is the container for the card, which is not really what I want.
Just to clear up some terms before I try and describe my problem: I’m using
parent to mean that document which is referencing the other document. So when I say that the c_ard_ document has a parent document multipurposeCardContainerV1. That means that multipurposeCardContainerV1 has references to multipurposeCardV1.
I need to see if the container has a parent document of type
discoverPageV1. In that case I need to limit which cards can be referenced by that container using
filter
.
The parent document (discover page):


import { Rule as RuleType } from '@sanity/types'
import Tabs from 'sanity-plugin-tabs'

export default {
  name: 'discoverPageV1',
  type: 'document',
  title: 'Discover page',
  __experimental_actions: [/*'create'*/ 'update', /*'delete'*/ 'publish'],
  inputComponent: Tabs,
  preview: {
    select: {
      title: 'Multi Purpose Cards',
    },
  },
  fieldsets: [
    {
      name: 'multiPurposeCardContainer',
      title: 'Multi Purpose Cards',
      options: { sortOrder: 10 },
    },
  ],
  fields: [
    {
      name: 'multiPurposeCardContainer',
      type: 'multipurposeCardContainerV1',
      title: 'Multi Purpose Cards',
      fieldset: 'multiPurposeCardContainer',
      validation: (Rule: RuleType) => Rule.required(),
    },
  ],
}
So the relationship is:
Discover Page -> (references) Container -> Cards
or sometimes just
Container -> Cards

if the Container is referenced by the Discover Page (which is a singleton, so it has a unique id if that helps) then we apply a filter to the cards so that only cards that has
count(general.tags) > 0
will be selectable.
Thank you for your time!
Dec 13, 2022, 9:28 AM
I can’t really find any documentation for the filter properties either. I see that
document
is used in the documentation but we have a
parent
and
path
as well, maybe it’s usable. Hard to tell though, especially now that I can’t find a way to print something to the console 🙂
Dec 13, 2022, 9:41 AM
SOLVED
Alright, so the
document
was in fact the parent discover page I was looking for all along. This worked:

{
      name: 'cards',
      type: 'array',
      title: 'Cards',
      validation: (Rule: RuleType) => Rule.required().min(1),
      of: [
        {
          type: 'reference',
          to: [{ type: 'multipurposeCardV1' }],
          options: {
            filter: ({ document, parent, path }) => {
              console.log({ document, parent, path })
              if (document._type === 'discoverPageV1') {
                return { filter: 'count(general.tags) > 0' }
              }

              return { filter: '' }
            },
          },
        },
      ],
    }
Once again, thank you so much for your time
🙏
Dec 13, 2022, 11:01 AM
Thanks for sharing your solution!
Dec 13, 2022, 4:47 PM

Sanity– build remarkable experiences at scale

The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?