Foundation + Schemas
This commit is contained in:
40
src/keystatic/fields/content/base.ts
Normal file
40
src/keystatic/fields/content/base.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
import { STATUS_OPTIONS } from '@/lib/constants/status'
|
||||
import { SEGMENT, SEGMENT_MESSAGE, slugify } from '@/lib/content/slug'
|
||||
|
||||
export const title = fields.slug({
|
||||
name: {
|
||||
label: 'Title',
|
||||
validation: {
|
||||
isRequired: true,
|
||||
},
|
||||
},
|
||||
slug: {
|
||||
label: 'File ID',
|
||||
description: 'Internal and unique across the collection.',
|
||||
generate: slugify,
|
||||
validation: {
|
||||
pattern: {
|
||||
regex: SEGMENT,
|
||||
message: SEGMENT_MESSAGE,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const status = fields.select({
|
||||
label: 'Status',
|
||||
options: STATUS_OPTIONS,
|
||||
defaultValue: 'draft',
|
||||
})
|
||||
|
||||
export const noindex = fields.checkbox({
|
||||
label: 'Hide from search engines',
|
||||
})
|
||||
|
||||
export const base = {
|
||||
title,
|
||||
status,
|
||||
noindex,
|
||||
}
|
||||
12
src/keystatic/fields/content/content.ts
Normal file
12
src/keystatic/fields/content/content.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
import { assets } from '@/lib/content/assets'
|
||||
|
||||
export const content = (collection: string) =>
|
||||
fields.markdoc({
|
||||
label: 'Content',
|
||||
options: {
|
||||
heading: [2, 3, 4],
|
||||
image: assets(collection),
|
||||
},
|
||||
})
|
||||
25
src/keystatic/fields/content/cover.ts
Normal file
25
src/keystatic/fields/content/cover.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
import { assets } from '@/lib/content/assets'
|
||||
|
||||
export const cover = (collection: string) =>
|
||||
fields.object(
|
||||
{
|
||||
image: fields.image({
|
||||
label: 'Image',
|
||||
...assets(collection),
|
||||
}),
|
||||
alt: fields.text({
|
||||
label: 'Alt text',
|
||||
}),
|
||||
caption: fields.text({
|
||||
label: 'Caption',
|
||||
}),
|
||||
credit: fields.text({
|
||||
label: 'Credit',
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Cover',
|
||||
},
|
||||
)
|
||||
18
src/keystatic/fields/content/dates.ts
Normal file
18
src/keystatic/fields/content/dates.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
export const dates = fields.object(
|
||||
{
|
||||
published: fields.datetime({
|
||||
label: 'Published',
|
||||
defaultValue: {
|
||||
kind: 'now',
|
||||
},
|
||||
}),
|
||||
updated: fields.datetime({
|
||||
label: 'Updated',
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Dates',
|
||||
},
|
||||
)
|
||||
42
src/keystatic/fields/content/route.ts
Normal file
42
src/keystatic/fields/content/route.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
import { ARTICLES } from '@/lib/constants/collections'
|
||||
import { OPTIONAL_SEGMENT, SEGMENT_MESSAGE } from '@/lib/content/slug'
|
||||
|
||||
const segment = fields.text({
|
||||
label: 'URL segment',
|
||||
description: 'Optional- Leave empty to use the slugified title',
|
||||
validation: {
|
||||
pattern: {
|
||||
regex: OPTIONAL_SEGMENT,
|
||||
message: SEGMENT_MESSAGE,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const pageRoute = fields.object(
|
||||
{
|
||||
segment,
|
||||
},
|
||||
{
|
||||
label: 'Route',
|
||||
},
|
||||
)
|
||||
|
||||
export const articleRoute = fields.object(
|
||||
{
|
||||
segment,
|
||||
parent: fields.relationship({
|
||||
label: 'Parent',
|
||||
description: 'Empty makes this a root',
|
||||
collection: ARTICLES,
|
||||
}),
|
||||
index: fields.integer({
|
||||
label: 'Index',
|
||||
description: 'Sorts among siblings. Empty sorts by date, newest first',
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'Route',
|
||||
},
|
||||
)
|
||||
33
src/keystatic/fields/content/summary.ts
Normal file
33
src/keystatic/fields/content/summary.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { fields } from '@keystatic/core'
|
||||
|
||||
import { cover } from './cover'
|
||||
|
||||
const excerpt = fields.text({
|
||||
label: 'Excerpt',
|
||||
multiline: true,
|
||||
validation: {
|
||||
length: {
|
||||
max: 160,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const pageSummary = fields.object(
|
||||
{
|
||||
excerpt,
|
||||
},
|
||||
{
|
||||
label: 'Summary',
|
||||
},
|
||||
)
|
||||
|
||||
export const articleSummary = (collection: string) =>
|
||||
fields.object(
|
||||
{
|
||||
excerpt,
|
||||
cover: cover(collection),
|
||||
},
|
||||
{
|
||||
label: 'Summary',
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user