Основы TinaCMS: изменение markdown в Gatsby

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

TinaCMS в сочетании с Gatsby дает возможность визуально управлять markdown файлами и мгновенно отображать изменения на страницах приложения.

Примечание: TinaCMS также совместима с Next.js.

В этом мануале вы узнаете, как установить TinaCMS, настроить ее для поддержки Gatsby и работать с файлами markdown.

Установка TinaCMS

Мы будем работать со стартером gatsby-starter-blog, так как в нем уже есть все, что нам нужно для markdown.

Читайте также: Обработка CSS в React с помощью styled-components

Четыре основные вещи, которые нужны нам сейчас: собственно, TinaCMS, библиотека styled-components (от которой зависит TinaCMS) и два плагина Tina –remark для обработки markdown и git, дающий возможность напрямую изменять файлы в файловой системе и делать коммиты при сохранении.

Запустите следующие команды:

$ gatsby new tina-example https://github.com/gatsbyjs/gatsby-starter-blog

$ yarn add gatsby-plugin-tinacms styled-components gatsby-tinacms-remark gatsby-tinacms-git

Настройка Gatsby и TinaCMS

Начальная настройка очень проста: нужно только добавить gatsby-plugin-tinacms с плагинами remark и git в файл gatsby-config.js. Поскольку по умолчанию боковая панель отодвигает сайт в сторону, рекомендуем установить для параметра position значение fixed.

Откройте файл gatsby-config.js и внесите все необходимые данные:

{
  resolve: 'gatsby-plugin-tinacms',
  options: {
    plugins: [
      "gatsby-tinacms-git",
      "gatsby-tinacms-remark",
    ],
    position: 'fixed'
  }
}

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

Боковая панель

Теперь в шаблон заметки нам нужно внести дополнительные сведения: fileRelativePath, rawFrontmatter, rawMarkdownBody. Они будут использоваться компонентом commentForm (это компонент высшего порядка TinaCMS). Все, что нам нужно сделать, это вложить в него наш экспортированный компонент.

Читайте также: Компоненты высшего порядка React: краткое введение

Откройте файл с шаблоном заметки, blog-post.js:

import { remarkForm } from "gatsby-tinacms-remark";

class BlogPostTemplate extends React.Component {
    // ...
};

export default remarkForm(BlogPostTemplate);

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    # ...
    markdownRemark(fields: { slug: { eq: $slug } }) {
      # ...
      fileRelativePath
      rawFrontmatter
      rawMarkdownBody
    }
  }
`;

Теперь у Tina есть доступ ко всем вашим постам markdown. Она сможет обновлять и быстро перезагружать страницу, чтобы сразу отобразить любые изменения. Кроме того, всякий раз, когда вы нажимаете кнопку сохранения, Tina внесет коммит в ваш репозиторий Github, поэтому любая подключенная к нему хостинговая платформа будет обновлена ​​автоматически.

Встроенное редактирование

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

Для этого вам даже не нужно ничего менять. Просто вместо remarkForm мы вложим шаблон страницы в liveRemarkForm, а ту часть, которую мы хотим редактировать, поместим в TinaField (так она станет редактируемой прямо на странице). TinaField нужно назвать rawMarkdownBody и передать сюда библиотеку Wysiwyg в качестве свойства. Wysiwyg – это сокращение от «what you see is what you get». Эта библиотека предоставляет возможности редактирования в реальном времени.

Вы сможете активировать режим редактирования с помощью удобного метода setIsEditing, нажимая на саму статью.

Откройте файл layout.js:

import { liveRemarkForm } from 'gatsby-tinacms-remark';
import { Wysiwyg } from '@tinacms/fields';
import { TinaField } from '@tinacms/form-builder';

const BlogPostTemplate = props => {
  const { previous, next } = props.pageContext;

  return (
    <Layout>
        {*/ ... */}
      <TinaField name="rawMarkdownBody" Component={Wysiwyg}>
        <article onClick={() => props.setIsEditing(true)}>
            {*/ ... */}
        </article>
      </TinaField>
    </Layout>
  )
};

Первое свойство в методе setIsEditing – это текущее состояние редактирования. Если вместо этого вы хотите использовать кнопку-переключатель, вы можете использовать что-то вроде props.setIsEditing(editing => !editing).

Удаление постов

Удалять файлы до смешного просто: нужно только импортировать метод DeleteAction, вставить его в объект с меткой и передать его в liveRemarkForm.

Откройте файл blog-post.js:

import { liveRemarkForm, DeleteAction } from 'gatsby-tinacms-remark';

const deleteButton = {
  label: 'Delete',
  actions: [DeleteAction]
};

export default liveRemarkForm(BlogPostTemplate, deleteButton);

Теперь рядом с кнопкой сохранения есть небольшое меню с опцией Delete.

Добавление публикаций

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

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

frontmatter будет обрабатывать метаданные поста из нашей формы. fields позволяет определить саму форму. С помощью withPlugin мы добавим нашу новую кнопку в макет. Откройте файл макета layout.js:

import { withPlugin } from 'tinacms';
import { createRemarkButton } from 'gatsby-tinacms-remark';
import slugify from 'react-slugify';

const CreatePostButton = createRemarkButton({
  label: "New Post",
  filename(form) {
    let slug = slugify(form.title.toLowerCase())
    return `content/blog/${slug}/${slug}.md`
  },
  frontmatter(form) {
    let slug = slugify(form.title.toLowerCase())
    return new Promise(resolve => {
      resolve({
        title: form.title,
        description: form.description,
        data: new Date(),
        path: `content/blog/${slug}/${slug}`,
      })
    })
  },
  fields: [
    { name: "title", label: "Title", component: "text", required: true },
    { name: "description", label: "Description", component: "text", required: true },
  ],
});

export default withPlugin(Layout, CreatePostButton);

Заключение

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

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

Tags: ,

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