const fs = require('fs-extra');
const path = require('path');
const glob = require('glob');
const Post = require('./post');
const art = require('art-template');
const { copyFile, writeFile } = require('./writeFile');
/**
* 页面类 /page/*
* @description
* 创建一个页面需要
* - 模板
* - 模板目录
* - 页面配置
* - 分页配置
* - 底部配置
* - 侧边栏配置
* - 页面基础信息配置
* - 内容
* - 文章列表或文章全文
* - 侧边栏或带有目录的侧边栏
* - 底部
* - 输出目录
*/
class Page {
constructor(mdDir, pageConfig) {
if (!mdDir) {
throw new Error('create new Page need mdDir');
}
this.categories = {};
this.tags = {};
this.mdDir = mdDir;
this.pageConfig = pageConfig;
}
// private
// 分页
_sliceList(postList) {
const pageSize = this.pageConfig.pageSize;
const slicedFiles = [];
let slicingFiles = postList;
for (let i = 1; i <= Math.ceil(postList.length / pageSize); i++) {
slicedFiles.push(slicingFiles.slice(0, pageSize));
slicingFiles = slicingFiles.slice(pageSize);
}
return slicedFiles;
}
//读取文章
_loadMd() {
const mdFiles = glob.sync('**/*.md', { cwd: this.mdDir });
this.mdList = mdFiles.filter((item) => item !== 'about.md');
}
// 分页器
_renderPagination(pageCount, current) {
const pages = new Array(pageCount).fill(0).map((_item, index) => {
return {
key: index + 1,
isCurrent: index + 1 === current,
href: `/page/${index + 1}`,
};
});
const prevPage = {
key: '上一页',
isCurrent: false,
href: `/page/${current - 1}`,
isPrev: true,
};
const nextPage = {
key: '下一页',
isCurrent: false,
href: `/page/${current + 1}`,
isNext: true,
};
if (pageCount === 1) {
return pages;
}
if (current === 1) {
return [...pages, nextPage];
}
if (current === pageCount) {
return [prevPage, ...pages];
}
return [prevPage, ...pages, nextPage];
}
// 侧边栏统计
_renderCategoryAndTag(md) {
const post = new Post(this.mdDir, md);
const { category, tags } = post.front;
// 记录分类和标签
this.categories[category]
? this.categories[category]++
: (this.categories[category] = 1);
tags?.forEach((tag) => {
this.tags[tag] ? this.tags[tag]++ : (this.tags[tag] = 1);
});
}
// 文章列表
_renderPostList(sidebar, list) {
const sortByTime = (a, b) => {
return b.createTime.getTime() - a.createTime.getTime();
};
return list
.map((item) => {
const post = new Post(this.mdDir, item, this.pageConfig.outputDir);
const postHtml = post
.loadConfig(this.pageConfig)
.loadTemplate({
layoutTemplate: this.layoutTemplate,
postTemplate: this.postTemplate,
itemTemplate: this.postItemTemplate,
})
.loadSidebar({
sidebarTemplate: this.sidebarTemplate,
sidebarData: sidebar,
})
.loadFooter({
footerTemplate: this.footerTemplate,
footerData: this.pageConfig.footerConfig,
})
.build();
return { postHtml, createTime: new Date(post.front.date) };
})
.sort(sortByTime);
}
// 侧边栏
_renderSidebar() {
const { sidebarConfig } = this.pageConfig;
const getCountByName = {
categories: Object.keys(this.categories).length,
tags: Object.keys(this.tags).length,
archives: this.postCount,
};
sidebarConfig.nav = sidebarConfig.nav.map((item) => ({
label: item.label,
url: item.url,
count: getCountByName[item.name],
}));
return sidebarConfig;
}
_render() {
this._loadMd();
this.mdList.forEach((mds) => this._renderCategoryAndTag(mds));
this.postCount = this.mdList.length;
const sidebarData = this._renderSidebar();
this.sidebarData = sidebarData;
const postLists = this._sliceList(
this._renderPostList(sidebarData, this.mdList)
);
const pageCount = postLists.length;
return postLists.map((postList, index) => {
return art.render(this.pageTemplate, {
layout: this.layoutTemplate,
title: this.pageConfig.title,
author: this.pageConfig.author,
description: this.pageConfig.description,
codeTheme: this.pageConfig.codeTheme,
postList: this.postListTemplate,
postData: {
posts: postList,
pagination: this._renderPagination(pageCount, index + 1),
},
sidebar: this.sidebarTemplate,
sidebarData,
footer: this.footerTemplate,
footerData: this.pageConfig.footerConfig,
links: this.pageConfig.sidebarConfig.links,
});
});
}
_buildAssets() {
copyFile(
path.join(this.templateBaseDir, 'assets'),
path.join(this.pageConfig.outputDir, 'assets')
);
}
// public
loadTemplate(templateConfig) {
this.templateBaseDir = templateConfig.templateBaseDir;
this.postItemTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.postItemTemplate
);
this.postListTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.postListTemplate
);
this.sidebarTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.sidebarTemplate
);
this.layoutTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.layoutTemplate
);
this.footerTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.footerTemplate
);
this.postTemplate = path.join(
templateConfig.templateBaseDir,
templateConfig.postTemplate
);
this.pageTemplate = fs.readFileSync(
path.join(templateConfig.templateBaseDir, templateConfig.pageTemplate),
'utf-8'
);
return this;
}
build() {
const pagesHtml = this._render();
this._buildAssets();
pagesHtml.forEach((pageHtml, index) => {
// 第一页时需要同时渲染index和page/1
if (index === 0) {
writeFile(path.join(this.pageConfig.outputDir, 'index.html'), pageHtml);
}
writeFile(
path.join(this.pageConfig.outputDir, `page/${index + 1}`, 'index.html'),
pageHtml
);
});
}
}
module.exports = Page;
没有合适的资源?快使用搜索试试~ 我知道了~
基于nodejs的静态网页生成器源码+项目说明.zip

共53个文件
js:19个
css:10个
art:10个

1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 78 浏览量
2022-12-17
23:19:22
上传
评论
收藏 525KB 7Z 举报
温馨提示
基于nodejs的静态网页生成器源码+项目说明.zip 一个基于nodejs的静态博客生成器 安装 CoinRailgun npm install -g coinrailgun 初始化博客 crn init blog cd blog 创建新的文章 crn new "Hello CRN" 生成静态文件 crn build 本地运行网站 crn server 执行crn init后生成的site.config.json中会有下方为展示出来的配置项,那些配置项暂时未无用配置 【特别强调】 1、csdn上资源保证是完整最新,会不定期更新优化; 2、请用自己的账号在csdn官网下载,若通过第三方代下,博主不对您下载的资源作任何保证,且不提供任何形式的技术支持和答疑!!!
资源推荐
资源详情
资源评论
























收起资源包目录




































































共 53 条
- 1
资源评论


onnx
- 粉丝: 1w+
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 2018最新购物网站横幅标语.doc
- 网络对大学生学习生活的影响的调查报告.doc
- 高速公路项目管理要点.doc
- 集团公司网络安全解决方案.doc
- 高校网络工程方案.doc
- 综述税务管理的信息化建立【精品发布】.doc
- 空间数据组织算法.pptx
- 基于VB的道路曲线程序设计.doc
- 网络运维管理系统投标方案.docx
- 中专电子商务实习报告.doc
- 基于STM32的数码相框系统设计与实现软件毕业论文.doc
- 西门子PLC控制系统接线方式与编程.ppt
- 第九讲:NoteExpress文献管理软件.ppt
- 通信工程施工质量监理现场作业指导书.doc
- 通信行业个人工作总结.doc
- 基于网络评价的高星级酒店顾客服务质量感知研究模板.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
