never-write
Version:
simple static site generator
274 lines (219 loc) • 6.02 kB
Markdown
# never-write
🇨🇳[中文](https://github.com/hiNISAL/never-write#never-wirte) | [ENGLISH](https://github.com/hiNISAL/never-write/blob/main/readme-en.md)
`never-write` is a static site generator by `markdown`.
<img width="100%" src="https://github.com/hiNISAL/never-write/blob/main/assets/preview.png" />
## INSTALL
```shell
npm i never-write -g
```
## USAGE
```shell
# initialize, must in an empty dir.
neverw --init
# generate
neverw build
```
## NEVERW --INIT
`neverw --init` will generate a base template.
```shell
# all article write in this dir
- posts/
# static resource
- public/
# config file
- never-write.yaml
```
all articles(markdown file) write in `posts` dir.
can change the root by config(build.postsRootPath).
## never-write.yaml
the root has `never-write.yaml` mean its a site will handler by never-write.
```yaml
site:
name: site name
desc: site description
build:
outDir: output dir
publicPath: base URL that app will be deployed at
postsRootPath: markdown files root
publicResourcePath: static resources, will copy to `outDir`
hook: hooks file dir
htmlMinify: minify output html
render:
# or given one of string 'cactus-dark'|'plain'|'plain-dark'
template:
index: indexes page template
post: post page template
tagIndexes: tags indexes page
pageSize: indexes page post size
dateFormatter: `never-write` will pre handler some date, then pipe to ejs to use, this options is the date formatter
summaryLength: summary split length
footerText: text at foot, support html
```
default config:
```yaml
site:
name:
desc:
build:
outDir: ./dist
publicPath: /
postsRootPath: ./posts
publicResourcePath: ./public
htmlMinify: true,
hook:
render:
template: cactus-dark
pageSize: 15
dateFormatter: YYYY/MM/DD hh:mm:ss
summaryLength: 100
footerText:
```
## TIPS
- all path need be relative from root
## custom theme/style/template
the template engined by ejs, in build stage, `never-write` will given some options to template, then generate the static page.
so if need custom the theme, just use options `render.template`, given it a ejs template.
sample:[https://github.com/hiNISAL/never-write/blob/main/templates/theme/plain-dark/index.html](https://github.com/hiNISAL/never-write/blob/main/templates/theme/plain-dark/index.html)
### EJS OPTIONS
for post page:
```ts
interface PostOptions {
// markdown file header yaml config
meta: Record<string, any>.
// the path jointed public path
staticPath: string;
// the relative path in site
relativePath: string;
// markdown file stats
sourceFileStat: fs.Stats;
// saved file name
filename: string;
// saved file name without ext
filenameWithoutExt: string;
// the site option in never-write.yaml
site: { name: string; desc: string };
// parsed markdown
html: string;
// markdown content without tag
text: string;
// post summary, the length decide from config(render.summaryLength)
summary: string;
// the date format from render.dateFormatter
// mtime is the markdown file modify time
dateFormat: { mtime: string };
// local saved dir
postSavedDir: string;
// local saved full path
postSavedFullPath: string;
namespace: 'post';
// homepage url
home: string;
// render config
render: Record<string, any>;
}
```
for indexes page:
`template.index` and `template.tagIndexes` has same options.
```ts
interface IndexesOptions {
// posts array, length decide from render.pageSize
posts: PostOptions[];
// current page
page: number;
// total page length
pageTotal: number;
// total post length
totalCount: number;
// self relative path from site
selfPath: string;
// prev page resolve path from site
prevPagePath: string;
// next page resolve path from site
nextPagePath: string;
// self relative path from site jointed `build.publicPath`
selfStaticPath: string;
// prev page relative path from site jointed `build.publicPath`
prevPageStaticPath: string;
// next page relative path from site jointed `build.publicPath`
nextPageStaticPath: string;
// self is the first page
isFirstPage: boolean;
// self is the last Page
isEndPage: boolean;
// the site option in `never-write.yaml`
site: { name: string; desc: string };
namespace: 'indexes'|'tag';
// tag information
tag: Record<string, {
posts: PostOptions[];
staticPath: string;
}>;
// current page'ss tag
tag: '';
// homepage url
home: string;
// render config
render: Record<string, any>;
}
```
## hook
added to never-write.yaml:
```yaml
build:
hook: ./hook/index.js
```
at build stage will read this path to get hook file, in time will exec the hook.
```js
// ./hook/index.js
module.exports = {
// before generate each post exec
eachBeforeRenderPost(opt) {
console.log(opt);
},
// after generate each post exec
eachAfterRenderPost(opt) {
console.log(opt);
},
// before generate each indexes file exec
eachBeforeRenderIndexes(opt): {
console.log(opt);
},
// after generate each indexes file exec
eachAfterRenderIndexes(opt): {
console.log(opt);
},
// before generate each tag indexes file exec
eachBeforeRenderTagsIndexes(opt) {
console.log(opt);
},
// after generate each tag indexes file exec
eachAfterRenderTagsIndexes(opt) {
console.log(opt);
},
// indexed page's posts sort function
// default is DESC
sortBy(a, b) {
// ...
},
};
```
## how to set tag
markdown files header can set config by yaml:
```md
title: page title
tag: tag1, tag2, tag3
## content
xixi...haha...
```
`tag` option will split by `,` and be array.
when markdown in process will group by `tag`.
## RESERVED FOLDER
those folder name in special case, cannot use under `posts` folder.
- page
to store index pages.
- tags
to store tag pages.
## OTHERS
the default theme style copy from hexo theme [cactus](https://probberechts.github.io/hexo-theme-cactus/), thanks (new theme its too hard for me).