مولد موقع ثابت مقره في Next.js
nextein عبارة عن غلاف حول next.js يسمح لك بكتابة مواقع ثابتة باستخدام markdown و react .
مطلوب Nodejs v10.x + لتشغيل أوامر nextein .
إذا كنت ترغب في القفز إلى مشروع بداية ، تحقق من Nextein-Starter
هناك بعض الخطوات التي عليك اتباعها لتركيب موقعك وتشغيله مع nextein
إنشاء مشروع:
mkdir my-sitecd my-sitenpm init -yتثبيت التبعيات
npm i nextein next react react-dom إضافة ملف تكوين next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
} ) إنشاء 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 >
)
} ) قم بإنشاء إدخال منشور markdown ضمن مجلد 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.
أضف البرامج النصية NPM لتشغيل وضع dev إلى package.json الخاصة بك. json
"scripts" : {
"dev" : " next "
}قم بتشغيل خادم التطوير
npm run dev أضف نصًا آخر NPM إلى package.json الخاصة بك. json لتصدير الموقع
"scripts" : {
"dev" : " next " ,
"export" : " next build && next export "
}fetcherاستخدم Fetcher لاسترداد المنشورات والبيانات من ملفات Markdown.
تتيح أساليب getPostsFilterBy و getDataFilterBy في Fotcher تمرير وظائف المرشح. على سبيل المثال ، يمكننا استخدام مرشح inCategory لاسترداد المنشورات في فئة معينة:
import { getPostsFilterBy } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const blog = await getPostsFilterBy ( InCategory ( 'blog' ) ) سيقوم getData و getDataFilterBy باسترداد البيانات الوصفية التي تم إنشاؤها فقط للإدخالات بدلاً من المنشور بأكمله.
طريقة fetcher هي وسيلة مريحة لتحديد مرشح ثم استخدام getPosts و getData مع مرشح تطبيق.
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const { getPosts } = fetcher ( InCategory ( 'blog' ) )
//...
const blog = await getPosts ( )يمكنك استخدام الطرق الديناميكية ووظائف المولد الثابت (GetStaticProps و GetStaticPaths) مع طرق الإحضار.
مثال على المسار الديناميكي [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 } ) {
//...
} مثال على A [[...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)وظيفة التصفية المراد تطبيقها على المنشورات لاسترداد المنشورات في فئة معينة.
category : {String} الفئة لتصفية نتائج التصفية.options : {Object} اختياريincludeSubCategories: Boolean True لتضمين المنشورات في الفئات الفرعية. الافتراضي: false يتم حل الفئات بواسطة بنية المجلد بشكل افتراضي. هذا يعني أن المنشور الموجود في posts/categoryA/subOne سيكون له categoryA/subOne ما لم تحدد اسم الفئة في Frontmatter.
import { getPosts } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const posts = await getPosts ( )
const homePosts = posts . filter ( inCategory ( 'home' ) )
إذا كنت ترغب في استرداد جميع المنشورات ضمن فئة معينة ، فلنقول categoryA التي ستشمل كل تلك الموجودة تحت subOne ، وتشمل الخيارات includeSubCategories: true .
import { inCategory } from 'nextein/filters'
const categoryAPosts = posts
. filter ( inCategory ( 'categoryA' , { includeSubCategories : true } ) )Content مكون لتقديم كائن post . يتلقى هذا المكون content من المنشور كخاصية. استخدم الخاصية excerpt لتقديم الفقرة الأولى فقط (هذا مفيد عند تقديم قائمة بالوظائف).
content : {Object} محتوى Markdown بتنسيق Hast ليتم تقديمه. يتم توفير هذا بواسطة post.contentexcerpt : {Boolean} صحيح فقط لتقديم الفقرة الأولى. خياري. الافتراضي: falserenderers : {Object} مجموعة من العارضين المخصصين للعناصر المبرمة مع شكل [tagName]: renderer .component : {String|React.Component} المكون المستخدم لعقدة الجذر. import Content from 'nextein/content'
//...
export default function PostPage ( { post } ) {
return < Content { ... post } />
} استخدام renderers لتغيير/نمط علامة <p>
const Paragraph = ( { children } ) => ( < p style = { { padding : 10 , background : 'silver' } } > { children } </ p > )
// Then in your render method ...
< Content
{ ... post }
renderers = { {
p : Paragraph
} }
/ >post__id هو المعرف الفريد الذي تم إنشاؤه بواسطة Nextein.data هي كائن Frontmatter يحتوي على معلومات POST META (العنوان ، الصفحة ، الفئة ، إلخ)data.category هي فئة المنشور. عندما لم يتم تحديدها ، إذا كان المنشور داخل المجلد ، فسيتم استخدام بنية الدليل تحت posts .data.date : تاريخ JSON من تاريخ أو تاريخ Frontmatter في اسم الملف أو تاريخ إنشاء الملفcontent هو تمثيل للمحتوى المنشور (بشكل عام بتنسيق HAST) الذي تم إنشاؤه بواسطة المكون الإضافي للبناء لنموذج محدد معين. { data , content } = post لا يوجد سوى عدد قليل من الخصائص المحددة في بيانات تعريف الأمامية التي تستخدمها nextein
---
category : categoryOne
date : 2017-06-23
---
Post Content...
category : اسم الفئة (اختياري)date : سلسلة التاريخ بتنسيق yyyy-mm-dd. تستخدم لفرز قائمة المشاركات. (خياري)published : ضبط على false لإزالة هذا المنشور من الإدخالات.name : اقرأ فقط اسم ملف النشر. تتم إزالة التاريخ من الاسم إذا كانت موجودة.withNextein وظيفة تكوين الغلاف المراد تطبيقها في next.config.js . يوفر طريقة لإضافة تكوين next.js الخاص بك مع تكوين nextein Internal Next.js.
Next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
// Your own next.js config here
} ) يمكنك أيضًا تحديد المكونات الإضافية Nextein باستخدام تكوين withNextein :
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
nextein : {
plugins : [
//your nextein plugins here
]
}
// Your own next.js config here
} ) يقبل تكوين nextein.plugins مجموعة من الإضافات مع التنسيقات التالية:
[name] : مجرد سلسلة لتحديد البرنامج المساعد.[name, options] : سلسلة لتحديد المكون الإضافي وكائن خيارات الإضافات.{ name, id, options } : كائن إضافي. حقل name مطلوب. يتم تحويل جميع التعريف السابق إلى هذا التنسيق. id اختياري ، عند توفيره يتيح مثيلات متعددة من نفس البرنامج المساعد. يجب أن يكون name المكون الإضافي مكونًا إضافيًا تم تثبيته مسبقًا ( nextein-plugin-markdown ) ، أو ملف محلي ( ./myplugins/my-awesome-plugin )
يتضمن التكوين الافتراضي:
plugins: [
[ 'nextein-plugin-source-fs' , { path : 'posts' , data : { page : 'post' } } ] ,
'nextein-plugin-markdown' ,
'nextein-plugin-filter-unpublished'
] قراءة الملفات من نظام الملفات.
خيارات:
path : مسار لقراءة الملفات من.data : البيانات الافتراضية التي سيتم تمريرها على أنها إضافية لكل إدخال. الافتراضي لـ {}includes : الافتراضي إلى **/*.* .ignore : مجموعة من الملفات التي تم تجاهلها. تتضمن القائمة الافتراضية: '**/.DS_Store' ,
'**/.gitignore' ,
'**/.npmignore' ,
'**/.babelrc' ,
'**/node_modules' ,
'**/yarn.lock' ,
'**/package-lock.json' تقديم ملفات التخفيض.
خيارات:
raw : افتراضي إلى true . اجعل هذا false لعدم إضافة المحتوى raw في كائن البريد.position : افتراضي إلى false . اجعل هذا true لإضافة معلومات الموضع لنشر المحتوى.rehype : افتراضي لـ [] . أضف مجموعة من الإضافات rehyperemark : افتراضي لـ [] . أضف مجموعة من الإضافات remark تصفية منشورات باستخدام خاصية لمنع عرض المسودة / الإدخالات غير المنشورة.
خيارات:
field : افتراضي لـ 'published' . سوف تحقق مما إذا كان field موجودًا في data النشر وتصفية إذا تم تعيينه على false .يمكنك كتابة المكونات الإضافية الخاصة بك. هناك أساسان نوعان مختلفان (المصدر والتحويلات). سيتم استدعاء المكونات الإضافية المصدر لإنشاء إدخالات المنشورات ، ثم ستتلقى المكونات الإضافية Transform هذه الإدخالات ويمكنها تعديل أو تصفية أو إلحاق أو تحويل على أي حال قائمة المشاركات.
انظر المكونات الإضافية ووثائق تصميم Lifecyle.