Разработка кастомных коллекций (Collections) Payload CMS

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомных коллекций (Collections) Payload CMS
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Кастомные коллекции Payload CMS

Коллекция (Collection) в Payload — тип контента с REST API, GraphQL схемой и интерфейсом в admin panel, генерируемыми автоматически из TypeScript-конфигурации. Каждая коллекция хранится в отдельной таблице PostgreSQL или коллекции MongoDB.

Структура коллекции

// collections/Products.ts
import { CollectionConfig } from 'payload/types'

const Products: CollectionConfig = {
  slug: 'products',           // URL сегмент: /api/products
  labels: {
    singular: 'Товар',
    plural: 'Товары',
  },
  admin: {
    useAsTitle: 'name',
    defaultColumns: ['name', 'price', 'category', 'inStock'],
    group: 'Каталог',
  },
  // ...
}

Типы полей

fields: [
  // Текстовые
  { name: 'name', type: 'text', required: true },
  { name: 'description', type: 'textarea' },
  { name: 'content', type: 'richText' },

  // Числа и даты
  { name: 'price', type: 'number', min: 0, required: true },
  { name: 'publishedAt', type: 'date' },

  // Выбор
  {
    name: 'status',
    type: 'select',
    options: [
      { label: 'Активен', value: 'active' },
      { label: 'Архив', value: 'archived' },
    ],
    defaultValue: 'active',
  },

  // Медиа
  { name: 'image', type: 'upload', relationTo: 'media' },

  // Связи
  {
    name: 'category',
    type: 'relationship',
    relationTo: 'categories',
    hasMany: false,
  },
  {
    name: 'tags',
    type: 'relationship',
    relationTo: 'tags',
    hasMany: true,
  },

  // Массив объектов
  {
    name: 'variants',
    type: 'array',
    fields: [
      { name: 'sku', type: 'text', required: true },
      { name: 'color', type: 'text' },
      { name: 'size', type: 'text' },
      { name: 'stock', type: 'number', defaultValue: 0 },
    ],
  },

  // Блоки (как Gutenberg)
  {
    name: 'sections',
    type: 'blocks',
    blocks: [TextBlock, ImageBlock, CTABlock],
  },

  // Группа полей
  {
    name: 'seo',
    type: 'group',
    fields: [
      { name: 'title', type: 'text' },
      { name: 'description', type: 'textarea' },
    ],
  },
]

Доступ (Access Control)

access: {
  // Чтение — публичное
  read: () => true,

  // Создание — только авторизованные
  create: ({ req: { user } }) => Boolean(user),

  // Обновление — только владелец или admin
  update: ({ req: { user }, id }) => {
    if (!user) return false
    if (user.role === 'admin') return true
    return { author: { equals: user.id } }  // фильтр-условие
  },

  // Удаление — только admin
  delete: ({ req: { user } }) => user?.role === 'admin',
},

Хуки коллекции

hooks: {
  beforeChange: [
    async ({ data, req, operation }) => {
      // Автоматический slug
      if (operation === 'create' && !data.slug) {
        data.slug = data.name
          .toLowerCase()
          .replace(/\s+/g, '-')
          .replace(/[^\w-]/g, '')
      }
      // Установить автора
      if (operation === 'create' && req.user) {
        data.author = req.user.id
      }
      return data
    },
  ],

  afterChange: [
    async ({ doc, operation }) => {
      // Инвалидация Next.js кэша
      if (operation === 'update') {
        await fetch(`/api/revalidate?path=/products/${doc.slug}`, {
          method: 'POST',
        })
      }
    },
  ],

  afterDelete: [
    async ({ doc }) => {
      // Очистка связанных данных
      console.log(`Product ${doc.id} deleted`)
    },
  ],
},

Версионирование

versions: {
  maxPerDoc: 20,
  drafts: {
    autosave: {
      interval: 2000,  // автосохранение каждые 2 секунды
    },
  },
},

Запросы к коллекции

// На сервере (Next.js Server Component)
import { getPayload } from 'payload'
import config from '@payload-config'

const payload = await getPayload({ config })

// Найти опубликованные товары в категории
const result = await payload.find({
  collection: 'products',
  where: {
    and: [
      { status: { equals: 'active' } },
      { category: { equals: categoryId } },
      { price: { less_than: 10000 } },
    ],
  },
  sort: '-createdAt',
  limit: 20,
  page: 1,
  depth: 2,  // глубина populate связей
})

const { docs, totalDocs, hasNextPage } = result

REST API (автогенерируемый)

# Список
GET /api/products?where[status][equals]=active&limit=20

# Один документ
GET /api/products/:id

# Создать (требует авторизации)
POST /api/products
Authorization: Bearer <token>
Content-Type: application/json

# Обновить
PATCH /api/products/:id

# Удалить
DELETE /api/products/:id

Сроки

Настройка одной коллекции с полями, доступом и хуками — 2–4 часа. Полный каталог (5–10 взаимосвязанных коллекций) — 2–4 дня.