React / Contentful — Создание записей с помощью связанных объектов

Contentful стала моей любимой безголовой CMS. Я использую ее для создания статических веб-страниц, этого блога и хранения других форм данных, таких как профили пользователей.

Как и многие другие CMS, Contentful — это система хранения данных на основе объектов. Contentful называет объекты моделями содержимого. Модели контента могут иметь поля нескольких типов, таких как короткий текст, длинный текст (Rich Text или Markdown), число, булево значение и т.д. Каждая запись определенной модели контента называется записью, а поля модели контента могут иметь тип, который ссылается на другие записи модели контента.

В качестве простого примера можно привести модель контента под названием Blog Post и модель под названием Author. Поле Author в Blog Post будет ссылаться на запись типа Author. Ссылочные поля могут ссылаться как на одну запись, так и на множество.

Поскольку я использую Contenful в основном в приложениях на React / Next.JS, это руководство будет посвящено программному созданию записей со связанными объектами с помощью Contentful Content Management API (CMA) Javscript SDK. Я также буду предполагать, что вы уже используете Contentful’s Delivery API в своем React-проекте.

Установите JavaScript SDK

Чтобы добавлять, удалять или изменять записи, вам необходимо установить Contentful Management Javascript SDK. Для этого просто выполните следующую команду в корневом каталоге вашего проекта:

npm i contentful-management
Войти в полноэкранный режим Выйти из полноэкранного режима

Если у вас его еще нет, вам нужно будет сгенерировать токен управления контентом в разделе API-ключи в настройках Contentful:

Затем добавьте следующую переменную окружения в файл env.local:

CONTENTFUL_MANAGEMENT_TOKEN=CFPAT-W-vQPcKWMV5GhXV1CAVWDEazy-1yRpnN4H3cqWFGfXU
CONTENTFUL_SPACE_ID=<YOUR CONTENTFUL SPACE ID>
Войти в полноэкранный режим Выйти из полноэкранного режима

Создание библиотечных функций

Теперь, когда наше окружение настроено, мы можем создать библиотечные функции для управления контентом:

/** Function for creating JSON link objects **/

export function createLinkObject(id) {
    const link = `{
        "en-US": {
            "sys": {
                "type": "Link",
                "linkType": "Entry",
                "id": "${id}"
            }
        }
      }`;
    return JSON.parse(link);
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Приведенная выше функция создает сущность JSON, которую CMA ожидает для связывания объектов. Вам просто нужно передать ей идентификатор записи, которую вы хотите связать, и она вернет объект JSON.

Чтобы увидеть, как это работает, давайте теперь создадим функцию для добавления записи:

import { createLinkObject } from '/path/to/lib/file'

const contentful = require('contentful-management')

function slugify(str) {
    /** Convert string to URL-safe slug */
    return str
        .toString()                   // Cast to string (optional)
        .normalize('NFKD')            // The normalize() using NFKD method returns the Unicode Normalization Form of a given string.
        .toLowerCase()                // Convert the string to lowercase letters
        .trim()                       // Remove whitespace from both sides of a string (optional)
        .replace(/s+/g, '-')         // Replace spaces with -
        .replace(/[^w-]+/g, '')     // Remove all non-word chars
        .replace(/--+/g, '-');      // Replace multiple - with single -
}

export async function createPost({
    title,       // Post title (string)
    user,        // User who posted (entry object)
    category,    // Category (entry object)
    content      // Post content (markdown)
}) {
    // Create the CMA client
    const client = contentful.createClient({
        accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN
    })

    // Get your Contentful space
    const space = await client.getSpace(process.env.CONTENTFUL_SPACE_ID)

    // Get your Contentful environment
    const env = await space.getEnvironment('master')

    // Our entry to be created
    const entryFields = {
        title: {
            'en-US': title
        },
        slug: {
            'en-US': slugify(title)
        },
        user: createLinkObject(user.sys.id),
        category: createLinkObject(category.sys.id),
        content: {
            'en-US': content
        }
    }

    const contentType = 'blogPost' // Contentful model type

    // Execute entry creation
    const entry = await env.createEntry(contentType, {
        fields: entryFields
    })

    // If we get a new entry ID, then success, otherwise default to null
    const newEntryId = entry.sys.id ?? null;

    if (newEntryId) {
        // Publish our entry, if success
        const pub = await entry.publish();
        return ({
            'status': 'success',
            'entryId': newEntryId
        })
    } else {
        console.log(entry)

        return ({
            'status': 'error',
            'message': 'Failed to create post'
        })
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Первая функция slugify преобразует наш заголовок в безопасную для URL строку для использования в качестве slug. Вы можете добавить некоторую логику для проверки существующего slug, но маловероятно, что вы опубликуете два поста с одинаковым названием.

В функции createPost() мы сначала инстанцируем клиента CMA, затем извлекаем наше пространство Contentful, затем наше окружение (скорее всего, master). Затем мы создаем наш объект записи и используем функцию createLinkObject() для добавления пользователя и категории. Наконец, мы выполняем createEntry() с типом содержимого и объектом Entry. Если мы обнаружим ID нового объекта Entry, значит, все прошло по плану!

Надеюсь, вы нашли это руководство полезным. Contentful — это отличный бэкенд общего назначения для статически генерируемых страниц, и я продолжаю находить для него новые и интересные применения.

Для получения дополнительной информации, пожалуйста, посетите наш блог.

Оцените статью
Procodings.ru
Добавить комментарий