diff --git a/gatsby-node.esm.js b/gatsby-node.esm.js
new file mode 100644
index 0000000..3300502
--- /dev/null
+++ b/gatsby-node.esm.js
@@ -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);
+};
diff --git a/gatsby-node.js b/gatsby-node.js
index 47a7474..20728a7 100644
--- a/gatsby-node.js
+++ b/gatsby-node.js
@@ -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);
-};
\ No newline at end of file
+require = require('esm')(module)
+module.exports = require('./gatsby-node.esm.js')
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 29bac13..c3ca23a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index dc85f95..b97071d 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/components/Article/Article.js b/src/components/Article/Article.js
index 6a4f4ec..9be7388 100644
--- a/src/components/Article/Article.js
+++ b/src/components/Article/Article.js
@@ -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
{title}
- {category}
+ {category}
Поделиться:
@@ -68,7 +69,7 @@ const Article = ({ data: { title, image, description, category, tags, time, date
- Смотреть еще в категории {category}
+ Смотреть еще в категории {category}
diff --git a/src/components/Articles/ArticleCard/ArticleCard.js b/src/components/Articles/ArticleCard/ArticleCard.js
index a9d2eb6..0700119 100644
--- a/src/components/Articles/ArticleCard/ArticleCard.js
+++ b/src/components/Articles/ArticleCard/ArticleCard.js
@@ -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 }
{title}
- {category}
+ {category}
diff --git a/src/helpers/slugify.js b/src/helpers/slugify.js
new file mode 100644
index 0000000..f198d55
--- /dev/null
+++ b/src/helpers/slugify.js
@@ -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
\ No newline at end of file
diff --git a/src/pages/index.js b/src/pages/index.js
index e625367..3393afc 100644
--- a/src/pages/index.js
+++ b/src/pages/index.js
@@ -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 {
diff --git a/src/templates/categoryTemplate.js b/src/templates/categoryTemplate.js
new file mode 100644
index 0000000..9409f75
--- /dev/null
+++ b/src/templates/categoryTemplate.js
@@ -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 (
+
+
+
+
+
+
+
+
+
Статьи
+
+
+
+ Все
+
+
+ Javascript
+
+
+ GraphQL
+
+
+ Reactjs
+
+
+ SEO оптимизация
+
+
+ Web разработка
+
+
+ pet-проекты
+
+
+ Nodejs
+
+
+ ООП
+
+
+ Новости
+
+
+
+
+ 278
+
+
+
+
+
+
+
+
+ )
+}
+
+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
diff --git a/static/admin/config.yml b/static/admin/config.yml
index e7c187e..4a76c02 100644
--- a/static/admin/config.yml
+++ b/static/admin/config.yml
@@ -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"}