Эта статья была спонсирована Cosmic JS . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.
В этом уроке я собираюсь показать вам, как создать простой блог с использованием React, GraphQL и Cosmic JS . Это будет самый быстрый и легкий блог, созданный на основе современных технологий. Давайте начнем.
TL; DR
Посмотреть демо
Установите блог Simple React на Cosmic JS
Посмотреть кодовую базу на GitHub
Начиная
Убедитесь, что на вашем компьютере установлены Node.js и NPM, в противном случае посетите веб-сайт Node.js, чтобы установить последнюю версию.
Давайте начнем с создания папки для нашего приложения. В вашем любимом терминале выполните следующие команды:
mkdir simple-react-blog
cd simple-react-blog
Теперь давайте добавим файл package.json, чтобы импортировать все наши зависимости для нашего приложения:
vim package.json
Добавьте следующее в наш файл package.json:
{
{
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "next build; NODE_ENV=production node server.js"
},
"dependencies": {
"axios": "^0.16.2",
"express": "^4.16.2",
"lodash": "^4.17.4",
"next": "^4.0.3",
"next-routes": "^1.1.0",
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}
Это довольно легкий список зависимостей для довольно легкого приложения. Итак, что мы будем устанавливать:
- Аксиос для нашего HTTP-клиента, основанного на обещаниях, для получения контента от Cosmic JS GraphQL API .
- Next.js как наша платформа React Universal.
- Следующие маршруты для динамических маршрутов.
- Express для нашего веб-приложения на стороне сервера.
- Реагировать на наш пользовательский интерфейс.
Наши скрипты необходимы для запуска нашего приложения в производство и разработку.
Запустите следующую команду, чтобы установить наши зависимости:
npm i
Строим наш блог
Далее, давайте начнем создавать страницы нашего блога. Создайте папку страниц и добавьте файл index.js:
vim index.js
и добавьте следующее в index.js:
import axios from 'axios'
import _ from 'lodash'
import Footer from './partials/footer'
import Header from './partials/header'
import helpers from '../helpers'
import config from '../config'
export default class extends React.Component {
static async getInitialProps({ req }) {
const query = `{
objects(bucket_slug: "${config.bucket.slug}") {
_id
type_slug
slug
title
metadata
created_at
}
}`
return await axios.post(`https://graphql.cosmicjs.com/v1`, { query })
.then(function (response) {
return {
cosmic: {
posts: _.filter(response.data.data.objects, { type_slug: 'posts' }),
global: _.keyBy(_.filter(response.data.data.objects, { type_slug: 'globals' }), 'slug')
}
}
})
.catch(function (error) {
console.log(error)
})
}
render() {
if (!this.props.cosmic)
return <div>Loading...</div>
return (
<div>
<Header cosmic={ this.props.cosmic }/>
<main className="container">
{
this.props.cosmic.posts &&
this.props.cosmic.posts.map(post => {
const friendly_date = helpers.friendlyDate(new Date(post.created_at))
post.friendly_date = friendly_date.month + ' ' + friendly_date.date
return (
<div className="card" data-href={`/${post.slug}`} key={post._id}>
{
post.metadata.hero.imgix_url &&
<a href={`/${post.slug}`} className="blog-post-hero blog-post-hero--short" style={{ backgroundImage: `url(${post.metadata.hero.imgix_url})`}}></a>
}
<div className="card-padding">
<h2 className="blog__title blog__title--small">
<a href={`/${post.slug}`}>{post.title}</a>
</h2>
<div className="blog__author">
<a href={`/author/${post.metadata.author.slug}`}>
<div className="blog__author-image" style={{ backgroundImage: `url(${post.metadata.author.metafields[0].imgix_url}?w=100)`}}></div>
</a>
<div className="blog__author-title">by <a href={`/author/${post.metadata.author.slug}`}>{post.metadata.author.title}</a> on {post.friendly_date}</div>
<div className="clearfix"></div>
</div>
<div className="blog__teaser droid" dangerouslySetInnerHTML={{__html: post.metadata.teaser}}></div>
<div className="blog__read-more">
<a href={`/${post.slug}`}>Read more...</a>
</div>
</div>
</div>
)
})
}
</main>
<Footer />
</div>
)
}
}
Здесь происходит несколько вещей:
- Мы импортируем наши основные модули: Axios, Lodash и другие помощники и компоненты.
- Мы добавляем некоторые партиалы: верхний и нижний колонтитулы, вы можете ссылаться на эти партиалы из базы кода на GitHub .
- Мы запрашиваем API Cosmic JS GraphQL, чтобы вернуть только то, что нам нужно: _id, type_slug, slug, title, metadata и creation_at.
- Мы устанавливаем основные реквизиты в нашем компоненте для
cosmic
И используйте lodash для разбора типов сообщений и глобальных объектов. - Мы возвращаем данные массива постов и URL-адреса изображений в наш основной блог.
Один пост-запрос
Для нашего отдельного поста мы добавляем свойство post
Сообщение найдено путем сопоставления query.slug и Object slug:
const gql_query = `{
objects(bucket_slug: "${config.bucket.slug}") {
type_slug
slug
title
content
metadata
created_at
}
}`
return await axios.post(`https://graphql.cosmicjs.com/v1`, { query: gql_query })
.then(function (response) {
return {
cosmic: {
posts: _.filter(response.data.data.objects, { type_slug: 'posts' }),
global: _.keyBy(_.filter(response.data.data.objects, { type_slug: 'globals' }), 'slug'),
post: _.find(response.data.data.objects, { slug: query.slug }),
}
}
})
.catch(function (error) {
console.log(error)
})
}
Проверьте полный файл на GitHub .
Вывод
Это сокращенная версия блога Simple React, доступная для загрузки на странице Cosmic JS Apps . Полная кодовая база включает в себя один просмотр страницы поста, а также страницу, посвященную постам каждого автора. Просмотрите полную кодовую базу на GitHub и разверните это приложение в несколько кликов с панели управления Cosmic JS, установив приложение в корзину Cosmic JS.
Надеюсь, вам понравился этот урок, если у вас есть какие-либо вопросы, обращайтесь к нам в Twitter и присоединяйтесь к нашему сообществу в Slack .