Skip to content

Instantly share code, notes, and snippets.

@MastaAaron
Last active May 20, 2023 09:50
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MastaAaron/24193bd83e1a41523d4d78b859e441c7 to your computer and use it in GitHub Desktop.
Save MastaAaron/24193bd83e1a41523d4d78b859e441c7 to your computer and use it in GitHub Desktop.
Sanity CMS: Infinitely-nestable Categories
export default {
name: `category`,
title: `Category`,
type: `document`,
fields: [
{
name: `name`,
title: `Category Name`,
type: `string`,
validation: Rule => Rule.required()
},
{
name: `parent`,
title: `Parent Category`,
type: `reference`,
to: [{ type: `category` }]
}
]
}
import S from '@sanity/desk-tool/structure-builder'
import client from 'part:@sanity/base/client'
import EditIcon from 'part:@sanity/base/edit-icon'
const getCategoryMenuItems = id => {
const customEditButton = S.menuItem()
.icon(EditIcon)
.title(`Edit Category`)
.showAsAction({ whenCollapsed: true })
.intent({
type: `edit`,
params: { id, type: `category` }
})
const defaultItems = S.documentTypeList(`category`).getMenuItems()
return [...defaultItems, customEditButton]
}
const subCategoryList = async (categoryId) => {
const category = await client.getDocument(categoryId)
return S.documentTypeList(`category`)
.title(category.name)
.filter('parent._ref == $categoryId')
.params({ categoryId })
.menuItems(getCategoryMenuItems(categoryId))
.canHandleIntent(() => false)
.initialValueTemplates([
S.initialValueTemplateItem(
`subCategory`,
{ parentCategoryId: categoryId }
)
])
.child(subCategoryList)
}
export default () => S.list()
.title('Content')
.items([
S.listItem()
.title(`Categories`)
.child(
S.documentTypeList(`category`)
.title(`Categories`)
.filter('_type == "category" && !defined(parent)')
.canHandleIntent(() => false)
.child(subCategoryList)
),
...S.documentTypeListItems().filter(item => {
const id = item.getId()
return ![`category`].includes(id)
})
])
import T from '@sanity/base/initial-value-template-builder'
const subCategoryTemplate = T.template({
id: `subCategory`,
title: `Sub-category`,
schemaType: `category`,
parameters: [
{
name: `parentCategoryId`,
title: `Parent Category ID`,
type: `string`
}
],
value: parameters => ({
parent: {
_type: `reference`,
_ref: parameters.parentCategoryId
}
})
})
export default [...T.defaults(), subCategoryTemplate]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment