От автора: сегодня мы поговорим о том, как можно быстро создать сайт на Gatsby React. Gatsby — это быстрый статический генератор сайтов, основанный на ReactJS. Статический генератор сайта (SSG) представляет собой компромисс между жестко закодированным HTML статического сайта и полномасштабной CMS (Content Management System), как WordPress. SSG можно использовать для создания HTML-страниц для веб-сайтов, ориентированных на контент (таких как блоги). Все это требует заполнения страницы контентом.
Этот пост будет разделен на пять разделов:
Начало работы.
Создание компонентов макета.
Создание записей в блогах.
Создание новых страниц из данных блога.
Создание список файлов разметки сайта на основной странице.
Мы тщательно изучим Gatsby и некоторые его особенности, создав воображаемый статический блог под названием CodeStack. Макет показан ниже. Поехали!
1. Начало работы
Предпосылки
Во-первых, убедитесь, что в вашей системе установлен Node.js. Если нет, перейдите на nodejs.org и установите последнюю версию для вашей операционной системы. Кроме того, в этой статье предполагается, что вы знаете, что такое ReactJS.
Установка CLI
У Gatsby есть инструмент командной строки, который предоставляет такие полезные команды, как:
gatsby new: строительные леса для нового проекта Gatsby.
gatsby develop: для запуска сервера веб-разработки с поддержкой горячей перезагрузки.
gatsby build: для создания готовой версии проекта.
Для установки введите следующее на своем терминале и нажмите enter:
npm install --global gatsby-cli
Создадим папку проекта codestack-blog и перейдем к ней.
gatsby new codestack-blog&& cd $ _
Если вы выполняете gatsby developв папке проекта, строительный участок должен выглядеть следующим образом:
Добавление плагинов
У Gatsby есть большой и растущий набор плагинов. Это, по сути, пакеты Node.js, которые взаимодействуют с API Gatsby.
Они могут быть установлены через NPM (диспетчер пакетов узлов) на терминале и, как правило, имеют три категории: функциональные, исходные и трансформаторные плагины.
Функциональные плагины
Эти плагины обеспечивают дополнительную функциональность на сайте Gatsby или в его среде разработки. Для нашего приложения нам понадобятся:
gatsby-plugin-react-helmet: позволяет изменять head теги. Обратите внимание, что он уже установлен в нашем проекте.
gatsby-plugin-catch-links: перехватывает локальные ссылки из уценки и других нереактивных страниц и делает pushState на стороне клиента, чтобы браузер не обновлял страницу.
Установите плагины или только второй плагин.
npm install gatsby-plugin-response-helmet gatsby-plugin-catch-links
Каждый раз, когда мы добавляем новый плагин, нужно обновлять файл gatsby-config.js с новым плагином, чтобы Gatsby узнавал и использовал его. Мы используем back-ticks.
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, ], }
Исходные плагины
Эти плагины «исходных» данных из удаленных или локальных мест — то, что Гэтсби называет nodes. Чтобы написать посты в Markdown на локальном диске, необходимо:
gatsby-source-filesystem: источники данных о файлах из файловой системы компьютера.
npm install gatsby-source-filesystem
Обновите gatsby-config.js файл:
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/pages`, name: 'pages', }, } ], }
Что тут происходит? Объект Options может быть передан плагину для получения дополнительной конфигурации. Мы передаем файловую систему path (то есть, место, где находятся наши файлы разметки), а затем name для исходных файлов, чтобы Gatsby знал о наших исходных файлах и, где применять трансформаторные плагины.
Трансформаторные плагины
Эти плагины преобразуют необработанные данные из nodes в используемые форматы данных. Например, нам понадобится:
gatsby-transformer-remark: он преобразовывает записи блога, написанные в .md файлах, размещённых на локальном диске, в HTML для рендеринга.
npm install gatsby-transformer-remark
Обновите gatsby-config.jsфайл еще раз.
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/pages`, name: 'pages', }, }, `gatsby-transformer-remark`, ], }
2. Создание компонентов компоновки
Gatsby позволяет легко создавать «компоненты макета». Компоненты макета — это разделы сайта, которые вы хотите разделить на несколько страниц. Для блога, который мы создаем, это заголовок и боковые панели.
Посмотрите в корневой папке src/layouts. Вы найдете index.js файл, в котором мы определяем компоненты макета. Index.css уже пришел со стилями.
После изучения index.js файла вы увидите, что уже созданы два компонента: Header и TemplateWrapper. В TemplateWrapper мы заворачиваем содержимое нашего сайта и компонентами макета, которые хотим, чтобы присутствовали на нескольких страницах.
Это стало возможным благодаря реквизитам children(). Они будут отображать все компоненты без макета сайта, на котором они размещены. Обратите внимание, что в отличие от дочерних реквизитов React, эти дочерние реквизиты, переданные компонентам макета, являются функцией и должны выполняться.
Прежде всего, создайте новую папку и файл CSS src/styles/layout-overide.css. Добавьте к списку импорта в index.js файле. Нам нужно импортировать его после index.css переопределения некоторых существующих правил стиля.
import React from 'react' import PropTypes from 'prop-types' import Link from 'gatsby-link' import Helmet from 'react-helmet' import './index.css' import "../styles/layout-overide.css";
Откройте layout-overide.cssи вставьте следующие правила стилей. Не нужно это понимать.
* { background: #f5f5f5; color: black; } html { height: 100%; } body { height: 100%; border: 5px solid #ffdb3a; } h1 { font-size: 1.5rem; line-height: 0.5rem; } p, div { font-size: 16px; }
Обновите макет заголовка.
const Header = () => ( <div style={{ background: '#f5f5f5', marginBottom: '3rem', borderBottom: '2px solid #e6e6e6', }} > <div style={{ margin: '0 auto', maxWidth: 980, padding: '1.45rem 1.0875rem', }} > <h1 style={{margin: 0, textAlign: 'center',fontSize: '18px'}}> <Link to="/" style={{ color: 'black', textDecoration: 'none', }} > CodeStack </Link> </h1> </div> </div> );
Также создайте Sidebar макет.
const Sidebar = (props) => ( <div style={{ border: '2px solid #e6e6e6', maxWidth: 960, padding: '0.5rem', marginBottom: '25px' }} > <strong>{props.title}.</strong> {props.description} </div> );
Нам нужно, чтобы компоненты Sidebar и обработанные {children()}элементы реагировали следующим образом:
Поскольку не существует простого способа определить медиазапросы в React, я нашел библиотеку под названием react-media, макет запроса CSS медиа для React. Установите его.
npm install --save react-media
Он предоставляет Media компонент, который ищет совпадения с запросом на мультимедиа CSS и отображает материал в зависимости от того, совпадает ли запрос или нет.
Добавьте его в список импорта в нашем файле.
import Media from 'react-media'
Давайте расставим все компоненты ( Header, Sidebarи children()), как мы хотим в TemplateWrapper . Внесите следующие изменения (простите за бесстыдную вставку моего имени):
const TemplateWrapper = ({ children }) => ( <div> <Helmet title="Gatsby Default Starter" meta={[ { name: "description", content: "Sample" }, { name: "keywords", content: "sample, something" } ]} /> <Header /> <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%" }} > <Media query={{ maxWidth: 848 }}> {matches => matches ? ( <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%", padding: "25px" }} > <div style={{ flex: 1 }}>{children()}</div> </div> ) : ( <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%", padding: "25px" }} > <div style={{ flex: 2.5, paddingRight: "30px" }}> {children()} </div> <div style={{ flex: 1 }}> <Sidebar title="Codestack" description="Articles on React and Node.js. All articles are written by Me. Fullstack Web Development." /> <Sidebar title="About author" description="I am a Full-stack Web Developer specializing in React and Node.js based in Nigeria." /> </div> </div> ) } </Media> </div> </div> );
Что происходит в этом монолитном блоке кода? React media использует операцию Ternary для определения того, что делать на основе maxWidth 848px. Когда экран соответствует ширине, отображаются только компоненты Header и children().
<Media query={{ maxWidth: 848 }}> {matches => matches ? ( ...stuff to render... ) : ( ...stuff to render... ) } </Media>
Ternary переподготовка. Если condition являетсяесть, оператор возвращает значение expr1; в противном случае он возвращает значение expr2. Если вы заметили, мы также использовали Flexbox для компоновки позиций children() и Sidebar компонентов. Запустите gatsby develop на терминале, наш статический блог должен выглядеть так:
3. Создание записей в блогах
Теперь давайте займемся созданием реальных постов в блоге. Gatsby использует GraphQL для извлечения данных из одного или нескольких источников, таких как локальный диск, WordPress API и т. д.
Лично мне нравится, что я могу создать статический блог и получить контент из WordPress API. Мой клиент имеет доступ к редактору WordPress, где он создает посты, и я избегаю всех проблем, связанных с разработкой сайта WordPress.
В этом посте мы будем загружать данные из файлов разметки, которые создадим на локальном диске. Плагин gatsby-source-filesystem, который мы настраивали ранее, ожидает наш контент в src/pages, так что именно туда, мы его и поместим!
Типичная практика для сообщений в блогах — это называть папку, как-то вроде MM-DD-YYYY-title. Вы можете называть его любым названием, которое вам нравится, или просто поместить файл markdown внутрь папки /pages.
Давайте создадим папку src/pages/12–22–2017-first-post и поместим внутрь index.md. Напишем:
--- path: "/hello-world" date: "2017-07-12T17:12:33.962Z" title: "My First Gatsby Post" --- Oooooh-weeee, my first blog post! First post Ipsum is a major key to success. Congratulations, you played yourself. Surround yourself with angels. Celebrate success right, the only way, apple. The key is to drink coconut, fresh coconut, trust me. Egg whites, turkey sausage, wheat toast, water. Of course they don’t want us to eat our breakfast, so we are going to enjoy our breakfast.
Блок, окруженный тире, называется frontmatter. Данные, которые мы здесь укажем, а также другие файлы разметки, будут распознаваться gatsby-transformer-remark плагином.
Плагин преобразует часть метаданных основной части файла разметки frontmatter и часть контента (Yippeeee, my first blog post!) В HTML.
Когда мы начнем создавать страницы блога непосредственно из файлов разметки в разделе 4 (следующий раздел), path будет использоваться для указания пути URL для визуализации файла. Например, файл разметки выше будет отображаться localhost:8000/hello-world.
Сначала давайте создадим шаблон, который будет отображать любой файл разметки на собственной странице блога. Создайте файл src/templates/blog-post.js (создайте src/templatesпапку).
import React from "react"; import Helmet from "react-helmet"; export default function Template({ data }) { const post = data.markdownRemark; return ( <div className="blog-post-container"> <Helmet title={`CodeStack - ${post.frontmatter.title}`} /> <div className="blog-post"> <h1>{post.frontmatter.title}</h1> <div className="blog-post-content" dangerouslySetInnerHTML={{ __html: post.html }} /> </div> </div> ); }
Мы создали Template компонент для получения data объекта, который будет получен из запроса GraphQL, который мы собираемся написать.
Еще раз, запрос GraphQL необходим для извлечения данных в компонент. Результат запроса вводится Gatsby в компонент Template как data и markdown Remark.
Мы обнаружим, что свойство markdownRemark содержит все детали файла разметки. Теперь давайте сделаем запрос. Он должен располагаться ниже Template компонента:
export const pageQuery = graphql` query BlogPostByPath($path: String!) { markdownRemark(frontmatter: { path: { eq: $path } }) { html frontmatter { date(formatString: "MMMM DD, YYYY") path title } } } ` ;
Если вы не знакомы с GraphQL, я попытаюсь объяснить то, что здесь происходит. Чтобы узнать больше о GraphQL, рассмотрите этот отличный ресурс.
GraphQL — это просто идея Facebook определенного типа раскола. Они написали спецификацию о типах запросов, которые могут быть отправлены на этот сервер, и о том, как сервер должен отвечать. API GraphQL лучше, чем REST, потому что вы описываете точные данные, которые нужны клиентской стороне, поэтому большой нехватки или чрезмерной выборки данных не существует.
Это означает, что вам нужно создать собственный сервер GraphQL. К счастью для нас, GatsbyJS поставляется со своим собственным сервером GraphQL.
В приведенном выше коде BlogPostByPath находится основной запрос, который приведет к возврату постав блоге. Он будет возвращен как data для инъекции в Template компонент.
Мы переводим BlogPostByPath на $path аргумент, чтобы вернуть пост в блоге, связанный с путем, который мы сейчас просматриваем.
Кроме того, напомним, markdownRemark перегрузил наши файлы разметки. Они будут рассматриваться как свойство, содержимое которого будет доступно через data.markdownRemark.
Мы могли бы получить доступ к HTML через data.markdownRemark.html. Кроме того, доступ к frontmatter контенту, который мы создали с блоком, можно получить через data.markdownRemark.title и т.д. Полный blog-template.js должен выглядеть так:
import React from "react"; import Helmet from "react-helmet"; export default function Template({ data }) { const post = data.markdownRemark; return ( <div className="blog-post-container"> <Helmet title={`CodeStack - ${post.frontmatter.title}`} /> <div className="blog-post"> <h1>{post.frontmatter.title}</h1> <div className="blog-post-content" dangerouslySetInnerHTML={{ __html: post.html }} /> </div> </div> ); } export const pageQuery = graphql` query BlogPostByPath($path: String!) { markdownRemark(frontmatter: { path: { eq: $path } }) { html frontmatter { date(formatString: "MMMM DD, YYYY") path title } } } ` ;
С этой точки зрения:
У нас есть куча плагинов, установленных для выполнения некоторых утилит, а также загрузки файлов с диска и преобразования Markdown в HTML.
У нас есть одиночный файл Markdown, который будет отображаться как пост в блоге.
У нас есть шаблон React для рендеринга постов в блоге в макете, а также подключенный GraphQL для запроса данных для публикации в блоге и ввода шаблона React с запрошенными данными.
Отлично!
4. Создание новых страниц из данных блога
Gatsby предоставляет API-интерфейс Node, который обеспечивает функциональность для создания динамических страниц из постов в блогах. Этот API открыт в файле gatsby-node.js в корневой папке проекта. Этот файл может экспортировать несколько Node API, но нас интересует API-интерфейс createPages.
Используйте следующий блок фрагмента кода, как указано в официальных документах (обратите внимание, что путь blogPostTemplate был настроен так, чтобы отражать наши):
const path = require('path'); exports.createPages = ({ boundActionCreators, graphql }) => { const { createPage } = boundActionCreators; const blogPostTemplate = path.resolve(`src/templates/blog-post.js`); return graphql(`{ allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { excerpt(pruneLength: 250) html id frontmatter { date path title } } } } }`) .then(result => { if (result.errors) { return Promise.reject(result.errors); } result.data.allMarkdownRemark.edges .forEach(({ node }) => { createPage({ path: node.frontmatter.path, component: blogPostTemplate, context: {} // additional data can be passed via context }); }); }); }
Проверьте, работает ли он. Я рекомендую закрыть окно вашего браузера, прекратив работу gatsby develop сервера с помощью ctrl c. Теперь запустите gatsby develop again и запустите http://localhost:8000/hello-world.
Создайте еще один файл src/pages/24–12–2017-learning-grid/index.md
--- path: "/another-one" date: "2017-07-12T17:12:33.962Z" title: "My Second Gatsby Post" --- In life there will be road blocks but we will over come it. Special cloth alert. Don’t ever play yourself. The key to more success is to get a massage once a week, very important, major key, cloth talk. <pre><code>// some css grid code </code></pre>
Снова закройте окно gatsby develop, остановите gatsby develop сервер. Запустите gatsby develop again и откройте http://localhost:8000/another- one. Как это выглядит:
Продолжайте, если хотите, и создавайте свои собственные страницы.
5. Создание списка файлов разметки сайта на целевой странице
Основная страница по умолчанию, которая поставляется с сайтом Gatsby, находится по адресу src/pages/index.js. Здесь мы должны определить шаблон и сделать запрос, чтобы ввести его в список файлов .md. Сделайте это:
import React from "react"; import Link from "gatsby-link"; import Helmet from "react-helmet"; import '../styles/blog-listing.css'; export default function Index({ data }) { const { edges: posts } = data.allMarkdownRemark; return ( <div className="blog-posts"> {posts .filter(post => post.node.frontmatter.title.length > 0) .map(({ node: post }) => { return ( <div className="blog-post-preview" key={post.id}> <h1> <Link to={post.frontmatter.path}>{post.frontmatter.title}</Link> </h1> <h2>{post.frontmatter.date}</h2> <p>{post.excerpt}</p> </div> ); })} </div> ); } export const pageQuery = graphql` query IndexQuery { allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) { edges { node { excerpt(pruneLength: 250) id frontmatter { title date(formatString: "MMMM DD, YYYY") path } } } } } `;
Надеюсь, вы уже знакомы с тем, что происходит. Обратите внимание, что мы написали вышеприведенный import, который не существует. Теперь создайте файл /styles/blog-listing.css:
div.blog-post-preview { border-bottom: 2px solid #e6e6e6; padding-top: 1rem; padding-bottom: 1rem; margin-bottom: 1rem; } h1 > * { font-size: 1.2rem; text-decoration-line: none; } h2 { font-size: 0.8rem !important; font-weight: 100 !important; }
Перезагрузите сервер, зайдите на основную страницу, и вы увидите работающий список:
Вывод
Мы подошли к концу этого урока. Спасибо, что прочитали. Этот пост — только верхушка айсберга, учитывая количество вещей, которые вы могли бы сделать с Gatsby. Не стесняйтесь изучать, как вы можете реализовать:
Функциональность поиска
Использование тегов для категоризации сообщений в блогах
Развертывание сайта Gatsby
Здесь вы можете получить конечный исходный код.
Автор: Emmanuel Yusufu
Источник: https://medium.freecodecamp.org/
Редакция: Команда webformyself.