mirror of
https://github.com/sergeyyarkov/devthread.ru.git
synced 2026-10-11 10:19:13 +03:00
snippet template
This commit is contained in:
parent
8e17931305
commit
53d5030799
@ -8,6 +8,8 @@ import './src/components/Articles/Articles.scss'
|
||||
import './src/components/Articles/ArticleCard/ArticleCard.scss'
|
||||
import './src/components/Newsletter/Newsletter.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/Books/Books.scss'
|
||||
import './src/components/Contacts/Contacts.scss'
|
||||
|
||||
@ -22,8 +22,8 @@ module.exports = {
|
||||
link: '/contacts'
|
||||
},
|
||||
{
|
||||
name: 'Ресурсы',
|
||||
link: '/deleted'
|
||||
name: 'Сниппеты',
|
||||
link: '/snippets'
|
||||
}
|
||||
],
|
||||
social: {
|
||||
@ -116,7 +116,7 @@ module.exports = {
|
||||
className: `anchor-link`,
|
||||
maintainCase: true,
|
||||
removeAccents: true,
|
||||
isIconAfterHeader: true,
|
||||
isIconAfterHeader: false,
|
||||
elements: [`h1`, `h2`, `h3`, `h4`],
|
||||
},
|
||||
},
|
||||
|
||||
@ -6,6 +6,7 @@ exports.createPages = async ({ actions, graphql }) => {
|
||||
const { createPage } = actions
|
||||
|
||||
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 tagTemplate = path.resolve('src/templates/tagTemplate.js')
|
||||
|
||||
@ -33,6 +34,7 @@ exports.createPages = async ({ actions, graphql }) => {
|
||||
|
||||
const all = result.data.allMarkdownRemark.edges
|
||||
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 tags = all.filter(tag => tag.node.frontmatter.templateKey === 'tag')
|
||||
|
||||
@ -44,7 +46,17 @@ exports.createPages = async ({ actions, graphql }) => {
|
||||
slug: node.frontmatter.slug
|
||||
},
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
snippets.forEach(({ node }) => {
|
||||
createPage({
|
||||
path: `snippet/${node.frontmatter.slug}`,
|
||||
component: snippetTemplate,
|
||||
context: {
|
||||
slug: node.frontmatter.slug
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
categories.forEach(({ node }) => {
|
||||
createPage({
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.about {
|
||||
margin-bottom: 13rem;
|
||||
& .about-heading {
|
||||
margin-bottom: 45px;
|
||||
}
|
||||
|
||||
@ -95,6 +95,7 @@ export default Article
|
||||
Article.propTypes = {
|
||||
data: PropTypes.shape({
|
||||
slug: PropTypes.string,
|
||||
keywords: PropTypes.array,
|
||||
title: PropTypes.string,
|
||||
image: PropTypes.object,
|
||||
description: PropTypes.string,
|
||||
|
||||
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import useSiteMetadataQuery from '../../hooks/useSiteMetadataQuery'
|
||||
import ArticleCard from './ArticleCard/ArticleCard'
|
||||
import Newsletter from '../Newsletter/Newsletter'
|
||||
|
||||
const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
|
||||
const { siteMetadata: { options: { articles: { onLoadMore } } } } = useSiteMetadataQuery()
|
||||
@ -27,7 +26,6 @@ const Articles = ({ data: { edges }, limit = 6, setLimit = () => null }) => {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Newsletter />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
}
|
||||
& .articles-loadMore {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
padding: 10px;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 13px;
|
||||
|
||||
border-radius: 5px 0px 0px 5px;
|
||||
}
|
||||
& button {
|
||||
|
||||
48
src/components/Snippet/Snippet.js
Normal file
48
src/components/Snippet/Snippet.js
Normal 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
|
||||
}
|
||||
42
src/components/Snippet/Snippet.scss
Normal file
42
src/components/Snippet/Snippet.scss
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/components/Snippets/Snippets.js
Normal file
33
src/components/Snippets/Snippets.js
Normal 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
|
||||
54
src/components/Snippets/Snippets.scss
Normal file
54
src/components/Snippets/Snippets.scss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/hooks/useSnippetsQuery.js
Normal file
25
src/hooks/useSnippetsQuery.js
Normal 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
|
||||
@ -6,6 +6,7 @@ import useSiteMetadataQuery from '../hooks/useSiteMetadataQuery'
|
||||
import SEO from '../components/SEO/SEO'
|
||||
import Layout from '../components/Layout/Layout'
|
||||
import Articles from '../components/Articles/Articles'
|
||||
import Snippets from '../components/Snippets/Snippets'
|
||||
import Offers from '../components/Offers/Offers'
|
||||
|
||||
import ArrowNext from '../images/arrow-next.svg'
|
||||
@ -32,6 +33,7 @@ const IndexPage = ({ data: { allMarkdownRemark: edges } }) => {
|
||||
<Row>
|
||||
<Col lg={9} xs={12}>
|
||||
<Articles data={edges} limit={limit} setLimit={setLimit} />
|
||||
<Snippets />
|
||||
</Col>
|
||||
<Col lg={3} xs={12}>
|
||||
<Offers />
|
||||
|
||||
@ -52,6 +52,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.anchor-link.before {
|
||||
top: -2px!important;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
@ -53,7 +53,7 @@ const CategoryPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query articlesByCategory($title: String!) {
|
||||
allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}}}) {
|
||||
allMarkdownRemark(filter: {frontmatter: {category: {eq: $title}, templateKey: {eq: "article"}}}) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
|
||||
39
src/templates/snippetTemplate.js
Normal file
39
src/templates/snippetTemplate.js
Normal 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
|
||||
@ -53,7 +53,7 @@ const TagPage = ({ data: { allMarkdownRemark: edges }, pageContext: { title } })
|
||||
|
||||
export const pageQuery = graphql`
|
||||
query articlesByTag($title: [String!]) {
|
||||
allMarkdownRemark(filter: {frontmatter: {tags: {in: $title}}}) {
|
||||
allMarkdownRemark(filter: {frontmatter: {tags: {in: $title}, templateKey: {eq: "article"}}}) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
|
||||
@ -22,6 +22,20 @@ collections:
|
||||
- {label: "Описание", name: "description", widget: "text"}
|
||||
- {label: "Содержание", name: "body", widget: "markdown"}
|
||||
- {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'
|
||||
label: "Category"
|
||||
folder: 'content/categories'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user