chore: add website preview templates (#1716)
This commit is contained in:
parent
9b18596fa2
commit
4fadf3fdb6
@ -60,6 +60,12 @@ module.exports = {
|
|||||||
'gatsby-plugin-postcss',
|
'gatsby-plugin-postcss',
|
||||||
'gatsby-plugin-react-helmet',
|
'gatsby-plugin-react-helmet',
|
||||||
'gatsby-plugin-catch-links',
|
'gatsby-plugin-catch-links',
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-netlify-cms',
|
||||||
|
options: {
|
||||||
|
modulePath: `${__dirname}/src/cms/cms.js`,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
resolve: `gatsby-plugin-manifest`,
|
resolve: `gatsby-plugin-manifest`,
|
||||||
options: {
|
options: {
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
|
"dayjs": "^1.7.5",
|
||||||
"gatsby": "next",
|
"gatsby": "next",
|
||||||
"gatsby-plugin-catch-links": "next",
|
"gatsby-plugin-catch-links": "next",
|
||||||
"gatsby-plugin-manifest": "next",
|
"gatsby-plugin-manifest": "next",
|
||||||
|
"gatsby-plugin-netlify-cms": "^3.0.0-rc.1",
|
||||||
"gatsby-plugin-postcss": "^1.0.0",
|
"gatsby-plugin-postcss": "^1.0.0",
|
||||||
"gatsby-plugin-react-helmet": "next",
|
"gatsby-plugin-react-helmet": "next",
|
||||||
"gatsby-remark-autolink-headers": "next",
|
"gatsby-remark-autolink-headers": "next",
|
||||||
@ -26,13 +28,14 @@
|
|||||||
"gatsby-transformer-json": "next",
|
"gatsby-transformer-json": "next",
|
||||||
"gatsby-transformer-remark": "next",
|
"gatsby-transformer-remark": "next",
|
||||||
"gatsby-transformer-yaml": "next",
|
"gatsby-transformer-yaml": "next",
|
||||||
|
"netlify-cms": "^2.0.11",
|
||||||
"postcss-at2x": "^2.0.0",
|
"postcss-at2x": "^2.0.0",
|
||||||
"postcss-cssnext": "^2.7.0",
|
"postcss-cssnext": "^2.7.0",
|
||||||
"postcss-neat": "^2.5.2",
|
"postcss-neat": "^2.5.2",
|
||||||
"postcss-nested": "^1.0.0",
|
"postcss-nested": "^1.0.0",
|
||||||
"postcss-simple-extend": "^1.0.0",
|
"postcss-simple-extend": "^1.0.0",
|
||||||
"postcss-simple-vars-async": "^1.2.1",
|
"postcss-simple-vars-async": "^1.2.1",
|
||||||
"prismjs": "^1.14.0",
|
"prismjs": "^1.15.0",
|
||||||
"react": "^16.4.2",
|
"react": "^16.4.2",
|
||||||
"react-dom": "^16.4.2",
|
"react-dom": "^16.4.2",
|
||||||
"react-helmet": "^5.2.0",
|
"react-helmet": "^5.2.0",
|
||||||
|
56
website/src/cms/cms.js
Normal file
56
website/src/cms/cms.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import CMS from 'netlify-cms';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { BlogPostTemplate } from '../templates/blog-post';
|
||||||
|
import { DocsTemplate } from '../templates/doc-page';
|
||||||
|
import Release from '../components/release';
|
||||||
|
import WhatsNew from '../components/whats-new';
|
||||||
|
import Notification from '../components/notification';
|
||||||
|
import '../css/lib/prism.css';
|
||||||
|
import '../css/imports/docs.css';
|
||||||
|
import '../css/imports/whatsnew.css';
|
||||||
|
import '../css/imports/header.css';
|
||||||
|
|
||||||
|
const BlogPostPreview = ({ entry, widgetFor }) => {
|
||||||
|
const data = entry.get('data');
|
||||||
|
return (
|
||||||
|
<BlogPostTemplate
|
||||||
|
title={data.get('title')}
|
||||||
|
author={data.get('author')}
|
||||||
|
date={dayjs(data.get('date')).format('MMMM D, YYYY')}
|
||||||
|
body={widgetFor('body')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DocsPreview = ({ entry, widgetFor }) => (
|
||||||
|
<DocsTemplate title={entry.getIn(['data', 'title'])} body={widgetFor('body')} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const ReleasePreview = ({ entry }) => (
|
||||||
|
<WhatsNew>
|
||||||
|
{entry.getIn(['data', 'updates']).map((release, idx) => (
|
||||||
|
<Release
|
||||||
|
key={idx}
|
||||||
|
version={release.get('version')}
|
||||||
|
date={dayjs(release.get('date')).format('MMMM D, YYYY')}
|
||||||
|
description={release.get('description')}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</WhatsNew>
|
||||||
|
);
|
||||||
|
|
||||||
|
const NotificationPreview = ({ entry }) =>
|
||||||
|
entry
|
||||||
|
.getIn(['data', 'notifications'])
|
||||||
|
.filter(notif => notif.get('published'))
|
||||||
|
.map((notif, idx) => (
|
||||||
|
<Notification key={idx} url={notif.get('url')} loud={notif.get('loud')}>
|
||||||
|
{notif.get('message')}
|
||||||
|
</Notification>
|
||||||
|
));
|
||||||
|
|
||||||
|
CMS.registerPreviewTemplate('blog', BlogPostPreview);
|
||||||
|
CMS.registerPreviewTemplate('docs', DocsPreview);
|
||||||
|
CMS.registerPreviewTemplate('releases', ReleasePreview);
|
||||||
|
CMS.registerPreviewTemplate('notifications', NotificationPreview);
|
@ -1,10 +1,10 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import classnames from 'classnames';
|
|
||||||
import { graphql, StaticQuery } from 'gatsby';
|
import { graphql, StaticQuery } from 'gatsby';
|
||||||
|
|
||||||
import Header from './header';
|
import Header from './header';
|
||||||
import Footer from './footer';
|
import Footer from './footer';
|
||||||
|
import Notification from './notification';
|
||||||
|
|
||||||
import '../css/imports/base.css';
|
import '../css/imports/base.css';
|
||||||
import '../css/imports/utilities.css';
|
import '../css/imports/utilities.css';
|
||||||
@ -54,15 +54,9 @@ const Layout = ({ children }) => {
|
|||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
{notifs.map((node, i) => (
|
{notifs.map((node, i) => (
|
||||||
<a
|
<Notification key={i} url={node.url} loud={node.loud}>
|
||||||
key={i}
|
|
||||||
href={node.url}
|
|
||||||
className={classnames('notification', {
|
|
||||||
'notification-loud': node.loud,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{node.message}
|
{node.message}
|
||||||
</a>
|
</Notification>
|
||||||
))}
|
))}
|
||||||
<Header notifications={notifs} />
|
<Header notifications={notifs} />
|
||||||
{children}
|
{children}
|
||||||
|
10
website/src/components/notification.js
Normal file
10
website/src/components/notification.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import cn from 'classnames';
|
||||||
|
|
||||||
|
const Notification = ({ url, loud, children }) => (
|
||||||
|
<a href={url} className={cn('notification', { 'notification-loud': loud })}>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Notification;
|
18
website/src/components/release.js
Normal file
18
website/src/components/release.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Markdownify from '../components/markdownify';
|
||||||
|
|
||||||
|
const Release = ({ version, date, description }) => (
|
||||||
|
<a href={`https://github.com/netlify/netlify-cms/releases/tag/${version}`} key={version}>
|
||||||
|
<li>
|
||||||
|
<div className="update-metadata">
|
||||||
|
<span className="update-version">{version}</span>
|
||||||
|
<span className="update-date">{date}</span>
|
||||||
|
</div>
|
||||||
|
<span className="update-description">
|
||||||
|
<Markdownify source={description} />
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Release;
|
11
website/src/components/whats-new.js
Normal file
11
website/src/components/whats-new.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const WhatsNew = ({ children }) => (
|
||||||
|
<section className="whatsnew">
|
||||||
|
<div className="contained">
|
||||||
|
<ol>{children}</ol>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default WhatsNew;
|
@ -1,10 +1,12 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { graphql } from 'gatsby';
|
import { graphql } from 'gatsby';
|
||||||
|
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
import Markdownify from '../components/markdownify';
|
import Markdownify from '../components/markdownify';
|
||||||
import VideoEmbed from '../components/video-embed';
|
import VideoEmbed from '../components/video-embed';
|
||||||
|
import WhatsNew from '../components/whats-new';
|
||||||
|
import Release from '../components/release';
|
||||||
|
|
||||||
import '../css/imports/hero.css';
|
import '../css/imports/hero.css';
|
||||||
import '../css/imports/cta.css';
|
import '../css/imports/cta.css';
|
||||||
@ -12,9 +14,8 @@ import '../css/imports/whatsnew.css';
|
|||||||
import '../css/imports/editors.css';
|
import '../css/imports/editors.css';
|
||||||
import '../css/imports/community.css';
|
import '../css/imports/community.css';
|
||||||
|
|
||||||
const Features = ({ items }) => (
|
const Features = ({ items }) =>
|
||||||
<Fragment>
|
items.map(item => (
|
||||||
{items.map(item => (
|
|
||||||
<div className="feature" key={item.feature}>
|
<div className="feature" key={item.feature}>
|
||||||
{item.imgpath && <img src={require(`../img/${item.imgpath}`)} />}
|
{item.imgpath && <img src={require(`../img/${item.imgpath}`)} />}
|
||||||
<h3>
|
<h3>
|
||||||
@ -24,9 +25,7 @@ const Features = ({ items }) => (
|
|||||||
<Markdownify source={item.description} />
|
<Markdownify source={item.description} />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
));
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
|
|
||||||
const HomePage = ({ data }) => {
|
const HomePage = ({ data }) => {
|
||||||
const landing = data.landing.childDataYaml;
|
const landing = data.landing.childDataYaml;
|
||||||
@ -68,30 +67,16 @@ const HomePage = ({ data }) => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="whatsnew">
|
<WhatsNew>
|
||||||
<div className="contained">
|
{updates.updates.slice(0, 3).map((node, idx) => (
|
||||||
<ol>
|
<Release
|
||||||
{updates.updates.slice(0, 3).map(node => (
|
key={idx}
|
||||||
<a
|
version={node.version}
|
||||||
href={`https://github.com/netlify/netlify-cms/releases/tag/${node.version}`}
|
date={moment(node.date).format('MMMM D, YYYY')}
|
||||||
key={node.version}
|
description={node.description}
|
||||||
>
|
/>
|
||||||
<li>
|
|
||||||
<div className="update-metadata">
|
|
||||||
<span className="update-version">{node.version}</span>
|
|
||||||
<span className="update-date">
|
|
||||||
{moment(node.date).format('MMMM D, YYYY')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span className="update-description">
|
|
||||||
<Markdownify source={node.description} />
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</a>
|
|
||||||
))}
|
))}
|
||||||
</ol>
|
</WhatsNew>
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="editors">
|
<section className="editors">
|
||||||
<div className="contained">
|
<div className="contained">
|
||||||
|
@ -4,6 +4,22 @@ import { graphql } from 'gatsby';
|
|||||||
|
|
||||||
import Layout from '../components/layout';
|
import Layout from '../components/layout';
|
||||||
|
|
||||||
|
export const BlogPostTemplate = ({ title, author, date, body, html }) => (
|
||||||
|
<div className="docs page">
|
||||||
|
<div className="container">
|
||||||
|
<article className="blog-content" id="blog-content">
|
||||||
|
<div className="blog-post-header">
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<p className="meta-info">
|
||||||
|
by {author} on {date}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const BlogPost = ({ data }) => {
|
const BlogPost = ({ data }) => {
|
||||||
const { html, frontmatter } = data.markdownRemark;
|
const { html, frontmatter } = data.markdownRemark;
|
||||||
const { author, title, date, description, meta_description } = frontmatter;
|
const { author, title, date, description, meta_description } = frontmatter;
|
||||||
@ -12,23 +28,11 @@ const BlogPost = ({ data }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className="docs page">
|
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
{desc && <meta name="description" content={desc} />}
|
{desc && <meta name="description" content={desc} />}
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<div className="container">
|
<BlogPostTemplate title={title} author={author} date={date} html={html} />
|
||||||
<article className="blog-content" id="blog-content">
|
|
||||||
<div className="blog-post-header">
|
|
||||||
<h1>{title}</h1>
|
|
||||||
<p className="meta-info">
|
|
||||||
by {author} on {date}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div dangerouslySetInnerHTML={{ __html: html }} />
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,38 @@ const toMenu = (menu, nav) =>
|
|||||||
group: nav.group.find(g => g.fieldValue === group.name),
|
group: nav.group.find(g => g.fieldValue === group.name),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const DocsSidebar = ({ docsNav, location, history }) => (
|
||||||
|
<aside id="sidebar" className="sidebar">
|
||||||
|
<DocsNav items={docsNav} location={location} />
|
||||||
|
<MobileNav items={docsNav} history={history} />
|
||||||
|
</aside>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const DocsTemplate = ({
|
||||||
|
title,
|
||||||
|
editLinkPath,
|
||||||
|
body,
|
||||||
|
html,
|
||||||
|
showWidgets,
|
||||||
|
widgets,
|
||||||
|
showSidebar,
|
||||||
|
docsNav,
|
||||||
|
location,
|
||||||
|
history,
|
||||||
|
}) => (
|
||||||
|
<div className="docs detail page">
|
||||||
|
<div className="container">
|
||||||
|
{showSidebar && <DocsSidebar docsNav={docsNav} location={location} history={history} />}
|
||||||
|
<article className="docs-content" id="docs-content">
|
||||||
|
{editLinkPath && <EditLink path={editLinkPath} />}
|
||||||
|
<h1>{title}</h1>
|
||||||
|
{body ? body : <div dangerouslySetInnerHTML={{ __html: html }} />}
|
||||||
|
{showWidgets && <Widgets widgets={widgets} />}
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const DocPage = ({ data, location, history }) => {
|
const DocPage = ({ data, location, history }) => {
|
||||||
const { nav, page, widgets, menu } = data;
|
const { nav, page, widgets, menu } = data;
|
||||||
|
|
||||||
@ -25,21 +57,18 @@ const DocPage = ({ data, location, history }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className="docs detail page">
|
|
||||||
<Helmet title={page.frontmatter.title} />
|
<Helmet title={page.frontmatter.title} />
|
||||||
<div className="container">
|
<DocsTemplate
|
||||||
<aside id="sidebar" className="sidebar">
|
title={page.frontmatter.title}
|
||||||
<DocsNav items={docsNav} location={location} />
|
editLinkPath={page.fields.path}
|
||||||
<MobileNav items={docsNav} history={history} />
|
html={page.html}
|
||||||
</aside>
|
showWidgets={showWidgets}
|
||||||
<article className="docs-content" id="docs-content">
|
widgets={widgets}
|
||||||
<EditLink path={page.fields.path} />
|
docsNav={docsNav}
|
||||||
<h1>{page.frontmatter.title}</h1>
|
location={location}
|
||||||
<div dangerouslySetInnerHTML={{ __html: page.html }} />
|
history={history}
|
||||||
{showWidgets && <Widgets widgets={widgets} />}
|
showSidebar
|
||||||
</article>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ collections: # A list of collections the CMS should be able to edit
|
|||||||
- name: "blog"
|
- name: "blog"
|
||||||
label: "Blog"
|
label: "Blog"
|
||||||
label_singular: "Post"
|
label_singular: "Post"
|
||||||
folder: "website/site/content/blog"
|
folder: "website/content/blog"
|
||||||
create: true
|
create: true
|
||||||
fields:
|
fields:
|
||||||
- {label: "Title", name: "title", widget: "string", tagname: "h1"}
|
- {label: "Title", name: "title", widget: "string", tagname: "h1"}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
|
|
||||||
<title>Content Manager</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="https://unpkg.com/netlify-cms/dist/netlify-cms.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
1338
website/yarn.lock
1338
website/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user