Un generador de sitios estático con sede en Next.js
nextein es un envoltorio alrededor de next.js que le permite escribir sitios estáticos usando markdown y react .
NodeJS V10.X + es necesario para ejecutar los comandos nextein .
Si quieres saltar a un proyecto de inicio, consulte NextEin-Starter
Hay algunos pasos que debe seguir para poner en funcionamiento su sitio con nextein
Crea un proyecto:
mkdir my-sitecd my-sitenpm init -yInstalar dependencias
npm i nextein next react react-dom Agregue un archivo de configuración next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
} ) Crear pages/index.js
import React from 'react'
import { getPosts } from 'nextein/fetcher'
import Content from 'nextein/content'
export async function getStaticProps ( ) {
return {
props : {
posts : await getPosts ( )
}
}
}
export default function Index ( { posts } ) {
return (
< section >
{
posts . map ( post => < Content { ... post } /> )
}
</ section >
)
} ) Cree una entrada de Post markdown en la carpeta posts ( 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.
Agregue los scripts NPM para ejecutar el modo DEV a su package.json
"scripts" : {
"dev" : " next "
}Ejecutar el servidor de desarrollo
npm run dev Agregue otro script de NPM a su package.json Json para exportar el sitio
"scripts" : {
"dev" : " next " ,
"export" : " next build && next export "
}fetcherUse Fetcher para recuperar las publicaciones y datos de sus archivos de Markdown.
Los métodos getPostsFilterBy y getDataFilterBy en Fetcher permiten pasar las funciones de filtro. Por ejemplo, podemos usar el filtro inCategory para recuperar publicaciones en una categoría determinada:
import { getPostsFilterBy } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const blog = await getPostsFilterBy ( InCategory ( 'blog' ) ) getData y getDataFilterBy recuperarán solo los metadatos generados para entradas en lugar de todo el puesto.
El método fetcher es una forma conveniente de definir un filtro y luego usar los getPosts y getData con un filtro aplicado.
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const { getPosts } = fetcher ( InCategory ( 'blog' ) )
//...
const blog = await getPosts ( )Puede usar rutas dinámicas y funciones de generador estático (GetStaticProps y GetstaticPath) con métodos Fetcher.
Ejemplo para una ruta dinámica [name].js
import fetcher from 'nextein/fetcher'
const { getData , getPost } = fetcher ( /* filter */ )
export async function getStaticPaths ( ) {
const data = await getData ( )
return {
paths : data . map ( ( { name } ) => ( { params : { name } } ) ) ,
fallback : false
}
}
export async function getStaticProps ( { params } ) {
const post = await getPost ( params )
return { props : { post } }
}
export default function Post ( { post } ) {
//...
} Ejemplo para un [[...name]].js Ruta dinámica:
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
const { getData , getPosts , getPost } = fetcher ( inCategory ( 'guides' ) )
export async function getStaticPaths ( ) {
const data = await getData ( )
return {
paths : [ { params : { name : [ ] } } ,
... data . map ( ( { name } ) => ( { params : { name : [ name ] } } ) )
] ,
fallback : false
}
}
export async function getStaticProps ( { params } ) {
const posts = await getPosts ( )
const post = await getPost ( params ) // This can be null if not matching `...name`
return { props : { posts , post } }
}
export default function Guides ( { posts , post } ) {
//...
}inCategory(category, options)La función de filtro se aplicará a las publicaciones para recuperar las publicaciones en una categoría determinada.
category : {String} La categoría para filtrar los resultados.options : {Object} opcionalincludeSubCategories: Boolean verdadero para incluir publicaciones en subcategorías. Valor predeterminado: false Las categorías se resuelven por la estructura de la carpeta de forma predeterminada. Esto significa que una publicación ubicada en posts/categoryA/subOne tendrá una categoría categoryA/subOne a menos que especifique el nombre de la categoría en la zonda delantera.
import { getPosts } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const posts = await getPosts ( )
const homePosts = posts . filter ( inCategory ( 'home' ) )
Si desea recuperar todas las publicaciones en una determinada categoría, supongamos que categoryA que incluirá a todos los que subOne , use las opciones includeSubCategories: true .
import { inCategory } from 'nextein/filters'
const categoryAPosts = posts
. filter ( inCategory ( 'categoryA' , { includeSubCategories : true } ) )Content Componente para representar un objeto post . Este componente recibe el content de la publicación como una propiedad. Use la propiedad excerpt para renderizar solo el primer párrafo (esto es útil al representar una lista de publicaciones).
content : {Object} Markdown Content en formato Hast para ser renderizado. Esto es proporcionado por post.contentexcerpt : {Boolean} fiel a solo representar el primer párrafo. Opcional. Valor predeterminado: falserenderers : {Object} Un conjunto de renderistas personalizados para elementos de Markdown con la forma de [tagName]: renderer .component : {String|React.Component} El componente utilizado para el nodo raíz. import Content from 'nextein/content'
//...
export default function PostPage ( { post } ) {
return < Content { ... post } />
} Usar renderers para cambiar/diseñar la etiqueta <p>
const Paragraph = ( { children } ) => ( < p style = { { padding : 10 , background : 'silver' } } > { children } </ p > )
// Then in your render method ...
< Content
{ ... post }
renderers = { {
p : Paragraph
} }
/ >post__id es el identificador único generado por NextEin.data son el objeto Frontmatter que contiene la información posterior a la meta (título, página, categoría, etc.)data.category es la categoría de la publicación. Cuando no se especifica, si la publicación está dentro de una carpeta, se utilizará la estructura del directorio debajo de posts .data.date : JSON Fecha de la fecha o fecha de Frontmatter en el nombre del archivo o la fecha de creación del archivocontent es la representación del contenido post (generalmente en formato HAST) creado por el complemento de compilación para un MIMETYPE dado. { data , content } = post Solo hay unas pocas propiedades definidas en los metadatos de la redamatter que se usa por nextein
---
category : categoryOne
date : 2017-06-23
---
Post Content...
category : el nombre de la categoría (opcional)date : Cadena de fecha en formato A yyyy-MM-DD. Se usa para ordenar la lista de publicaciones. (opcional)published : Establecer en false para eliminar esta publicación de las entradas.name : Lea solo el nombre del archivo de publicación. La fecha se elimina del nombre si está presente.withNextein Una función de configuración de envoltura que se aplicará en el next.config.js . Proporciona una forma de agregar su propia configuración next.js junto con nextein Internal Next.js config.
next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
// Your own next.js config here
} ) También puede definir complementos NextEin utilizando la configuración withNextein :
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
nextein : {
plugins : [
//your nextein plugins here
]
}
// Your own next.js config here
} ) La configuración nextein.plugins acepta una matriz de complementos con los siguientes formatos:
[name] : solo una cadena para definir el complemento.[name, options] : una cadena para definir el objeto de opciones de complemento y complementos.{ name, id, options } : un objeto de complemento. Se requiere el campo name . Todas las definiciones anteriores se transforman en este formato. La id es opcional, cuando se proporciona, permite múltiples instancias del mismo complemento. El name del complemento debe ser un complemento preinstalado ( nextein-plugin-markdown ) o un archivo local ( ./myplugins/my-awesome-plugin )
La configuración predeterminada incluye:
plugins: [
[ 'nextein-plugin-source-fs' , { path : 'posts' , data : { page : 'post' } } ] ,
'nextein-plugin-markdown' ,
'nextein-plugin-filter-unpublished'
] Lea archivos del sistema de archivos.
Opciones:
path : ruta para leer archivos desde.data : los datos predeterminados se pasarán como adicionales para cada entrada. Predeterminado a {}includes : predeterminado a **/*.* .ignore : un conjunto de archivos ignorados. La lista predeterminada incluye: '**/.DS_Store' ,
'**/.gitignore' ,
'**/.npmignore' ,
'**/.babelrc' ,
'**/node_modules' ,
'**/yarn.lock' ,
'**/package-lock.json' Renderizar archivos de markdown.
Opciones:
raw : predeterminado a true . Haga esto false para no agregar el contenido raw en el objeto de publicación.position : predeterminado a false . Haga esto true para agregar la información de posición para publicar el contenido HAST.rehype : predeterminado a [] . Agregue un conjunto de complementos para rehyperemark : predeterminado a [] . Agregue un conjunto de complementos para remark Publicaciones de filtro utilizando una propiedad para evitar que se muestren entradas de borrador / no publicadas.
Opciones:
field : predeterminado a 'published' . Comprobará si un field está presente en data posteriores y se filtrará si se establece en false .Puedes escribir tus propios complementos. Básicamente hay 2 tipos diferentes (fuente y transformaciones). Se llamará a los complementos de origen para generar las entradas de publicaciones y luego los complementos de transformación recibirán esas entradas y podrán modificar, filtrar, agregar o transformar de todos modos la lista de publicaciones.
Consulte el documento de diseño de complementos y estilo de vida.