-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
BlogPost.jsx
112 lines (104 loc) · 3.42 KB
/
BlogPost.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* Copyright (C) 2018-present Arctic Ice Studio <development@arcticicestudio.com>
* Copyright (C) 2018-present Sven Greb <development@svengreb.de>
*
* Project: Nord Docs
* Repository: https://github.com/arcticicestudio/nord-docs
* License: MIT
*/
import React from "react";
import MDXRenderer from "gatsby-mdx/mdx-renderer";
import { MDXProvider } from "@mdx-js/react";
import { graphql } from "gatsby";
import BaseLayout from "layouts/core/BaseLayout";
import Section, { Content } from "containers/core/Section";
import PageTypoHead from "../shared/PageTypoHead";
import mappedHtmlElementComponents from "../shared/mappedHtmlElementComponents";
import { blogPostTemplatePropTypes } from "../shared/propTypes";
/**
* A template for blog posts with custom HTML components and injected props that can be used in the MDX document.
*
* @author Arctic Ice Studio <development@arcticicestudio.com>
* @author Sven Greb <development@svengreb.de>
* @since 0.10.0
* @see https://mdxjs.com
* @see https://github.com/ChristopherBiscardi/gatsby-mdx
*
*/
const BlogPost = ({ data: { images, mdx, videos }, location: { pathname }, ...passProps }) => {
/*
* Generate mappings for content images and videos to allow to use them by their file names.
* Examples:
*
* - `prop.images["snow-mountain.png"]`
* - `prop.videos["arctic-owl.mp4"]`
*/
const blogPostImages = {};
images?.edges?.forEach(({ node: { childImageSharp } }) => {
blogPostImages[childImageSharp.fluid.originalName] = childImageSharp.fluid;
});
const blogPostVideos = {};
videos?.edges?.forEach(({ node }) => {
blogPostVideos[`${node.name}.${node.extension}`] = node.publicURL;
});
return (
<BaseLayout pathName={pathname}>
<Section>
<Content as="article" centered>
<PageTypoHead fontScale={9} headline={mdx.frontmatter?.title} subline={mdx.frontmatter?.introduction} />
<MDXProvider components={mappedHtmlElementComponents}>
<MDXRenderer
bannerImage={mdx.fields?.bannerImage?.childImageSharp.fluid}
coverImage={mdx.fields?.coverImage?.childImageSharp.fluid}
heroImage={mdx.fields?.heroImage?.childImageSharp.fluid}
heroVideo={mdx.fields?.heroVideo}
heroVideoPoster={mdx.fields?.heroVideoPoster?.childImageSharp.fluid}
images={blogPostImages}
videos={blogPostVideos}
{...passProps}
>
{mdx.code.body}
</MDXRenderer>
</MDXProvider>
</Content>
</Section>
</BaseLayout>
);
};
BlogPost.propTypes = blogPostTemplatePropTypes;
export const pageQuery = graphql`
query($id: String!, $relativeDirectory: String!) {
images: allFile(
filter: { relativeDirectory: { eq: $relativeDirectory }, extension: { regex: "/(png|jpe?g)/" } }
sort: { fields: [name], order: ASC }
) {
edges {
node {
childImageSharp {
...contentMdxDocumentImageFluid
}
extension
name
}
}
}
mdx(id: { eq: $id }) {
code {
body
}
id
...contentBlogPost
}
videos: allFile(
filter: { relativeDirectory: { eq: $relativeDirectory }, extension: { regex: "/(mp4|webm)/" } }
sort: { fields: [name], order: ASC }
) {
edges {
node {
...contentBlogPostMediaFile
}
}
}
}
`;
export default BlogPost;