sno-blog/sanity/schemas/documents/post.ts
2026-02-02 22:53:36 +03:00

140 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineField, defineType } from 'sanity'
export const postType = defineType({
name: 'post',
title: 'Пост',
type: 'document',
icon: () => '📝',
fields: [
defineField({
name: 'title',
title: 'Заголовок',
type: 'string',
validation: (Rule) => Rule.required().min(5).max(200),
}),
defineField({
name: 'slug',
title: 'Slug',
type: 'slug',
options: {
source: 'title',
maxLength: 96,
},
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'excerpt',
title: 'Краткое описание',
type: 'text',
rows: 3,
description: 'Краткое описание для карточки поста (до 200 символов)',
validation: (Rule) => Rule.max(200),
}),
defineField({
name: 'mainImage',
title: 'Главное изображение',
type: 'image',
options: {
hotspot: true,
},
fields: [
{
name: 'alt',
type: 'string',
title: 'Альтернативный текст',
description: 'Важно для SEO и доступности',
},
],
}),
defineField({
name: 'author',
title: 'Автор',
type: 'reference',
to: { type: 'author' },
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'categories',
title: 'Категории',
type: 'array',
of: [{ type: 'reference', to: { type: 'category' } }],
}),
defineField({
name: 'publishedAt',
title: 'Дата публикации',
type: 'datetime',
initialValue: () => new Date().toISOString(),
}),
defineField({
name: 'body',
title: 'Содержимое',
type: 'blockContent',
}),
defineField({
name: 'seo',
title: 'SEO',
type: 'object',
options: {
collapsible: true,
collapsed: true,
},
fields: [
{
name: 'metaTitle',
title: 'Meta Title',
type: 'string',
description: 'Оставьте пустым для использования заголовка поста',
},
{
name: 'metaDescription',
title: 'Meta Description',
type: 'text',
rows: 3,
description: 'Оставьте пустым для использования краткого описания',
},
{
name: 'ogImage',
title: 'Open Graph изображение',
type: 'image',
description: 'Изображение для социальных сетей (1200x630)',
},
],
}),
],
preview: {
select: {
title: 'title',
author: 'author.name',
media: 'mainImage',
date: 'publishedAt',
},
prepare({ title, author, media, date }) {
const formattedDate = date
? new Date(date).toLocaleDateString('ru-RU')
: 'Не опубликовано'
return {
title,
subtitle: `${author || 'Без автора'}${formattedDate}`,
media,
}
},
},
orderings: [
{
title: 'Дата публикации (новые)',
name: 'publishedAtDesc',
by: [{ field: 'publishedAt', direction: 'desc' }],
},
{
title: 'Дата публикации (старые)',
name: 'publishedAtAsc',
by: [{ field: 'publishedAt', direction: 'asc' }],
},
{
title: 'Заголовок',
name: 'titleAsc',
by: [{ field: 'title', direction: 'asc' }],
},
],
})