github

elmasse / nextein

  • воскресенье, 9 июля 2017 г. в 03:13:08
https://github.com/elmasse/nextein


A static site generator based in Next.js



nextein

A static site generator based in Next.js

What is it?

nextein is a wrapper around next.js that allows you to write static sites using markdown and react.

Getting Started

There are a few steps you have to follow to get your site up and running with nextein

  • Create a project:

    • mkdir my-site
    • cd my-site
    • npm init -y
  • Install Dependencies

    • npm i nextein@beta next@beta react react-dom
  • Add a next.config.js config file

        const nexteinConfig = require('nextein/config').default
    
        module.exports = nexteinConfig({
    
        })
    
  • Create pages/index.js

        import React from 'react'
    
        import withPosts from 'nextein/posts'
        import { Content } from 'nextein/post'
    
        export default withPosts( ({ posts }) => {
            return (
                <section>
                {
                    posts.map(post => <Content {...post} />)
                }
                </section>
    
            )
        })
    
  • Create a markdown post entry under posts folder (posts/my-first-post.md)

    ---
    title: First Post
    category: post
    ---
    
    This is the first paragraph and it will be used as an excerpt when loaded in a `<Content excerpt />` tag.
    
    This paragraph should *not* appear in that list.
    
  • Add npm scripts to run dev mode to your package.json

    {
        "scripts": {
            "dev": "nextein"
        }
    }
  • Run the development server

  • Add another npm script to your package.json to export the site

    {
        "scripts": {
            "dev": "nextein",
            "export": "nextein build && nextein export"
        }
    }

Example

see nextein-example for a working example

Documentation

withPosts

HOC for /pages components that renders a list of posts. It makes the post list available thru the posts property.

import withPosts from 'nextein/posts'

export default withPosts( ({ posts }) => { /* render your posts here */ } )

inCategory(category)

Filter function to be applied to posts to retrieve posts in given category

import withPosts, { inCategory } from 'nextein/posts'

export default withPosts( ({ posts }) => { 
    const homePosts = posts.filter(inCategory('home'))
    /* render your homePosts here */ 
} )

sortByDate

Sort function to be applied to posts to sort by date (newest on top). This requires the post contains a date in frontmatter or in the file name (ala jekyll)

import withPosts, { sortByDate } from 'nextein/posts'

export default withPosts( ({ posts }) => { 
    posts.sort(sortByDate)
    /* render your posts here */ 
} )

withPost

HOC for /pages components that renders a single post. It makes the post available thru the post property.

import withPost from 'nextein/post'

export default withPost( ({ post }) => { /* render your post here */ } )

Content

Component to render a post object. This component receive the content from the post as a property. Use the excerpt property to only render the first paragraph (this is useful when rendering a list of posts).

  • content: {String} Markdown content to be render. This is provided by post.content
  • excerpt: {Boolean} true to only render the first paragraph. Optional
  • renderers: {Object} A set of custom renderers for Markdown elements.
import withPost, { Content } from 'nextein/post'

export default withPost( ({ post }) => { return (<Content {...post} />) } )

Using the excerpt property

import withPosts, {inCategory} from 'nextein/posts'

export default withPosts( ({ posts }) => { 
    const homePosts = posts.filter(inCategory('home'))
    return (
        <section>
        {
            homePosts.map( (post, idx) => <Content key={idx} {...post} excerpt/> )
        }
        </section>
    )
} )

Using renderers to change/style the <p> tag

export default withPost( ({ post }) => { 
    return (
        <Content {...post} 
            renderers={{
                p: Paragraph 
            }}
        />
    ) 
} )

const Paragraph = ({ children }) => (<p style={{padding:10, background: 'silver'}}> { children } </p> )

post

  • data is the frontmatter object containig the post meta information (title, page, category, etc)
    • data.url is the generated url for the post
    • data.category is the post's category
    • data.date: JSON date from frontmatter's date or date in file name or file creation date
  • content is markdown content of the post
{ data, content } = post

frontmatter

There are only a few defined properties in the frontmatter metadata that is used by nextein

---
page: my-awesome-post
category: categoryOne
slug: /posts/my-first-post
date: 2017-06-23

---

Post Content...
  • page: the component under /pages that will be used to render the post (default to post which reads /pages/post component) Note: If you have an entry that should not be rendered by its own page (such as a part of an index file only) use page: false to avoid generating the url and exporting entry.
  • category: the category name (optional)
  • slug: the post url (optional)
  • date: date string in YYYY-MM-DD format. Used to sort posts list. (optional)
  • published: Set to false to remove this post from entries.

nexteinConfig

A wrapper configuration function to be applied into the next.config.js. It provides a way to add your own next.js config along with nextein internal next.js config.

next.config.js

const nexteinConfig = require('nextein/config').default

module.exports = nexteinConfig({
    // Your own next.js config here
})