В предыдущем проекте в Keystone 4 я мог работать с управлением версиями контента. То есть, если бы я обновлял объект контента (например, BlogPost), у меня была бы возможность переключаться между предыдущей версией сообщения в блоге и текущей версией.
Я не вижу никаких вариантов для этого в документации по Keystone 6, и мне также трудно найти какие-либо ресурсы по этой теме в Интернете. Есть ли у кого-нибудь понимание этого? Если это невозможно из коробки - есть ли у вас какие-либо советы, как это сделать вручную?
заранее спасибо
Управление версиями контента — это то, что команда Keystone много обсуждала внутри, но это довольно сложная область. Существует так много разных способов решения проблемы, даже при управлении версиями в рамках одного элемента. Если вы привнесете в него отношения и управление версиями для нескольких элементов, проблемное пространство быстро разрастется.
Если собственное решение действительно будет построено, оно, вероятно, будет построено «поверх» Keystone — аналогично пакету @keystone-6/auth — то есть отдельному настраиваемому пакету, который использует задокументированные API Keystone для добавления функциональность. Несмотря на это, в настоящее время рабочие процессы управления версиями и публикации — это то, что вам нужно будет разработать и создать самостоятельно.
Мой совет будет заключаться в том, чтобы сначала четко определить, что именно вам нужно для версии, а что нет. Что следует учитывать:
Tags
, является ли редактирование тегов новой «версией» сообщения или это «вне» версионной части?)Некоторые основные подходы, которые приходят на ум:
Для чего-то относительно простого, такого как сообщение в блоге, вы, возможно, сможете обойтись черновиком/опубликованным рабочим процессом, реализованным в элементе на уровне поля. Что-то вроде этого:
Post: list({
fields: {
slug: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
publishedTitle: text({ validation: { isRequired: true } }),
publishedBody: document({ /* ... */ }),
draftTitle: text({ validation: { isRequired: true } }),
draftBody: document({ /* ... */ }),
},
// access, hooks, etc.
}),
Ваш внешний интерфейс отображает только поле published...
, но вы ограничиваете бэкенд, позволяя редактировать только поля draft...
(вы даже можете скрыть опубликованные поля из пользовательского интерфейса администратора). Можно добавить крючок или пользовательскую мутацию, чтобы «продвигать» черновик контента для публикации путем его копирования между полями. При правильном контроле доступа вы даже можете настроить внешний интерфейс для предварительного просмотра черновика контента institchu с помощью магического параметра URL или чего-то еще.
Это довольно простой, но простой в настройке и использовании.
Более мощной альтернативой было бы представление версий отдельными элементами и использование поля для отслеживания того, какая версия является текущим опубликованным контентом:
Post: list({
fields: {
slug: text({ validation: { isRequired: true }, isIndexed: true }),
title: text({ validation: { isRequired: true } }),
body: document({ /* ... */ }),
isPublished: checkbox(),
},
// access, hooks, etc.
}),
В этом случае поле slug
не является уникальным в списке — каждое сообщение может иметь несколько элементов, представляющих либо предстоящие черновики, либо предыдущие версии. Когда версия поста публикуется (путем установки isPublished
в значение true), хук гарантирует, что для всех элементов с одним и тем же слагом флаг isPublished
установлен в значение false. Внешний интерфейс просто фильтрует isPublished
, чтобы получить текущую версию (при необходимости с контролем доступа). Это позволяет как публиковать обновления, так и выполнять откат к любой предыдущей версии. Это также в некоторой степени решает отношения - например. если у вас есть связанный список Tags
, связанный по принципу «многие ко многим» с Posts
, обновления тегов публикации версионируются вместе с содержимым.
Чтобы сгладить рабочий процесс, вероятно, было бы полезно иметь пользовательскую мутацию, которая дублировала бы существующую публикацию, позволяя вам легко вносить изменения в существующий контент. И, возможно, настраиваемая страница пользовательского интерфейса администратора, которая поможет визуализировать историю сообщений и управлять действиями по возврату и т. д.
Это всего лишь два примера, но есть десятки других подходов к решению проблемы. Просто четко определите свои требования, а затем сделайте самую простую вещь, которая работает! :)
Также ознакомьтесь с этой записью, чтобы добавить статус публикации в список, создать базовый черновой/опубликованный рабочий процесс — keystonejs.com/docs/walkthroughs/lesson-3. Это не имеет прямого отношения к моим примерам выше, просто еще одно решение, которое делает разные компромиссы.
Абсолютно идеальный ответ. Большое спасибо @Molomby. Я изучу ваши варианты дальше и, вероятно, прибегну к слабости Keystone, если я застряну на чем-то более конкретном. Еще раз спасибо!