Un générateur de sites statique basé sur Next.js
nextein est un wrapper autour de next.js qui vous permet d'écrire des sites statiques en utilisant markdown et react .
Nodejs v10.x + est nécessaire pour exécuter les commandes nextein .
Si vous voulez sauter dans un projet de démarrage, vérifiez Nextein-Starter
Il y a quelques étapes à suivre pour mettre votre site opérationnel avec nextein
Créer un projet:
mkdir my-sitecd my-sitenpm init -yInstaller des dépendances
npm i nextein next react react-dom Ajouter un fichier de configuration next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
} ) Créer 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 >
)
} ) Créez une entrée de poste markdown dans le dossier 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.
Ajoutez des scripts NPM pour exécuter le mode Dev à votre package.json
"scripts" : {
"dev" : " next "
}Exécutez le serveur de développement
npm run dev Ajoutez un autre script NPM à votre package.json pour exporter le site
"scripts" : {
"dev" : " next " ,
"export" : " next build && next export "
}fetcherUtilisez Fettcher pour récupérer les publications et les données de vos fichiers Markdown.
Les méthodes getPostsFilterBy et getDataFilterBy dans Fetchher permet de passer les fonctions de filtre. Par exemple, nous pouvons utiliser le filtre inCategory pour récupérer les publications dans une catégorie donnée:
import { getPostsFilterBy } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const blog = await getPostsFilterBy ( InCategory ( 'blog' ) ) Le getData et getDataFilterBy ne récupéreront que les métadonnées générées pour les entrées au lieu de l'ensemble du message.
La méthode fetcher est un moyen pratique de définir un filtre, puis d'utiliser les getPosts et getData avec un filtre appliqué.
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const { getPosts } = fetcher ( InCategory ( 'blog' ) )
//...
const blog = await getPosts ( )Vous pouvez utiliser des routes dynamiques et des fonctions de générateur statique (getStaticProps et getStaticPaths) avec les méthodes de récupération.
Exemple pour une route dynamique [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 } ) {
//...
} Exemple pour un [[...name]].js Dynamic Route:
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)Filtre Fonction à appliquer aux publications pour récupérer les publications dans une catégorie donnée.
category : {String} La catégorie pour filtrer les résultats.options : {Object} FacultatifincludeSubCategories: Boolean est vrai pour inclure des publications dans les sous-catégories. Par défaut: false Les catégories sont résolues par la structure du dossier par défaut. Cela signifie qu'un message situé à posts/categoryA/subOne aura une catégorie categoryA/subOne à moins que vous ne spécifiez le nom de catégorie en frontmatter.
import { getPosts } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const posts = await getPosts ( )
const homePosts = posts . filter ( inCategory ( 'home' ) )
Si vous souhaitez récupérer tous les messages dans une certaine catégorie, disons categoryA qui inclura tous ceux sous subOne , utilisez les options includeSubCategories: true .
import { inCategory } from 'nextein/filters'
const categoryAPosts = posts
. filter ( inCategory ( 'categoryA' , { includeSubCategories : true } ) )Content Composant pour rendre un objet post . Ce composant reçoit le content de la publication en tant que propriété. Utilisez la propriété excerpt pour rendre uniquement le premier paragraphe (ceci est utile lors de la rendu d'une liste de messages).
content : {Object} Markdown Content au format hast pour être rendu. Ceci est fourni par post.contentexcerpt : {Boolean} fidèle à ne rendre que le premier paragraphe. Facultatif. Par défaut: falserenderers : {Object} Un ensemble de rendus personnalisés pour les éléments de marque avec la forme de [tagName]: renderer .component : {String|React.Component} Le composant utilisé pour le nœud racine. import Content from 'nextein/content'
//...
export default function PostPage ( { post } ) {
return < Content { ... post } />
} Utilisation renderers pour modifier / styliser la balise <p>
const Paragraph = ( { children } ) => ( < p style = { { padding : 10 , background : 'silver' } } > { children } </ p > )
// Then in your render method ...
< Content
{ ... post }
renderers = { {
p : Paragraph
} }
/ >post__id est l'identifiant unique généré par Nextein.data sont l'objet Frontmatter contiennent la méta-information du post (titre, page, catégorie, etc.)data.category est la catégorie du poste. Lorsqu'il n'est pas spécifié, si le poteau se trouve à l'intérieur d'un dossier, la structure du répertoire sous posts sera utilisée.data.date : JSON Date de la date ou de la date de Frontmatter dans le nom de fichier ou la date de création de fichierscontent est la représentation du contenu du post (généralement au format Hast) créé par le plugin de construction pour un mimétype donné. { data , content } = post Il n'y a que quelques propriétés définies dans les métadonnées de la masse qui est utilisée par nextein
---
category : categoryOne
date : 2017-06-23
---
Post Content...
category : le nom de la catégorie (facultatif)date : Date String au format Yyyy-MM-DD. Utilisé pour trier la liste des publications. (facultatif)published : réglé sur false pour supprimer ce message des entrées.name : lisez uniquement le nom du fichier post. La date est supprimée du nom si elle est présente.withNextein Une fonction de configuration de wrapper à appliquer sur le next.config.js . Il fournit un moyen d'ajouter votre propre configuration next.js avec nextein Internal Next.js Config.
Next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
// Your own next.js config here
} ) Vous pouvez également définir les plugins Nextein à l'aide de la configuration withNextein :
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
nextein : {
plugins : [
//your nextein plugins here
]
}
// Your own next.js config here
} ) La configuration nextein.plugins accepte un tableau de plugins avec les formats suivants:
[name] : Juste une chaîne pour définir le plugin.[name, options] : une chaîne pour définir le plugin et un objet Options Plugins.{ name, id, options } : un objet de plugin. Le champ name est requis. Toutes les définitoins précédentes sont transformées en ce format. L' id est facultatif, lorsqu'il est fourni permet plusieurs instances du même plugin. Le name du plugin doit être un plugin préinstallé ( nextein-plugin-markdown ), ou un fichier local ( ./myplugins/my-awesome-plugin )
La configuration par défaut comprend:
plugins: [
[ 'nextein-plugin-source-fs' , { path : 'posts' , data : { page : 'post' } } ] ,
'nextein-plugin-markdown' ,
'nextein-plugin-filter-unpublished'
] Lisez les fichiers à partir du système de fichiers.
Options:
path : chemin pour lire les fichiers de.data : les données par défaut à passer en plus pour chaque entrée. Par défaut à {}includes : par défaut à **/*.* .ignore : un ensemble de fichiers ignorés. La liste par défaut comprend: '**/.DS_Store' ,
'**/.gitignore' ,
'**/.npmignore' ,
'**/.babelrc' ,
'**/node_modules' ,
'**/yarn.lock' ,
'**/package-lock.json' Rendez les fichiers de marque.
Options:
raw : par défaut à true . Faites-le false pour ne pas ajouter le contenu raw dans l'objet post.position : par défaut à false . Rendez-le true pour ajouter les informations de position pour publier du contenu hast.rehype : par défaut à [] . Ajouter un ensemble de plugins pour rehyperemark : par défaut à [] . Ajouter un ensemble de plugins pour remark Filtrez les publications en utilisant une propriété pour empêcher l'affichage des entrées de brouillon / non publiées.
Options:
field : par défaut à 'published' . Vérifiera si un field est présent dans data post-données et filtre si elle est définie sur false .Vous pouvez écrire vos propres plugins. Il existe essentiellement 2 types différents (source et transforts). Les plugins source seront appelés pour générer les entrées de messages, puis les plugins de transformation recevront ces entrées et pourront modifier, filtrer, ajouter ou transformer de toute façon la liste des publications.
Voir Plugins & Lifecyle Design Document.