snippet template

This commit is contained in:
Sergey Yarkov 2020-07-18 21:05:48 +03:00
parent 8e17931305
commit 53d5030799
19 changed files with 284 additions and 10 deletions

View File

@ -8,6 +8,8 @@ import './src/components/Articles/Articles.scss'
import './src/components/Articles/ArticleCard/ArticleCard.scss' import './src/components/Articles/ArticleCard/ArticleCard.scss'
import './src/components/Newsletter/Newsletter.scss' import './src/components/Newsletter/Newsletter.scss'
import './src/components/Article/Article.scss' import './src/components/Article/Article.scss'
import './src/components/Snippet/Snippet.scss'
import './src/components/Snippets/Snippets.scss'
import './src/components/Articles/MoreArticles/MoreArticles.scss' import './src/components/Articles/MoreArticles/MoreArticles.scss'
import './src/components/Books/Books.scss' import './src/components/Books/Books.scss'
import './src/components/Contacts/Contacts.scss' import './src/components/Contacts/Contacts.scss'

View File

@ -22,8 +22,8 @@ module.exports = {
link: '/contacts' link: '/contacts'
}, },
{ {
name: 'Ресурсы', name: 'Сниппеты',
link: '/deleted' link: '/snippets'
} }
], ],
social: { social: {
@ -116,7 +116,7 @@ module.exports = {
className: `anchor-link`, className: `anchor-link`,
maintainCase: true, maintainCase: true,
removeAccents: true, removeAccents: true,
isIconAfterHeader: true, isIconAfterHeader: false,
elements: [`h1`, `h2`, `h3`, `h4`], elements: [`h1`, `h2`, `h3`, `h4`],
}, },
}, },

View File

@ -6,6 +6,7 @@ exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions const { createPage } = actions
const articleTemplate = path.resolve('src/templates/articleTemplate.js') const articleTemplate = path.resolve('src/templates/articleTemplate.js')
const snippetTemplate = path.resolve('src/templates/snippetTemplate.js')
const categoryTemplate = path.resolve('src/templates/categoryTemplate.js') const categoryTemplate = path.resolve('src/templates/categoryTemplate.js')
const tagTemplate = path.resolve('src/templates/tagTemplate.js') const tagTemplate = path.resolve('src/templates/tagTemplate.js')
@ -33,6 +34,7 @@ exports.createPages = async ({ actions, graphql }) => {
const all = result.data.allMarkdownRemark.edges const all = result.data.allMarkdownRemark.edges
const articles = all.filter(article => article.node.frontmatter.templateKey === 'article') const articles = all.filter(article => article.node.frontmatter.templateKey === 'article')
const snippets = all.filter(snippet => snippet.node.frontmatter.templateKey === 'snippet')
const categories = all.filter(category => category.node.frontmatter.templateKey === 'category') const categories = all.filter(category => category.node.frontmatter.templateKey === 'category')
const tags = all.filter(tag => tag.node.frontmatter.templateKey === 'tag') const tags = all.filter(tag => tag.node.frontmatter.templateKey === 'tag')
@ -44,7 +46,17 @@ exports.createPages = async ({ actions, graphql }) => {
slug: node.frontmatter.slug slug: node.frontmatter.slug
}, },
}); });
}); })
snippets.forEach(({ node }) => {
createPage({
path: `snippet/${node.frontmatter.slug}`,
component: snippetTemplate,
context: {
slug: node.frontmatter.slug
},
})
})
categories.forEach(({ node }) => { categories.forEach(({ node }) => {
createPage({ createPage({

View File

@ -1,6 +1,7 @@
@import '../../styles/variables.scss'; @import '../../styles/variables.scss';
.about { .about {
margin-bottom: 13rem;
& .about-heading { & .about-heading {
margin-bottom: 45px; margin-bottom: 45px;
} }

View File

@ -95,6 +95,7 @@ export default Article
Article.propTypes = { Article.propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
slug: PropTypes.string, slug: PropTypes.string,
keywords: PropTypes.array,
title: PropTypes.string, title: PropTypes.string,
image: PropTypes.object, image: PropTypes.object,
description: PropTypes.string, description: PropTypes.string,

View File

@ -2,7 +2,6 @@ import React from 'react';
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery' import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery'
import ArticleCard from './ArticleCard/ArticleCard' import ArticleCard from './ArticleCard/ArticleCard'
import Newsletter from '../Newsletter/Newsletter'
const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => { const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
const { siteMetadata: { options: { articles: { onLoadMore } } } } = useSiteMetadataQuery() const { siteMetadata: { options: { articles: { onLoadMore } } } } = useSiteMetadataQuery()
@ -27,7 +26,6 @@ const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
} }
</div> </div>
</div> </div>
<Newsletter />
</> </>
) )
} }

View File

@ -58,7 +58,7 @@
} }
& .articles-loadMore { & .articles-loadMore {
text-align: center; text-align: center;
margin-bottom: 30px; margin-bottom: 50px;
} }
} }

View File

@ -25,7 +25,6 @@
padding: 10px; padding: 10px;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
font-size: 13px; font-size: 13px;
border-radius: 5px 0px 0px 5px; border-radius: 5px 0px 0px 5px;
} }
& button { & button {

View File

@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types'
import SEO from '../SEO/SEO'
const Snippet = ({ data: { keywords, description, title, date }, html }) => {
return (
<>
<SEO title={title} titleTemplate={false} description={description} keywords={keywords.join(', ')} type='article' />
<div className="snippet">
<article>
<div className="snippet-date">
{date}
</div>
<div className="snippet-heading">
<h1>{title}</h1>
</div>
<div className="snippet-description">
<p>
{description}
</p>
</div>
<div className="snippet-inner inner">
<div dangerouslySetInnerHTML={{__html: html}}></div>
</div>
<div className="snippet-comments">
<div className="snippet-comments__heading">
<h2>Комментарии</h2>
</div>
<div className="snippet-comments__content">
</div>
</div>
</article>
</div>
</>
)
}
export default Snippet
Snippet.propTypes = {
data: PropTypes.shape({
keywords: PropTypes.array,
title: PropTypes.string,
description: PropTypes.string,
date: PropTypes.string
}),
html: PropTypes.string
}

View File

@ -0,0 +1,42 @@
@import '../../styles/variables.scss';
.snippet {
& article {
& .snippet-date {
text-align: center;
font-size: 16px;
color: #767676;
}
& .snippet-heading {
font-size: 21px;
text-align: center;
& h1 {
font-size: 40px;
}
margin-bottom: 15px;
}
& .snippet-description {
margin-bottom: 50px;
& p {
text-align: center;
}
}
& .snippet-comments {
margin: 25px 0;
}
}
}
.dark {
& .snippet {
& article {
& p, h1, h2, h3, h4, h5, h6, ul, ol {
color: $white-clr;
}
& blockquote {
background: #2A2A2A;
color: $white-clr;
}
}
}
}

View File

@ -0,0 +1,33 @@
import React from 'react';
import { Link } from 'gatsby'
import useSnippetsQuery from '../../hooks/useSnippetsQuery'
const Snippets = () => {
const { snippets } = useSnippetsQuery()
return (
<div className='snippets'>
<h2>Сниппеты</h2>
{snippets.map(({ node: { frontmatter } }, i) => (
<div key={i} className='snippet-item'>
<div className="left-info">
<div className="snippet-item__date">
{frontmatter.date}
</div>
<div className="snippet-item__heading">
<Link to={`/snippet/${frontmatter.slug}`}>{frontmatter.title}</Link>
</div>
</div>
<div className="right-info">
<div className="snippet-item__tags">
{frontmatter.tags.map((tag, i) => (
<div key={i} className="tag-item">{tag}</div>
))}
</div>
</div>
</div>
))}
</div>
)
}
export default Snippets

View File

@ -0,0 +1,54 @@
@import '../../styles/variables.scss';
.snippets {
margin-bottom: 40px;
& h2 {
margin-bottom: 20px;
font-size: 34px;
}
& .snippet-item {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 64px;
background: linear-gradient(92.41deg, #F5F9FF 0%, #F6F4FB 100%);
border-radius: 7px;
margin-bottom: 10px;
padding: 10px 15px;
&__date {
font-size: 13px;
}
&__heading {
& a {
font-size: 16px;
font-weight: 700;
text-decoration: none;
}
}
&__tags {
display: flex;
& .tag-item {
margin: 0;
margin-right: 5px;
padding: 5px 10px;
background: #EBF1FE;
color: #6ab0f3;
font-size: 14px;
border-radius: 4px;
}
}
}
}
.dark {
& .snippets {
color: $white-clr;
& .snippet-item {
background: #2A2A2A;
& .tag-item {
color: #5183F5;
background: rgba(0, 0, 0, 0.2);
}
}
}
}

View File

@ -0,0 +1,25 @@
import { useStaticQuery, graphql } from 'gatsby'
const useSnippetsQuery = () => {
const { allMarkdownRemark: { edges } } = useStaticQuery(graphql`
{
allMarkdownRemark(filter: {frontmatter: {templateKey: {eq: "snippet"}}}, sort: {order: DESC, fields: frontmatter___date}) {
edges {
node {
frontmatter {
slug
title
tags
description
date(formatString: "D MMMM YYYY", locale: "ru-RU")
}
}
}
}
}
`)
return { snippets: edges }
}
export default useSnippetsQuery

View File

@ -6,6 +6,7 @@ import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery'
import SEO from '../components/SEO/SEO' import SEO from '../components/SEO/SEO'
import Layout from '../components/Layout/Layout' import Layout from '../components/Layout/Layout'
import Articles from '../components/Articles/Articles' import Articles from '../components/Articles/Articles'
import Snippets from '../components/Snippets/Snippets'
import Offers from '../components/Offers/Offers' import Offers from '../components/Offers/Offers'
import ArrowNext from '../images/arrow-next.svg' import ArrowNext from '../images/arrow-next.svg'
@ -32,6 +33,7 @@ const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
<Row> <Row>
<Col lg={9} xs={12}> <Col lg={9} xs={12}>
<Articles data={edges} limit={limit} setLimit={setLimit} /> <Articles data={edges} limit={limit} setLimit={setLimit} />
<Snippets />
</Col> </Col>
<Col lg={3} xs={12}> <Col lg={3} xs={12}>
<Offers /> <Offers />

View File

@ -52,6 +52,10 @@
} }
} }
.anchor-link.before {
top: -2px!important;
}
.anchor { .anchor {
display: block; display: block;
position: relative; position: relative;

View File

@ -53,7 +53,7 @@ const CategoryPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title
export const pageQuery = graphql` export const pageQuery = graphql`
query articlesByCategory($title: String!) { query articlesByCategory($title: String!) {
allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}}}) { allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}, templateKey: {eq: "article"}}}) {
edges { edges {
node { node {
frontmatter { frontmatter {

View File

@ -0,0 +1,39 @@
import React from 'react'
import { Main } from '../ui/ui'
import { Grid, Row, Col } from 'react-flexbox-grid'
import Snippet from '../components/Snippet/Snippet'
import Layout from '../components/Layout/Layout'
import { graphql } from "gatsby"
const snippetTemplate = ({ data: { markdownRemark: { frontmatter, html } } }) => {
return (
<Layout>
<Main>
<Grid fluid style={{ maxWidth: 900 }}>
<Row>
<Col lg={12}>
<Snippet data={frontmatter} html={html} />
</Col>
</Row>
</Grid>
</Main>
</Layout>
)
}
export const pageQuery = graphql`
query Snippet($slug: String!) {
markdownRemark(frontmatter: {slug: {eq: $slug}, templateKey: {eq: "snippet"}}) {
html
frontmatter {
slug
keywords
title
description
date(formatString: "D MMMM YYYY", locale: "ru-RU")
}
}
}
`
export default snippetTemplate

View File

@ -53,7 +53,7 @@ const TagPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } })
export const pageQuery = graphql` export const pageQuery = graphql`
query articlesByTag($title: [String!]) { query articlesByTag($title: [String!]) {
allMarkdownRemark(filter: {frontmatter: {tags: {in: $title}}}) { allMarkdownRemark(filter: {frontmatter: {tags: {in: $title}, templateKey: {eq: "article"}}}) {
edges { edges {
node { node {
frontmatter { frontmatter {

View File

@ -22,6 +22,20 @@ collections:
- {label: "Описание", name: "description", widget: "text"} - {label: "Описание", name: "description", widget: "text"}
- {label: "Содержание", name: "body", widget: "markdown"} - {label: "Содержание", name: "body", widget: "markdown"}
- {label: "Тэги", name: "tags", widget: "relation", multiple: true, collection: "tags", valueField: "title", searchFields: ["title"]} - {label: "Тэги", name: "tags", widget: "relation", multiple: true, collection: "tags", valueField: "title", searchFields: ["title"]}
- name: 'snippets'
label: "Snippet"
folder: 'content/snippets'
create: true
slug: "{{slug}}"
fields:
- {label: "Template key", name: "templateKey", widget: "hidden", default: "snippet"}
- {label: "Slug", name: "slug", widget: "string"}
- {label: "Keywords", name: "keywords", widget: "list"}
- {label: "Название сниппета", name: "title", widget: "string"}
- {label: "Дата публикации", name: "date", widget: "datetime"}
- {label: "Тэги", name: "tags", widget: "list"}
- {label: "Описание", name: "description", widget: "text"}
- {label: "Содержание", name: "body", widget: "markdown"}
- name: 'categories' - name: 'categories'
label: "Category" label: "Category"
folder: 'content/categories' folder: 'content/categories'