mirror of
https://github.com/sergeyyarkov/devthread.ru.git
synced 2026-10-11 02:09:04 +03:00
added category page
This commit is contained in:
parent
8abf87d842
commit
cb48215bc4
60
gatsby-node.esm.js
Normal file
60
gatsby-node.esm.js
Normal file
@ -0,0 +1,60 @@
|
||||
import slugify from './src/helpers/slugify'
|
||||
import { fmImagesToRelative } from 'gatsby-remark-relative-images'
|
||||
import path from 'path'
|
||||
|
||||
exports.createPages = async ({ actions, graphql }) => {
|
||||
const { createPage } = actions
|
||||
|
||||
const articleTemplate = path.resolve('src/templates/articleTemplate.js')
|
||||
const categoryTemplate = path.resolve('src/templates/categoryTemplate.js')
|
||||
|
||||
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')
|
||||
const categories = all.filter(category => category.node.frontmatter.templateKey === 'category')
|
||||
|
||||
articles.forEach(({ node }) => {
|
||||
createPage({
|
||||
path: `article/${node.frontmatter.slug}`,
|
||||
component: articleTemplate,
|
||||
context: {
|
||||
slug: node.frontmatter.slug
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
categories.forEach(({ node }) => {
|
||||
createPage({
|
||||
path: `category/${slugify(node.frontmatter.title)}`,
|
||||
component: categoryTemplate,
|
||||
context: {
|
||||
title: node.frontmatter.title
|
||||
},
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
exports.onCreateNode = ({ node }) => {
|
||||
fmImagesToRelative(node);
|
||||
};
|
||||
@ -1,39 +1,2 @@
|
||||
const { fmImagesToRelative } = require('gatsby-remark-relative-images');
|
||||
const path = require('path')
|
||||
|
||||
exports.createPages = ({ actions, graphql }) => {
|
||||
const { createPage } = actions
|
||||
const articleTemplate = path.resolve('src/templates/articleTemplate.js')
|
||||
|
||||
return graphql(`
|
||||
{
|
||||
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`).then(result => {
|
||||
if (result.errors) {
|
||||
return Promise.reject(result.errors);
|
||||
}
|
||||
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
|
||||
createPage({
|
||||
path: `article/${node.frontmatter.slug}`,
|
||||
component: articleTemplate,
|
||||
context: {
|
||||
slug: node.frontmatter.slug
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
exports.onCreateNode = ({ node }) => {
|
||||
fmImagesToRelative(node);
|
||||
};
|
||||
require = require('esm')(module)
|
||||
module.exports = require('./gatsby-node.esm.js')
|
||||
5
package-lock.json
generated
5
package-lock.json
generated
@ -7314,6 +7314,11 @@
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
|
||||
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ=="
|
||||
},
|
||||
"esm": {
|
||||
"version": "3.2.25",
|
||||
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
|
||||
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA=="
|
||||
},
|
||||
"espree": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@reach/router": "^1.3.4",
|
||||
"esm": "^3.2.25",
|
||||
"gatsby": "^2.23.12",
|
||||
"gatsby-image": "^2.4.12",
|
||||
"gatsby-plugin-netlify-cms": "^4.3.9",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import SEO from '../SEO/SEO'
|
||||
import Img from "gatsby-image"
|
||||
import slugify from '../../helpers/slugify'
|
||||
import { Link } from 'gatsby'
|
||||
import './Article.scss'
|
||||
|
||||
@ -35,7 +36,7 @@ const Article = ({ data: { title, image, description, category, tags, time, date
|
||||
<h1>{title}</h1>
|
||||
</div>
|
||||
<div className="article-category">
|
||||
<Link to={`/category/${category}`}>{category}</Link>
|
||||
<Link to={`/category/${slugify(category)}`}>{category}</Link>
|
||||
</div>
|
||||
<div className="article-share">
|
||||
<span>Поделиться:</span>
|
||||
@ -68,7 +69,7 @@ const Article = ({ data: { title, image, description, category, tags, time, date
|
||||
<div dangerouslySetInnerHTML={{__html: html}}></div>
|
||||
</div>
|
||||
<div className="article-more">
|
||||
<span>Смотреть еще в категории <Link to={`/category/${category}`}>{category}</Link></span>
|
||||
<span>Смотреть еще в категории <Link to={`/category/${slugify(category)}`}>{category}</Link></span>
|
||||
</div>
|
||||
<div className="article-comments">
|
||||
<div className="article-comments__heading">
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import slugify from '../../../helpers/slugify'
|
||||
import Img from "gatsby-image"
|
||||
import { Link } from 'gatsby'
|
||||
import './ArticleCard.scss'
|
||||
@ -15,7 +16,7 @@ const ArticleCard = ({ data: { slug, title, image, category, description, tags }
|
||||
<h2><Link to={`/article/${slug}`}>{title}</Link></h2>
|
||||
</div>
|
||||
<div className="article-card__category">
|
||||
<Link to={`/category/${category}`}>{category}</Link>
|
||||
<Link to={`/category/${slugify(category)}`}>{category}</Link>
|
||||
</div>
|
||||
<div className="article-card__tags">
|
||||
<ul>
|
||||
|
||||
67
src/helpers/slugify.js
Normal file
67
src/helpers/slugify.js
Normal file
@ -0,0 +1,67 @@
|
||||
const slugify = str => {
|
||||
const patterns = {
|
||||
rus: /^[0-9а-яё-\s]*$/i
|
||||
}
|
||||
|
||||
const translit = str => {
|
||||
if (str.match(patterns.rus)) {
|
||||
const ru = {
|
||||
а: "a",
|
||||
б: "b",
|
||||
в: "v",
|
||||
г: "g",
|
||||
д: "d",
|
||||
е: "e",
|
||||
ё: "e",
|
||||
ж: "j",
|
||||
з: "z",
|
||||
и: "i",
|
||||
к: "k",
|
||||
л: "l",
|
||||
м: "m",
|
||||
н: "n",
|
||||
о: "o",
|
||||
п: "p",
|
||||
р: "r",
|
||||
с: "s",
|
||||
т: "t",
|
||||
у: "u",
|
||||
ф: "f",
|
||||
х: "h",
|
||||
ц: "c",
|
||||
ч: "ch",
|
||||
ш: "sh",
|
||||
щ: "shch",
|
||||
ы: "y",
|
||||
э: "e",
|
||||
ю: "u",
|
||||
я: "ya"
|
||||
},
|
||||
newStr = [];
|
||||
|
||||
for (var i = 0; i < str.length; ++i) {
|
||||
const candidate = str[i].toLowerCase()
|
||||
|
||||
if (ru[candidate]) {
|
||||
newStr.push(ru[candidate]);
|
||||
}
|
||||
|
||||
if (candidate === '-' || !isNaN(candidate)) {
|
||||
newStr.push(candidate)
|
||||
}
|
||||
}
|
||||
|
||||
return newStr.join("");
|
||||
}
|
||||
|
||||
return 'not rus'
|
||||
}
|
||||
|
||||
if (str.match(patterns.rus)) {
|
||||
return translit(str).split(' ').join('-').toLowerCase()
|
||||
}
|
||||
|
||||
return str.split(' ').join('-').toLowerCase()
|
||||
};
|
||||
|
||||
export default slugify
|
||||
@ -43,7 +43,7 @@ const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
|
||||
|
||||
export const query = graphql`
|
||||
{
|
||||
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}) {
|
||||
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "article"}}}, sort: {order: DESC, fields: frontmatter___date}) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
|
||||
100
src/templates/categoryTemplate.js
Normal file
100
src/templates/categoryTemplate.js
Normal file
@ -0,0 +1,100 @@
|
||||
import React from "react"
|
||||
import { Link, graphql } from 'gatsby'
|
||||
import SEO from '../components/SEO/SEO'
|
||||
import Layout from '../components/Layout/Layout'
|
||||
import Articles from '../components/Articles/Articles'
|
||||
import Offers from '../components/Offers/Offers'
|
||||
import Newsletter from '../components/Newsletter/Newsletter'
|
||||
|
||||
const CategoryPage = ({ data: { allMarkdownRemark: edges } }) => {
|
||||
return (
|
||||
<Layout>
|
||||
<SEO title='Категория' />
|
||||
<main>
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-9 col-xs-12">
|
||||
<div className="articles">
|
||||
<div className="articles-heading">
|
||||
<h1>Статьи</h1>
|
||||
</div>
|
||||
<div className="articles-categories">
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Все</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Javascript</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>GraphQL</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Reactjs</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>SEO оптимизация</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Web разработка</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>pet-проекты</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Nodejs</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>ООП</Link>
|
||||
</div>
|
||||
<div className="tag-item">
|
||||
<Link to='/'>Новости</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="articles-search">
|
||||
<input placeholder="Напишите сюда чтобы отфильтровать статьи" type="text" />
|
||||
<span>278</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-md-9 col-xs-12">
|
||||
<Articles data={edges} />
|
||||
<Newsletter />
|
||||
</div>
|
||||
<div className="col-md-3 col-xs-12">
|
||||
<Offers />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query articleByCategory($title: String!) {
|
||||
allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}}}) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
slug
|
||||
title
|
||||
image {
|
||||
childImageSharp {
|
||||
fluid {
|
||||
...GatsbyImageSharpFluid
|
||||
}
|
||||
}
|
||||
}
|
||||
category
|
||||
tags
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default CategoryPage
|
||||
@ -14,8 +14,8 @@ collections:
|
||||
- {label: "Slug", name: "slug", widget: "string"}
|
||||
- {label: "Время чтения", name: "time", widget: "string"}
|
||||
- {label: "Заголовок", name: "title", widget: "string"}
|
||||
- {labe: "Обложка", name: "image", widget: "image"}
|
||||
- {label: "Категория", name: "category", widget: "relation", collection: "categories", valueField: "title", searchFields: ["title"]}
|
||||
- {label: "Обложка", name: "image", widget: "image"}
|
||||
- {label: "Категория", name: "category", widget: "relation", collection: "categories", valueField: "title", searchFields: ["title", "slug"]}
|
||||
- {label: "Дата публикации", name: "date", widget: "datetime"}
|
||||
- {label: "Описание", name: "description", widget: "text"}
|
||||
- {label: "Содержание", name: "body", widget: "markdown"}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user