Как вы можете создать собственное бесплатное поле для комментариев без сервера

1656592460 kak vy mozhete sozdat sobstvennoe besplatnoe pole dlya kommentariev bez

Шона Персада

MpCJ8q3WCMWCa4cczwBl1111OMXVssktvV21

Гибкое моделирование содержимого Contentful выходит далеко за рамки публикаций в блоге. Вот как вы можете использовать Contentful и Netlify для создания вложенной системы комментариев, которую легко модерировать и развертывать.

Мотивация

Я считаю, что большинства систем комментирования… не хватает. Disqus часто воспроизводится медленно, а их поведение отслеживания пользователей не имеет лучшей репутации. Между тем, плагин комментариев Facebook достаточно приятен, но, конечно, ограничен пользователями Facebook.

То, чего я действительно хотел, так это встроенная скорость и подход к вложенному комментированию и модерации, которые использовали такие сайты, как Hacker News и Indie Hackers, но мне требовалось решение, которое можно было бы переносить в несколько проектов.

Просто не казалось, что там идеально подходит, поэтому я решил создать свой собственный со своим списком желаний:

  • Бесплатно
  • Низкий барьер для входа минимальные шаги, необходимые для представления комментария
  • Низкие расходы — без сервера, чтобы не беспокоиться о хостинге или масштабировании
  • Легкая модерация — использовать приборную панель для выполнения CRUD на комментариях
  • Пеформант — сверхбыстрое отображение на странице
  • Гибкий — пользователи должны иметь возможность входить через несколько платформ
  • Мощный — комментарии должны иметь функции разумного форматирования
  • Высокое качество комментариев — пользователи могут голосовать за и против комментариев
  • Подписки — пользователи могут получать уведомления, когда на их комментарии отвечают

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

План

Наш пакет будет сначала включать:

Мы создадим компонент React, который будет служить нашим полем для комментариев, и предоставим ему возможность совершать вызов API в Contentful для получения комментариев в случае необходимости. Он также сможет осуществить вызов API в нашу функцию Lambda, чтобы опубликовать комментарий к Contentful.

С точки зрения проекта наша лямбда-функция будет жить рядом с нашим интерфейсным кодом. И интерфейс, и бэкэнд будут настроены для постоянного развертывания через Netlify.

Кстати, приведенный выше стек бесплатный! Ну, в основном. Если вы не собираетесь оставлять более 10000 комментариев, это бесплатно. Кроме того, я не связан ни с одной из этих компаний… Я просто люблю их вещи 🙂

Доволен за 10 секунд

Если вы еще не знакомы с Contentful и тем, как он работает, это CMS без головы (управляемая API). Вы можете моделировать содержимое с помощью различных полей и типов полей, а затем создавать содержимое на основе этих моделей. Вы можете создавать интерфейс, как вам нравится, и запрашивать свои данные с помощью их API. Он чрезвычайно гибок, а их приборная панель очень удобна в использовании. В принципе, это самое лучшее, что произошло с CMS с тех пор?

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

Мы будем использовать Contentful, поскольку:

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

Netlify за 10 секунд

Я думаю, что Netlify, безусловно, имеет самый приятный опыт развертывания для внешних программ. Он связывается с вашим репозиторием GitHub и настраивает вас на постоянное развертывание статического сайта на поддерживающий CDN хостинги. В них также есть функции Netlify, которые позволяют развертывать AWS Lambda без боли, связанной с AWS.

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

Мы будем использовать Netlify, потому что:

  • безболезненная интеграция AWS Lambda
  • возможно, вы уже используете его для своего веб-сайта/блога, требующего комментариев
  • Если вы еще не используете его, вы все еще можете развернуть функции Lambda, которые мы создаем в самой AWS

Подождите, нет «Отреагировать за 10 секунд»?

Я не знаю достаточно 10 секунд, чтобы сделать React справедливо. Если вы еще не научились, то должны! Но пропустите вещи Redux и Flux. Скорее всего, вам ничего из этого не нужно (но это другая тема в другой раз).

Моделирование контента в Contentful

Теперь к делу.

Мы можем применить два разных подхода относительно того, как обращаемся с нашими пользователями: неавтономный и вошли в комментируя:

  • Без авторизации — кто-либо может оставить комментарий, просто указав свое имя
  • Вошли — комментировать могут только пользователи, прошедшие аутентификацию в определенной системе аутентификации

Я предпочитаю комментирование после авторизации, потому что, по моему мнению, разговоры имеют тенденцию быть более цивилизованными. Кроме того, вы обычно избегаете спама. С другой стороны, барьер для создания комментария несколько выше.

Однако мы начнем с неавтоматического комментирования, потому что это проще реализовать. Как только мы промокнем ноги, мы перейдем к комментированию авторизованной учетной записи в части 2.

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

Как для подходов без авторизации, так и для вошедших в систему, наша модель содержимого комментариев также останется неизменной, хотя позже будут внесены некоторые изменения в Автор поле, как указано ниже.

Это модель, лежащая в основе нашей системы комментариев. Комментарии должны иметь четыре поля:

tp1JYhltz8FSFApiR5aS1XrwgQ-w1MSIZKbF
Панель инструментов Contentful

Тело

  • Фактическое тело комментария
  • Отметьте это как название записи
  • Не стесняйтесь также установить максимальное и/или минимальное значение для его длины

Автор

  • Уникальный идентификатор пользователя, опубликовавший этот комментарий.
  • Для неповторимого комментирования используйте краткий текст и введите имя автора в это поле
  • Для комментирования войдя в систему это поле станет ссылкой на будущую модель CommentAuthor

Тема

  • Уникальный идентификатор публикации в блоге (или эквивалент), которому принадлежат эти комментарии
  • Это также может быть URL-адрес страницы
  • Для максимальной гибкости я решил не считать, что вы сохраняете свои публикации в блоге в Contentful, иначе это будет поле ссылки вместо короткого текста

Родительский комментарий

  • Если этот комментарий является ответом на другой комментарий, мы ссылаемся на этот комментарий здесь
  • Это поле позволяет нам создавать вложенные комментарии.

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

Фронт-энд

Теперь, когда наша модель комментариев готова, пора создать поле для комментариев. Хорошая новость состоит в том, что я уже создал общий компонент React «Поле для комментариев». Он разработан как а низкого порядка компонент, куда вы заворачиваете a высшего порядка компонент вокруг него, чтобы обрабатывать выборку и создание Contentful комментариев, а также другую бизнес-логику приложения.

Вы можете установить его и другие пакеты через npm:

npm install react-commentbox contentful contentful-management --save

В репозитории GitHub есть список всех опор, которые вы можете передать ему, но, как минимум, мы будем внедрять и передаем их:

  • getComments: функция, возвращающая обещание, решаемая к массиву комментариев, упорядоченных от самого старого к самому новому
  • normalizeComment: функция, которая сопоставляет ваш массив комментариев с объектами, которые понимает компонент
  • comment: функция, которая выполняет вызов API для создания комментария и возвращает обещание
  • disabled: установлено значение true, когда комментирование должно быть выключено
  • disabledComponent: компонент, отображаемый во время комментирования, отключен

Давайте создадим наш компонент высшего уровня:

import React from 'react';import CommentBox from 'react-commentbox';
class MyCommentBox extends React.Component {
    state = { authorName: '', authorNameIsSet: false };
    onChangeAuthorName = (e) => this.setState({         authorName: e.currentTarget.value     });
    onSubmitAuthorName = (e) => {
        e.preventDefault();        this.setState({ authorNameIsSet: true });    };}

Обратите внимание, что компонент отвечает за установку имени автора.

Кстати, мы используем плагин Babel transform-class-properties, чтобы избежать изнурительной настройки конструктора и привязки функций. Вам не нужно его использовать, но это очень удобно.

Теперь нам нужно реализовать реквизиты бизнес-логики react-commentbox потребности.

Мы начнем с получения комментариев из Contentful и их нормализации:

// fetch our comments from ContentfulgetComments = () => {
    return this.props.contentfulClient.getEntries({        'order': 'sys.createdAt',        'content_type': 'comment',        'fields.subject': this.props.subjectId,    }).then( response => {
        return response.items;
    }).catch(console.error);};
// turn Contentful entries to objects that react-commentbox expects.normalizeComment = (comment) => {
    const { id, createdAt } = comment.sys;    const { body, author, parentComment } = comment.fields;
    return {        id,        bodyDisplay: body,        userNameDisplay: author,        timestampDisplay: createdAt.split('T')[0],        belongsToAuthor: false,        parentCommentId: parentComment ? parentComment.sys.id : null    };};

Далее нам нужно совершить вызов API для создания комментариев:

// make an API call to post a commentcomment = (body, parentCommentId = null) => {
    return this.props.postData('/create-comment', {        body,        parentCommentId,        authorName: this.state.authorName,        subjectId: this.props.subjectId    });};

Нам также нужно спросить имя пользователя, прежде чем он сможет прокомментировать:

// will be shown when the comment box is initially disableddisabledComponent = (props) => {
    return (        <form             className="author-name"             onSubmit{ this.onSubmitAuthorName }        >            <input                type="text"                placeholder="Enter your name to post a comment"                value={ this.state.authorName }                onChange={ this.onChangeAuthorName }            />            <button type="submit">Submit</button>        </form>    );};

Затем соберите все это вместе renderпередав соответствующие реквизиты в react-commentbox:

render() {
    return (        <div>            <h4>Comments</h4>            <CommentBox                disabled={ !this.state.authorNameIsSet }                getComments={ this.getComments }                normalizeComment={ this.normalizeComment }                comment={ this.comment }                disabledComponent={ this.disabledComponent }            />        </div>    );};

Мы также установили disabled поддержка к true при этом имя автора не установлено. Это выключает textareaи показывает disabledComponent форму, которую мы создали, чтобы получить имя автора.

Вы можете просмотреть полный компонент здесь.

Возможно, вы заметили, что наша новосозданная MyCommentBox также ожидает несколько реквизитов сам: subjectId, postDataи contentfulClient.

The subjectId это просто некий уникальный идентификатор или URL-адрес публикации в блоге (или эквивалентной сущности), для которого предназначены эти комментарии.

postData это функция, осуществляющая POST-вызовы ajax. Использование fetchэто может выглядеть так:

function postData(url, data) {
    return fetch(`.netlify/functions${url}`, {        body: JSON.stringify(data),        headers: {            'content-type': 'application/json'        },        method: 'POST',        mode: 'cors' // if your endpoints are on a different domain    }).then(response => response.json());}

contentfulClient является экземпляром клиента, который вы получаете при использовании содержимого пакета npm (поэтому убедитесь, что вы его установили):

import { createClient } from 'contentful';const contentfulClient = createClient({    space: 'my-space-id',    accessToken: 'my-access-token'});

Вы можете получить идентификатор пространства на информационной панели Contentful в разделе «Настройки пространства» > «Общие настройки».

Маркер доступа можно получить в разделе «Настройки пространства» > «Ключи API» > «Маркеры доставки/предварительного просмотра содержимого» > «Добавить ключ API».

Затем вы можете передать свои реквизиты при создании MyCommentBoxкак показано здесь.

Back-end

Мы воплотим в свою жизнь /create-comment конечная точка как функция AWS Lambda.

Предпосылки

Чтобы создавать, предварительно просматривать и в конце концов развертывать эти функции, мы собираемся использовать удобный пакет netlify-lambda npm. Он позволяет вам писать ваши Lambda-функции как обычные функции ES6 в определенном исходном каталоге, а затем создает их удобным для Lambda способ и помещает их в каталог назначения, готовый к развертыванию. Еще лучше, это позволяет нам предварительно просматривать эти функции, разворачивая их локально.

Итак, вам нужно создать определенный исходный каталог для хранения вашей функции (например src/lambda), затем создайте a netlify.toml файл в вашем корневом каталоге. Как минимум этот файл должен выглядеть так:

[build] Functions = "lambda"

Приведенное выше рассказывает netlify-lambda в какой каталог разместить ваши встроенные функции, то есть он будет встраивать функции src/lambda и хранить их в ./lambda. Кроме того, когда придет время развертывания, Netlify заглянет в ./lambda каталог для развертывания в AWS.

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

netlify-lambda serve <source directory>

Это позволит вам запускать свои функции http://localhost:9000/{function-name}.

Это поведение по умолчанию, но оно не совсем соответствует тому, что произойдет в производстве, поскольку наши функции выполняются в домене, отличном от нашего интерфейса. В производстве наши функции будут доступны в том же домене, что и наш интерфейс, через URL-адрес {domain}/.netlify/functions/{function-name}.

Чтобы повторить это поведение локально, нам нужно прокси-серверировать вызовы интерфейса /.netlify/functions/{function-name} к http://localhost:9000/{function-name}.

Достижение этого зависит от настроек вашего проекта. Я расскажу о двух популярных настройках:

Для проектов create-react-app добавьте следующее package.json:

"proxy": {        "/.netlify/functions": {        "target": "        "pathRewrite": {            "^/\\.netlify/functions": ""        }    }}

Для проектов Gatsby.js добавьте следующее gatsby-config.js:

const proxy = require('http-proxy-middleware');...developMiddleware: app => {    app.use(        '/.netlify/functions/',        proxy({            target: '            pathRewrite: {                '/.netlify/functions/': '',            }        })    );},

Для большинства других проектов можно использовать сервер разработки webpack, который поддерживает прокси.

Написание нашей функции

Прежде чем мы приступим к написанию специфического для Lambda кода, мы сначала создадим общую функцию для обработки большей части нашей логики. Таким образом, наш код остается переносимым за пределы Lambda.

Давайте создадим а createComment функция:

const contentful = require('contentful-management');const client = contentful.createClient({    accessToken: process.env.CONTENTFUL_CONTENT_MANAGEMENT_ACCESS_TOKEN});
module.exports = function createComment(    body,     authorName,     subjectId,     parentCommentId = null) {
    return client.getSpace('my-space-id')        .then(space => space.getEnvironment('master'))        .then(environment => environment.createEntry('comment', {            fields: {                body: {                    'en-US': body                },                author: {                    'en-US': authorName                },                subject: {                    'en-US': subjectId                },                parentComment: {                    'en-US': {                        sys: {                            type: 'Link',                            linkType: 'Entry',                            id: parentCommentId                        }                    }                }            }        }))        .then(entry => entry.publish());};

Вы можете разместить вышеупомянутую функцию где-то, например a utils каталог. Он использует contentful-management npm, чтобы создать и опубликовать новую запись комментария, и возвращает обещание. Обратите внимание, что мы указали наш ключ управления API как переменную среды. Вы точно не хотите жестко кодировать это. При развертывании в Netlify или в любом другом месте обязательно проверьте, установлены ли переменные среды.

Маркер доступа управления можно получить на информационной панели Contentful в разделе «Настройки пространства» > «Ключи API» > «Маркеры управления содержимым» > «Создать личный маркер».

Теперь давайте создадим нашу лямбда-специфическую функцию:

const createComment = require('../utils/createComment');
exports.handler = function (event, context, callback) {
    const { body, authorName, subjectId, parentCommentId } = JSON.parse(event.body);
    createComment(body, authorName, subjectId, parentCommentId)        .then(entry => callback(null, {            headers: {                'Content-Type': 'application/json'            },            statusCode: 200,            body: JSON.stringify({ message: 'OK' })        }))        .catch(callback);};

Поместите эту функцию в свой исходный каталог Lambda и назовите файл с путём, которым вы хотите, чтобы URL-адрес был, например create-comment.js . Это сделает вашу функцию доступной по URL-адресу /.netlify/functions/create-comment.

Большая картина

Чтобы проиллюстрировать нашу полную настройку интерфейса и серверной части, я создал проект create-react-app, функционирующий как легко развернутый, полностью функциональный пример.

Обратите внимание, что в примере проекта netlify.toml файл, есть еще несколько строк, которые вы должны добавить в собственный файл. Command сообщает Netlify, какие команды запустить для создания проекта. Publish сообщает Netlify, где найти статические активы, готовые к развертыванию после завершения сборки. Вы можете прочитать больше об этом файле в документации Netlify.

Пример проекта также легко клонировать и развертывать в вашем аккаунте Netlify с помощью удобной кнопки развертывания в README.

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

Как только он заработает, вы сможете начать комментировать как руководитель.

(Примечание: это только снимок экрана, поэтому не пытайтесь нажимать его ^_^)

iIM89R0mRNjlfbmT1JIbnLTaJ-vnOliNirFf

В следующий раз

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

Спасибо, что прочли! – Шон

Первоначально опубликовано на shaunasaservice.com.

Добавить комментарий

Ваш адрес email не будет опубликован.