feat(client): use custom components for guide articles
parent
54e6f4d6ae
commit
6a93b44aca
|
@ -30,12 +30,15 @@ exports.onCreateNode = function onCreateNode({ node, actions, getNode }) {
|
|||
}
|
||||
|
||||
if (node.internal.type === 'MarkdownRemark') {
|
||||
let slug = createFilePath({ node, getNode });
|
||||
const slug = createFilePath({ node, getNode });
|
||||
if (!slug.includes('LICENSE')) {
|
||||
const {
|
||||
frontmatter: { component = '' }
|
||||
} = node;
|
||||
createNodeField({ node, name: 'slug', value: slug });
|
||||
createNodeField({ node, name: 'component', value: component });
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.createPages = function createPages({ graphql, actions }) {
|
||||
|
@ -75,6 +78,7 @@ exports.createPages = function createPages({ graphql, actions }) {
|
|||
fields {
|
||||
slug
|
||||
nodeIdentity
|
||||
component
|
||||
}
|
||||
frontmatter {
|
||||
block
|
||||
|
|
|
@ -1,58 +1,28 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { graphql } from 'gatsby';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import Breadcrumbs from './components/Breadcrumbs';
|
||||
import ArticleLayout from './components/ArticleLayout';
|
||||
|
||||
const propTypes = {
|
||||
data: PropTypes.object,
|
||||
location: PropTypes.object,
|
||||
pageContext: PropTypes.shape({
|
||||
meta: PropTypes.objectOf(PropTypes.string)
|
||||
})
|
||||
data: PropTypes.object
|
||||
};
|
||||
|
||||
const GuideArticle = props => {
|
||||
const {
|
||||
location: { pathname },
|
||||
data: {
|
||||
markdownRemark: {
|
||||
html,
|
||||
fields: { slug },
|
||||
frontmatter: { title }
|
||||
}
|
||||
},
|
||||
pageContext: { meta }
|
||||
markdownRemark: { html }
|
||||
}
|
||||
} = props;
|
||||
return (
|
||||
<Fragment>
|
||||
<Helmet>
|
||||
<title>{`${title} | freeCodeCamp Guide`}</title>
|
||||
<link href={`https://www.freecodecamp.org${slug}`} rel='canonical' />
|
||||
<meta
|
||||
content={`https://www.freecodecamp.org${slug}`}
|
||||
property='og:url'
|
||||
/>
|
||||
<meta content={title} property='og:title' />
|
||||
<meta
|
||||
content={meta.description ? meta.description : ''}
|
||||
property='og:description'
|
||||
/>
|
||||
<meta
|
||||
content={meta.description ? meta.description : ''}
|
||||
name='description'
|
||||
/>
|
||||
<meta content={meta.featureImage} property='og:image' />
|
||||
</Helmet>
|
||||
<Breadcrumbs path={pathname} />
|
||||
<ArticleLayout {...props}>
|
||||
<article
|
||||
className='article'
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
id='article'
|
||||
tabIndex='-1'
|
||||
/>
|
||||
</Fragment>
|
||||
</ArticleLayout>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -65,12 +35,7 @@ export const pageQuery = graphql`
|
|||
query ArticleById($id: String!) {
|
||||
markdownRemark(id: { eq: $id }) {
|
||||
html
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
frontmatter {
|
||||
title
|
||||
}
|
||||
...ArticleLayout
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { graphql } from 'gatsby';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import Breadcrumbs from './Breadcrumbs';
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.any,
|
||||
data: PropTypes.object,
|
||||
location: PropTypes.object,
|
||||
pageContext: PropTypes.shape({
|
||||
meta: PropTypes.objectOf(PropTypes.string)
|
||||
})
|
||||
};
|
||||
|
||||
const ArticleLayout = props => {
|
||||
const {
|
||||
children,
|
||||
location: { pathname },
|
||||
data: {
|
||||
markdownRemark: {
|
||||
fields: { slug },
|
||||
frontmatter: { title }
|
||||
}
|
||||
},
|
||||
pageContext: { meta }
|
||||
} = props;
|
||||
return (
|
||||
<Fragment>
|
||||
<Helmet>
|
||||
<title>{`${title} | freeCodeCamp Guide`}</title>
|
||||
<link href={`https://www.freecodecamp.org${slug}`} rel='canonical' />
|
||||
<meta
|
||||
content={`https://www.freecodecamp.org${slug}`}
|
||||
property='og:url'
|
||||
/>
|
||||
<meta content={title} property='og:title' />
|
||||
<meta
|
||||
content={meta.description ? meta.description : ''}
|
||||
property='og:description'
|
||||
/>
|
||||
<meta
|
||||
content={meta.description ? meta.description : ''}
|
||||
name='description'
|
||||
/>
|
||||
<meta content={meta.featureImage} property='og:image' />
|
||||
</Helmet>
|
||||
<Breadcrumbs path={pathname} />
|
||||
{children}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
ArticleLayout.displayName = 'ArticleLayout';
|
||||
ArticleLayout.propTypes = propTypes;
|
||||
|
||||
export default ArticleLayout;
|
||||
|
||||
export const fragmentQuery = graphql`
|
||||
fragment ArticleLayout on MarkdownRemark {
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
frontmatter {
|
||||
title
|
||||
}
|
||||
}
|
||||
`;
|
|
@ -13,7 +13,7 @@ exports.createGuideArticlePages = createPage => ({
|
|||
node: {
|
||||
htmlAst,
|
||||
excerpt,
|
||||
fields: { slug },
|
||||
fields: { slug, component },
|
||||
id
|
||||
}
|
||||
}) => {
|
||||
|
@ -32,7 +32,13 @@ exports.createGuideArticlePages = createPage => ({
|
|||
|
||||
return createPage({
|
||||
path: `/guide${slug}`,
|
||||
component: guideArticle,
|
||||
component: !component
|
||||
? guideArticle
|
||||
: path.resolve(
|
||||
__dirname,
|
||||
'../../src/templates/Guide/components/',
|
||||
component
|
||||
),
|
||||
context: {
|
||||
id,
|
||||
meta
|
||||
|
|
Loading…
Reference in New Issue