Управление контентом для сайта GatsbyJS с помощью NetlifyCMS
В этой статье речь пойдет об очень удобном инструменте для управления контентом для вашего веб-сайта. Netlify CMS содержит в себе редактирование текста, предварительный просмотр в реальном времени и загрузку медиафайлов с помощью перетаскивания файла мышью.
В конце этой статьи мы получим простой сайт-блог который будет сделан вместе с генератором статических страниц GatsbyJS и непосредственно с NetlifyCMS, с помощью которого мы будем добавлять или изменять содержимое сайта (конкретно статьи). Так же мы разместим этот сайт на бесплатном хостинге Netlify проделав всего пару простых действий.
🌐 Посмотреть результат можно здесь.
Содержание
- Основные преимущества использования Netlify CMS
- Установка и настройка Netlify CMS на веб-сайт
- Деплой сайта на хостинг Netlify
- Настройка OAuth на Github
- Вывод статей на главную страницу
- Создание динамической страницы
- Аутентефикация через Nelify Identity
- Заключение и полезные ссылки
Основные преимущества использования Netlify CMS
NetlifyCMS является полностью бесплатным и находится в открытом доступе на GitHub. Вы можете использовать данную CMS вместе с любым генератором статиеских сайтов для создания быстрых сайтов. Стоит отметить, что контент хранится в репозитории Git вместе с исходным кодом вашего сайта для упрощения управления версиями и возможностью обновлять контент непосредственно в Git.
Отмечу еще несколько преимуществ, которые содержит в себе CMS:
- Удобный веб-интерфейс - как говорилось ранее вы с легкостью сможете изменять контент вашего сайта, добавлять или удалять медиафайлы и т.д. Познакомиться с UI интерфейсом можно на демо-сайте. Вход в систему не требуется, достаточно нажать на кнопку Login.
- Простая установка - достаточно добавить несколько файлов index.html и config.yml в папке /admin, и установить npm пакет, но об этом позже.
- Аутентефикация - аутентефикация в систему происходит с помощью веб-токенов GitHub, GitLab, или Bitbucket и JSON. Также можно использовать Netlify Identity что даст возможность производить вход например через Google.
- Настраиваемые типы контента - вы сможете указать неограниченное количество типов контента с помощью настраиваемых полей.
- Полностью расширяемый - есть возможность расширить CMS под свои нужды, написать собственный плагин для редактора или создать виджет.
Создание сайт-блога на основе GatsbyJS
GatsbyJS - это генератор статических сайтов, который представляет из себя React фрэймворк для создания быстрых веб-сайтов и приложений. Мы создадим небольшой веб-сайт который будет предствлять из себя сайт-блог. На нем будет всего 3 страницы:
- Главная - здесь будем показывать список статей
- О блоге - небольшая страница, где будет отображаться какой то текст
- Динамическая старница статьи, которая будет показывать содержание статьи
Отмечу, что можно использовать шаблон сайта с нужным вам генератором, где уже становлена CMS и достаточно сделать пару кликов и сайт будет уже готов (нужно только переделать под себя), но мы не будем использовать это, так как мы хотим разобраться как связать конкретно GatsbyJS и NetlifyCMS.
Заготовка проекта
На этом этапе мы сделаем небольшую заготовку проекта. То есть добавим верстку для наших страниц и компонентов, подключим шрифты и стили. Также коснемся немного graphql запросов.
Итак, клонируем hello-world-starter репозиторий в созданную вами папку с любым названием. Он представляет из себя GatsbyJS сайт которое содержит в себе одну страницу, где выведено сообщение Hello world!.
mkdir gatsby-blog
git clone https://github.com/gatsbyjs/gatsby-starter-hello-world .
Сразу же удаляем папку .git чтобы убрать все коммиты.
Описание каждого файла вы сможете посмотреть на странице этого репозитория в README.md файле. Отдельные файлы такие как gatsby-node.js или gatsby-browser.js будут объяснены по ходу создания этого сайта. Перейдем в package.json файл и рассмотрим скрипты запуска.
- build - сборка приложения
- develop - запуск сервера для разработки
- format - форматирование всех файлов через prettier
- start - запускает npm run develop
- serve - запуск скомпилированного сайта
- clean - очищает папку .cache
Более подробно о gatsby cli можно узнать здесь.
После клонирования репозитория, устанавливаем необходимые npm пакеты и запускаем сайт в dev режиме
npm install
npm run develop
После переходим по адресу http://localhost:8000/ где мы должны увидеть надпись Hello world!.
Добавление страниц
Теперь добавим нужные нам страницы. Для начала создадим специальный компонет-шаблон где будут показываться наши основные страницы. Переходим в ./src и создаем папки с файлом таким образом: ./src/components/Layout/Layout.jsx
Создадим этот компонент:
// ./src/components/Layout/Layout.jsx
import React from 'react';
const Layout = ({ children }) => {
return (
<>
<main>
<div className="container">
{children}
</div>
</main>
</>
)
}
export default Layout
Теперь создадим страницы Index и About:
// ./src/pages/index.jsx
import React from 'react';
import { Link } from 'gatsby'
import Layout from '../components/Layout/Layout'
const IndexPage = () => {
return (
<Layout>
<h1>Articles (6):</h1>
<div className="main-posts">
<div className='post'>
<h2>
<Link to={'/'}>{'Article 1'}</Link>
</h2>
<small>{'2021-01-01'}</small>
</div>
</div>
</Layout>
)
}
export default IndexPage
// ./src/pages/about.jsx
import React from 'react'
import { Link } from 'gatsby'
import Layout from '../components/Layout/Layout'
const AboutPage = () => {
return (
<Layout>
<h1>About</h1>
<div className="about-content">
<p>About content...</p>
<Link to='/'>Return to index page.</Link>
</div>
</Layout>
)
}
export default AboutPage
Как видим, получилась довольно простая разметка. Для перехода между страницами мы используем компонент Link от gatsby. Перейдите по адресу http://localhost:8000 и вы увидите эту разметку. Пока что это выглядит не совсем хорошо, поэтому дальше мы добавим несколько стилей и еще один компонент Header.
О файле gatsby-config.js
Файл gatsby-config.js который находится в корне проекта, является очень важным и полезным файлом. Он определяет метаданные сайта, плагины и другую общую конфигурацию. При редактировании этого файла всегда необходимо перезапускать dev сервер для того чтобы применились новые настройки.
Например мы можем определить поле siteMetadata в объекте конфигурации. Это позволит использовать вам повторяющиеся данные. Наример название сайта, список навигации по сайту, url сайта. Добавим поле title и description в siteMetadata:
// ./gatsby-config.js
module.exports = {
siteMetadata: {
title: 'myblog.com',
description: 'GatsbyJS blog site.'
}
}
Для доставки данных Gatsby использует graphql, вы можете перейти по адресу http://localhost:8000/___graphql и выполнить к примеру запрос:
{
site {
siteMetadata {
title
description
}
}
}
Тогда вы получите объект, где увидите поля title и description со значениями. Как использовать graphql запросы в компонентах я покажу позже.
Добавление поддержки sass для стилей.
Sass - это довольно удобный инструмент, который позволяет писать css код быстрее за счет нового синтаксиса. В данном сайте Sass будет даже излишним, и можно было бы обойтись обычным css, но мы все равно для примера добавим его, так как это очень просто сделать с Gatsby.
Установим несколько пакетов: gatsby-plugin-sass и sass. gatsby-plugin-sass позволит использовать нам sass/scss файлы на нашем сайте, а пакет sass - это сама реализация Sass.
npm install sass gatsby-plugin-sass
Это еще не всё, необходимо добавить этот плагин добавить в конфигурационный файл gatsby-config.js в массив с plugins:
// ./gatsby-config.js
module.exports = {
plugins: ['gatsby-plugin-sass'],
}
Теперь попробуем добавить несколько стилей на страницу. Создаем папку styles в папке src и файл global.scss где будут лежать наши глобальные стили:
// ./src/styles/global.scss
* {
box-sizing: border-box;
outline: none;
}
body {
margin: 0;
font-family: 'Arial', sans-serif;
}
h1,h2,h3,h4,h5,h6,p {
padding: 0;
margin: 15px 0;
}
ul {
margin: 0;
}
main {
margin-top: 40px;
h1 {
margin-bottom: 40px;
}
}
.container {
max-width: 800px;
margin-left: auto;
margin-right: auto;
padding: 0 15px;
}
.blog-post {
&__title {
& h1 {
margin-bottom: 0;
}
}
&__description p {
margin-bottom: 2rem;
}
&__img img {
width: 100%;
border-radius: 3px;
}
&__content {
margin-top: 25px;
font-size: 17px;
line-height: 26px;
& img {
width: 100%;
border-radius: 3px;
}
& p {
margin: 0 0 15px;
}
}
}
.main-posts {
& .post {
margin-bottom: 20px;
& h2 {
margin-bottom: 5px;
& a {
color: #000;
text-decoration: none;
}
}
& p {
text-align: justify;
}
border-bottom: 1px solid #e9e9e9;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
}
}
Теперь нужно подключить этот файл к сайту. Сделать это можно изменив файл gatsby-browser.js. Создаем его в корне проекта и просто импортируем туда эти стили. После этого стили должны примениться к сайту.
import './src/styles/global.scss'
Файл gatsby-browser.js позволяет реагировать на действия в браузере и если нужно, оборачивать страницы другими компонентами. Как раз этот файл и может быть использован для определения глобальных стилей. Более подробно о том как использовать этот файл можно узнать в документации.
Подключение шрифтов
Для того чтобы подключить шрифты к сайту, их необходимо для начала скачать. Возьмем бесплатный шрифт Inter. Прейдем на этот сайт и отметим галочкой шрифт 500, 600 и 700. Снизу добавим префикс к папке со значением ../../static/fonts/. Копируем сгенерированный код для подключения, скачиваем шрифты по кнопке снизу и перекидываем шрифты в папку ./static/fonts. Папку fonts нужно создать соответственно.
Далее создадим файл fonts.scss в папке styles и кинем туда наш сгенерированный код для подключения шрифтов.
/* ./src/styles/fonts.scss */
/* inter-500 - latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
src: url('../../static/fonts/inter-v2-latin-500.eot'); /* IE9 Compat Modes */
src: local(''),
url('../../static/fonts/inter-v2-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../../static/fonts/inter-v2-latin-500.woff2') format('woff2'), /* Super Modern Browsers */
url('../../static/fonts/inter-v2-latin-500.woff') format('woff'), /* Modern Browsers */
url('../../static/fonts/inter-v2-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */
url('../../static/fonts/inter-v2-latin-500.svg#Inter') format('svg'); /* Legacy iOS */
}
/* inter-600 - latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
src: url('../../static/fonts/inter-v2-latin-600.eot'); /* IE9 Compat Modes */
src: local(''),
url('../../static/fonts/inter-v2-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../../static/fonts/inter-v2-latin-600.woff2') format('woff2'), /* Super Modern Browsers */
url('../../static/fonts/inter-v2-latin-600.woff') format('woff'), /* Modern Browsers */
url('../../static/fonts/inter-v2-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */
url('../../static/fonts/inter-v2-latin-600.svg#Inter') format('svg'); /* Legacy iOS */
}
/* inter-700 - latin */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
src: url('../../static/fonts/inter-v2-latin-700.eot'); /* IE9 Compat Modes */
src: local(''),
url('../../static/fonts/inter-v2-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../../static/fonts/inter-v2-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('../../static/fonts/inter-v2-latin-700.woff') format('woff'), /* Modern Browsers */
url('../../static/fonts/inter-v2-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('../../static/fonts/inter-v2-latin-700.svg#Inter') format('svg'); /* Legacy iOS */
}
Теперь переходим в файл global.scss, подключаем файл fonts.scss и меняем font-family в body на Inter.
Чтобы подключить файл fonts.scss в global.scss нужно использовать @import в самом начале файла:
@import './fonts.scss';
Теперь шрифт Inter подключен и должен быть виден на сайте.
Компонент Header для навигации
Далее для разнообразия добавим компонент Header для навигации. Создаем путь ./src/components/Header/Header.jsx и напишем сам компонент:
// ./src/components/Header/Header.jsx
import React from 'react';
import { Link } from 'gatsby'
const Header = () => {
return (
<header className='header'>
<div className='header-container'>
<div>
<Link to='/'>
<p>test</p>
</Link>
</div>
<div className='header-container__nav'>
<nav>
<ul>
<li>
<Link to='/about'>About</Link>
</li>
</ul>
</nav>
</div>
</div>
</header>
)
}
export default Header
Создадим стили этого компонента в файле Header.scss
// ./src/components/Header/Header.scss
.header {
height: 65px;
display: flex;
align-items: center;
box-shadow: 1px 2px 18px rgba(0,0,0,.1);
padding: 0 15px;
& a {
text-decoration: none;
color: #000;
& p {
font-weight: bold;
margin: 0;
}
}
&-container {
max-width: 800px;
width: 100%;
margin-right: auto;
margin-left: auto;
display: flex;
justify-content: space-between;
&__nav {
& ul li {
list-style: none;
}
}
}
}
Подключаем стили в глобальный файл global.scss через импорт:
@import '../components/Header/Header.scss';
Не забываем еще включить этот компонент в файл Layout.jsx:
// ./src/components/Layout/Layout.jsx
import React from 'react';
import Header from '../Header/Header'
const Layout = ({ children }) => {
return (
<>
<Header />
<main>
<div className="container">
{children}
</div>
</main>
</>
)
}
export default Layout
Использование React Hooks для выполнения запроса GraphQL
Попробуем в комоненте Header в тэге параграфа вывести название нашего сайта, которое было написано в конфигурационном файле. Для этого создадим папку hooks в папке src и файл useSiteMetadataQuery.js. Мы будем использовать функцию useStaticQuery от Gatsby которая позволяет использовать React Hook для выполнения запросов graphql во время сборки сайта.
// ./src/hooks/useSiteMetadataQuery.js
import { useStaticQuery, graphql } from 'gatsby'
const useSiteMetadataQuery = () => {
const { site: { siteMetadata } } = useStaticQuery(graphql`
query SiteMetaData {
site {
siteMetadata {
title
description
}
}
}
`)
return { siteMetadata }
}
export { useSiteMetadataQuery }
Как видно, для того чтобы выполнить запрос и вытащить данные из graphql, то должны импользовать тэг-функцию graphql. Gatsby обрабатывает этот тэг своим способом. Подробнее можно узнать в документации.
Теперь мы можем легко использовать этот hook. Перейдем в Header компонент и изменим его вот так:
// ./src/components/Header/Header.jsx
import React from 'react';
import { Link } from 'gatsby'
import { useSiteMetadataQuery } from '../../hooks/useSiteMetadataQuery'
const Header = () => {
const { siteMetadata: { title } } = useSiteMetadataQuery()
return (
<header className='header'>
<div className='header-container'>
<div>
<Link to='/'>
<p>{title}</p>
</Link>
</div>
<div className='header-container__nav'>
<nav>
<ul>
<li>
<Link to='/about'>About</Link>
</li>
</ul>
</nav>
</div>
</div>
</header>
)
}
export default Header
Используя ES6 деструктуризацию объекта мы вытаскиваем данные и подставляем их куда хотим. В нашем случае мы вытащили поле title и подставили значение между тэгами параграфа.
Добавление SEO компонента
Рассмотрим как добавлять различные seo мета-тэги в заголовок html документа. Для этого установим пакет react-helmet который позволит управлять нам этим.
npm install react-helmet
Теперь создадим компонент с названием SEO где будет хранится наш шаблон для станиц:
// ./src/components/SEO/SEO.jsx
import React from 'react';
import PropTypes from "prop-types"
import { Helmet } from "react-helmet"
import { useSiteMetadataQuery } from '../../hooks/useSiteMetadataQuery'
const SEO = ({ title, description }) => {
const { siteMetadata } = useSiteMetadataQuery()
const seo = {
title: title || siteMetadata.title,
description: description || siteMetadata.description
}
return (
<Helmet title={seo.title} titleTemplate={`${seo.title} - ${siteMetadata.title}`} >
<html lang="ru" />
<meta name="description" content={seo.description} />
<meta name="theme-color" content="#ffffff" />
</Helmet>
)
}
export default SEO
SEO.propTypes = {
title: PropTypes.string,
description: PropTypes.string
}
Теперь компонент SEO содержит несколько мета-тэгов, по необходимости вы можете добавить и свои в будущем. Пакет prop-types используется для получения нужных типов когда мы передаем значение в props. Его тоже нужно установить: npm install prop-types
Далее осталось вставить этот компонент на все страницы вот таким образом:
// ./src/pages/index.jsx
import React from 'react';
import { Link } from 'gatsby'
import Layout from '../components/Layout/Layout'
import SEO from '../components/SEO/SEO'
const IndexPage = () => {
return (
<>
<SEO title='Index page' />
<Layout>
<h1>Articles (6):</h1>
<div className="main-posts">
<div className='post'>
<h2>
<Link to={'/'}>{'Article 1'}</Link>
</h2>
<small>{'2021-01-01'}</small>
</div>
</div>
</Layout>
</>
)
}
export default IndexPage
Аналогично со страницей About.
На этом заготовка проекта завершена. Теперь нам осталось подключить NetlifyCMS и настроить его, создать шаблон для динамической страницы статьи и вывести нужные данные
Установка и настройка Netlify CMS на веб-сайт
Для того чтобы связать GatsbyJS и NetlifyCMS для начала установим необходимые npm пакеты:
npm install gatsby-plugin-netlify-cms netlify-cms-app
После добавляем плагин gatsby-plugin-netlify-cms в конфигурационный файл gatsby-config.js в массив plugins. Этот плагин автоматически гененирует файл admin/index.html для NetlifyCMS.
Также еще создаем файл с папкой ./static/admin/config.yml и прописываем конфигурацию для CMS. Конфигурация создается в YML синтаксисе.
backend:
name: github
repo: username/repo-name
branch: main
locale: 'ru'
media_folder: static/assets
public_folder: /assets
collections:
- name: articles
label: Article
folder: content/articles
slug: "{{year}}-{{month}}-{{day}}_{{slug}}"
create: true
fields:
- { label: "Template Key", name: "templateKey", widget: "hidden", default: "article" }
- { label: "Имя URL", name: "slug", widget: "string" }
- { label: "Заголовок", name: "title", widget: "string" }
- { label: "Дата публикации", name: "date", widget: "datetime" }
- { label: "Обложка", name: "image", widget: "image" }
- { label: "Описание", name: "description", widget: "text"}
- { label: "Содержание", name: "body", widget: "markdown" }
Рассмотрим важные опции для конфигурации:
- backend - эта опция определяет, где будет храниться ваш контент. В нашем случае сайт с контентом хранить будем на GitHub указав name, repo и branch предварительно создав репозиторий. Подробнее
- media_folder - этот параметр указывает путь к папке, в которой должны быть сохранены загруженные файлы, относительно репозитория.
- public_folder - параметр указывает путь к папке, в которой будут доступны файлы, загруженные медиатекой, относительно созданного сайта. Для полей с виджетами файл или изображение, значение поля создается путем добавления этого пути к выбранному файлу.
- collections - данный параметр определяет какие типы контента и поля редактора в UI генерируют файлы и контент в вашем репозитории. Подробнее об этом параметре
Как видим, в нашей конфигурации ничего сложного нет, мы создали только одну коллекцию articles и определили несколько полей со встроенными виджетами. Виджеты widget определяют тип данных и интерфейс для полей ввода.
Так же мы указали опцию folder, где будут хранится наши статьи в формате .md. Поле Template key понадобится нам для того, чтобы в будущем получить эти статьи через GraphQL запрос.
Деплой сайта на хостинг Netlify
Netlify - это платформа, которая предлагает облачный хостинг. Вы можете публиковать свои сайты прямо из репозиториев git. Многие функции полностью бесплатны на этой платформы, вы можете не беспокоится и цене.
Для того чтобы развернуть сайт на Netlify, для начала необходимо загрузить в этот репозиторий наш сайт с CMS:
git init
git add .
git commit -m "site"
git branch -M main
git remote add origin https://github.com/username/repo-name.git
git push -u origin main
Далее переходим на сам сайт Netlify и регистрируемся. После нажимаем на кнопку New site from Git, выбираем Git провайдера (GitHub) и далее выбираем наш репозиторий с сайтом. Вконце нажимем Deploy site. Далее ждем когда Netlify установит все необходимые пакеты и соберет сайт. После сборки вы должны увидеть свой сайт.
Настройка OAuth на Github
Чтобы убедиться, что Netlify CMS имеет доступ к вашему репозиторию GitHub, вам необходимо настроить приложение OAuth на GitHub.
- Переходим сюда и создаем новое приложение нажав на кнопку New OAuth App
-
Далее заполняем поля:
- Application name - вводим имя приложения.
- Homepage URL - вводим ссылку на наш сайт .netlify.app
- Authorization callback URL - вводим ссылку: https://api.netlify.com/auth/done
После создания приложения у вас должны появится два ключа: Client ID и Client Secre. Client secret вы должны сгенерировать нажав на кнопку Generate new client secret. Эти ключи нужно добавить на ваш сайт Netlify.
- На сайте Netlify переходим по пути Site settings > Access control > OAuth
- В разделе Authentication Providers выбираем Install Provider.
- Выбираем GitHub в качестве провайдера и вставляем наши ключи.
Теперь когда всё это сделано, у вас есть возможность перейти в CMS. Достаточно в конце URL дописать /admin/. После перехода в CMS создадим три статьи. В качестве описания и содержания вставим любой текст, для обложки найдем любую картинку.
Вывод статей на главную страницу
Выведем список стайтей на нашу главную страницу. Переходим в редактор кода и в териминал прописываем git pull origin main. После этого вы должны были получить созданные нами ранее статьи, конкретно .md файлы в папке content и картинки в папке static/assets.
Устанавливаем следующие пакеты:
npm install gatsby-transformer-remark gatsby-source-filesystem
- gatsby-source-filesystem - данный пакет нужен, для того чтобы получить данные из локальной файловой системы.
- gatsby-transformer-remark - этот пакет парсит файлы markdown.
Изменим конфигурационный файл добавив туда эти плагины:
// gatsby-config.js
module.exports = {
/* Your site config here */
plugins: [
'gatsby-plugin-sass',
'gatsby-plugin-netlify-cms',
{
resolve: "gatsby-source-filesystem",
options: {
name: "content",
path: `${__dirname}/content`,
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
// CommonMark mode (default: true)
commonmark: true,
// Footnotes mode (default: true)
footnotes: true,
// Pedantic mode (default: true)
pedantic: true,
// GitHub Flavored Markdown mode (default: true)
gfm: true,
// Plugins configs
plugins: [],
},
},
],
siteMetadata: {
title: 'myblog.com',
description: 'GatsbyJS blog site.'
}
}
И если мы перезапустим dev севрер и выполним вот такой запрос:
{
allMarkdownRemark {
edges {
node {
frontmatter {
title
date
description
slug
image
templateKey
}
rawMarkdownBody
}
}
}
}
То мы получим всё, что находится в папке content.
Изменим index.jsx таким образом:
// ./src/pages/index.jsx
import React from 'react';
import { Link, graphql } from 'gatsby'
import Layout from '../components/Layout/Layout'
import SEO from '../components/SEO/SEO'
const IndexPage = ({ data: { articles: { edges } } }) => {
return (
<>
<SEO title='Index page' />
<Layout>
<h1>Articles ({ edges.length }):</h1>
<div className="main-posts">
{edges.map(({ node }, i) => (
<div className='post' key={i}>
<h2>
<Link to={`/article/${node.frontmatter.slug}`}>{node.frontmatter.title}</Link>
</h2>
<small>{node.frontmatter.date}</small>
<p>{node.frontmatter.description}</p>
</div>
))}
</div>
</Layout>
</>
)
}
export const query = graphql`
{
articles: allMarkdownRemark(
filter: { frontmatter: { templateKey: { eq: "article" } } }
sort: { order: DESC, fields: frontmatter___date }
) {
edges {
node {
frontmatter {
slug
title
date(formatString: "D MMMM YYYY", locale: "ru-RU")
description
}
}
}
}
}
`
export default IndexPage
С помощью тэга graphql мы делаем запрос для получения статей. Также указываем еще и templateKey в качестве параметра чтобы получить именно статьи. Далее мы просто получаем эти статьи в аргументе страницы IndexPage и поставляем нужные значения.
Создание динамической страницы
Теперь наша задача заключается в том, чтобы взять md файлы из папки content и на каждый файл создать отдельную страницу, разумеется в этом нам поможет Gatsby. Создадим шаблон для динамической страницы создав файл ./src/templates/article.jsx:
// ./src/templates/article.jsx
import React from 'react';
import { graphql } from 'gatsby'
import Layout from '../components/Layout/Layout'
import SEO from '../components/SEO/SEO'
const articleTemplate = ({ data: { article: { frontmatter, html } } }) => {
return (
<>
<SEO title={frontmatter.title} />
<Layout>
<div className="blog-post">
<div className="blog-post__title">
<h1>{frontmatter.title}</h1>
</div>
<div className="blog-post__date">
<small>{frontmatter.date}</small>
</div>
<div className="blog-post__description">
<p>{frontmatter.description}</p>
</div>
<div className="blog-post__img">
<img src={frontmatter.image} alt={frontmatter.title}/>
</div>
<div className="blog-post__content">
<div dangerouslySetInnerHTML={{ __html: html }}></div>
</div>
</div>
</Layout>
</>
)
}
export const query = graphql`
query Article($slug: String!) {
article: markdownRemark(frontmatter: {slug: {eq: $slug}}) {
html
frontmatter {
slug
title
description
date(formatString: "D MMMM YYYY", locale: "ru-RU")
image
}
}
}
`
export default articleTemplate
Здесь мы делаем похожий принцип. Но чтобы получить нужную статью по которой мы кликнули, мы должны в качестве переменной в graphql запрос передать значение $slug. Далее просто подставляем значения.
Далее создаем файл в корне проекта с названием gatsby-node.js. Код в этом файле будет запускаться только один раз в процессе создания сайта. Как раз он нам и пригодится чтобы создать страницы. Подробнее о Gatsby Node APIs.
// ./gatsby-node.js
const path = require('path')
exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions
const articleTemplate = path.resolve('src/templates/article.jsx')
const result = await graphql(
`
{
allMarkdownRemark {
edges {
node {
frontmatter {
templateKey
slug
title
}
}
}
}
}
`
)
if (result.errors) {
throw result.errors
}
const all = result.data.allMarkdownRemark.edges
const articles = all.filter(article => article.node.frontmatter.templateKey === "article")
articles.forEach(({ node }) => {
createPage({
path: `article/${node.frontmatter.slug}/`,
component: articleTemplate,
context: {
slug: node.frontmatter.slug,
},
})
})
}
Здесь тоже всё просто. Сначала получаем абсолютный путь до нашего шаблона src/templates/article.jsx. Далее выполняем запрос на получение всех существующих "узлов". Отфильтровываем массив для получения только статей и далее через функцию forEach создаем страницу с помощью createPage где:
- path - валидный URL.
- component - абсолютный путь к компоненту для этой страницы
- context - данные контекста для этой страницы. Передается как реквизит в компонент this.props.pageContext, а также в запрос graphql как аргументы graphql.
Теперь осталось перезапустить сервер и протестировать сайт. Если по какой то причине контент не обновляется или возникают другие проблемы, попробуйте прописать команду gatsby clean в терминал.
Для того чтобы запустить сайт в финальной сборке, достаточно написать:
gatsby build
gatsby serve
После проверки осталось только сделать push на github. Netlify сам поймет изменения и заново соберет сайт.
git add .
git commit -m "article template"
git push origin main
Аутентефикация через Nelify Identity
Сервис Netlify Identity позволяет вам управлять и аутентифицировать пользователей на вашем сайте или в приложении, не требуя, чтобы они были пользователями Netlify или любой другой службы. Вы можете использовать это для закрытого контента, администрирования сайта и многого другого. Чтобы включить службу Netlify Identity на сайте достаточно выбрать вкладку Identity и нажать на кнопку Enable Identity.
Затем перейти по пути Site settings > Identity > Services > Git Gateway и выбрать Enable Git Gateway. Далее в файле config.yml меняем поле backend с github на git-gateway. И делаем push в репозиторий. После очередной сборки сайта, вы можете перейди в админ-панель и нажать на кнопку Login with Netlify Identity. Далее вы сможете создать нового пользователя и войти в админ-панель.
В данный момент каждый сможет создать нового пользователя, поэтому нам нужно отключить эту функцию. Переходим в Site Settings > Identity > Registration preferences и нажимаем на Edit settings и ставим галочку Invite only.
Чтобы сделать вход через Google или Github, просто добавьте провайдера в разделе External providers
На этом установка и настройка NetlifyCMS завершена.
Заключение и полезные ссылки
Создание GatsbyJS сайта вместе с NetlifyCMS оказалась не очень сложной задачей. NetlifyCMS отлично подойдет в роли не сложной админки для управления контентом на сайте. В статье не затронута такая вещь как Publish mode, которая позволяет контролировать этапы публикации контента. Вы можете прочитать о ней самостоятельно.
🔗 Ниже распологаются полезные ссылки: