Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Netlify cms example #8949

Merged
merged 12 commits into from
Oct 19, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions examples/netlifycms/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# build output
dist
.next

# dependencies
node_modules
package-lock.json
yarn.lock
!/yarn.lock
test/node_modules

# logs & pids
*.log
pids

# coverage
.nyc_output
coverage

# test output
test/**/out*
test/**/next-env.d.ts
.DS_Store

# Editors
**/.idea

# example output
examples/**/out

38 changes: 38 additions & 0 deletions examples/netlifycms/components/layout/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import Link from 'next/link';

const Layout = ({ children }) => {
return (
<React.Fragment>
<nav>
<Link href={'/'}>
<a>home</a>
</Link>
<Link href={'/blog'}>
<a>blog</a>
</Link>
<Link href={'/about'}>
<a>about</a>
</Link>
</nav>
<main>{children}</main>
<style jsx global>{`
nav {
text-align: center;
}
nav a {
margin-right: 2px;

padding: 4px;
}

main {
display: flex;
flex-direction: column;
}
`}</style>
</React.Fragment>
);
};

export default Layout;
6 changes: 6 additions & 0 deletions examples/netlifycms/content/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: About
date: 2019-03-17T19:31:20.591Z
---

Welcome to example using nextjs and netlifycms
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: A blog post with picture of dog
date: 2019-09-06T08:28:44.549Z
thumbnail: /static/img/puppy-and-adult-dog.jpg
---

Unfortunately, that's it.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Why did the chicken cross the road
date: 2019-09-06T08:28:44.549Z
thumbnail: /static/img/1200px-whio_blue_duck_at_staglands_akatarawa_new_zealand.jpg
---

To get to the other side.

I know it's a picture of duck in thumbnail
10 changes: 10 additions & 0 deletions examples/netlifycms/content/home.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Home
date: 2019-03-17T19:31:20.591Z
---

### Sample netflifycms with next.js page

Look at the repository to check it out [link](https://github.com/masives/netlifycms-nextjs/tree/master/content/blogPosts)

Since only automatic static site generation and listing blogposts is different from documented tutorial I've not documented rest. You can find instructions [here](https://www.netlifycms.org/docs/nextjs/)
37 changes: 37 additions & 0 deletions examples/netlifycms/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const fs = require('fs')
const blogPostsFolder = './content/blogPosts'

const getPathsForPosts = () => {
return fs
.readdirSync(blogPostsFolder)
.map(blogName => {
const trimmedName = blogName.substring(0, blogName.length - 3)
return {
[`/blog/post/${trimmedName}`]: {
page: '/blog/post/[slug]',
query: {
slug: trimmedName
}
}
}
})
.reduce((acc, curr) => {
return { ...acc, ...curr }
}, {})
}

module.exports = {
webpack: configuration => {
configuration.module.rules.push({
test: /\.md$/,
use: 'frontmatter-markdown-loader'
})
return configuration
},
async exportPathMap (defaultPathMap) {
return {
...defaultPathMap,
...getPathsForPosts()
}
}
}
23 changes: 23 additions & 0 deletions examples/netlifycms/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "nextjs-netlifycms",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"export": "npm run build && next export"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"next": "^9.0.5",
"react": "^16.9.0",
"react-dom": "^16.9.0"
},
"devDependencies": {
"frontmatter-markdown-loader": "^2.0.0"
}
}
15 changes: 15 additions & 0 deletions examples/netlifycms/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import App from 'next/app'
import Layout from '../components/layout'

export default class MyApp extends App {
render () {
const { Component, pageProps } = this.props

return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
}
20 changes: 20 additions & 0 deletions examples/netlifycms/pages/about/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'

import content from '../../content/about.md'

const About = () => {
const { attributes, html } = content
return (
<React.Fragment>
<h1>{attributes.title}</h1>
<div dangerouslySetInnerHTML={{ __html: html }} />
<style jsx>{`
h1,
div {
text-align: center;
}
`}</style>
</React.Fragment>
)
}
export default About
53 changes: 53 additions & 0 deletions examples/netlifycms/pages/blog/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { Component } from 'react'
import Link from 'next/link'

const importBlogPosts = async () => {
// https://medium.com/@shawnstern/importing-multiple-markdown-files-into-a-react-component-with-webpack-7548559fce6f
// second flag in require.context function is if subdirectories should be searched
const markdownFiles = require
.context('../../content/blogPosts', false, /\.md$/)
.keys()
.map(relativePath => relativePath.substring(2))
return Promise.all(
markdownFiles.map(async path => {
const markdown = await import(`../../content/blogPosts/${path}`)
return { ...markdown, slug: path.substring(0, path.length - 3) }
})
)
}

export default class Blog extends Component {
static async getInitialProps () {
const postsList = await importBlogPosts()

return { postsList }
}
render () {
const { postsList } = this.props
return (
<div className='blog-list'>
{postsList.map(post => {
return (
<Link href={`blog/post/${post.slug}`}>
<a>
<img src={post.attributes.thumbnail} />
<h2>{post.attributes.title}</h2>
</a>
</Link>
)
})}
<style jsx>{`
.blog-list a {
display: block;
text-align: center;
}
.blog-list img {
max-width: 100%;

max-height: 300px;
}
`}</style>
</div>
)
}
}
38 changes: 38 additions & 0 deletions examples/netlifycms/pages/blog/post/[slug].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { Component } from 'react';

class Post extends Component {
static async getInitialProps({ query }) {
const { slug } = query;
const blogpost = await import(`../../../content/blogPosts/${slug}.md`).catch(error => null);

return { blogpost };
}
render() {
if (!this.props.blogpost) return <div>not found</div>;

const {
html,
attributes: { thumbnail, title },
} = this.props.blogpost.default;

return (
<>
<article>
<h1>{title}</h1>
<img src={thumbnail} />
<div dangerouslySetInnerHTML={{ __html: html }} />
</article>
<style jsx>{`
article {
margin: 0 auto;
}
h1 {
text-align: center;
}
`}</style>
</>
);
}
}

export default Post;
21 changes: 21 additions & 0 deletions examples/netlifycms/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { Component } from 'react'

import content from '../content/home.md'

export default class Home extends Component {
render () {
const { attributes, html } = content
return (
<React.Fragment>
<h1>{attributes.title}</h1>
<div dangerouslySetInnerHTML={{ __html: html }} />
<style jsx>{`
h1,
div {
text-align: center;
}
`}</style>
</React.Fragment>
)
}
}
51 changes: 51 additions & 0 deletions examples/netlifycms/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Example app using Netlify CMS

## How to use

### Using `create-next-app`

Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:

```bash
npx create-next-app --example netlifycms netlifycms-app
# or
yarn create next-app --example netlifycms netlifycms-app
```

### Download manually

Download the example:

```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/netlifycms
cd nested-components
```

Install it and run:

```bash
npm install
npm run dev
# or
yarn
yarn dev
```

Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))

```bash
now
```

## The idea behind the example

[Netlify CMS](https://www.netlifycms.org/) is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflows. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git.

## How it works

Sites take its content from markdown files in `/content`. Two of pages (`home` and `about`) are referencing directly their respective markdown files.

Blog component loads all posts (during build!) and lists them out [How to load multiple md files](https://medium.com/@shawnstern/importing-multiple-markdown-files-into-a-react-component-with-webpack-7548559fce6f)

Posts are separate static sites thanks to dynamically created export map. I took inspiration on how to do it from
[here](https://medium.com/@joranquinten/for-my-own-website-i-used-next-js-725678e65b09)
Loading