Skip to content

honmaple/snow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Snow

静态博客生成器

快速开始

开始(Quickstart)

创建新的站点

──╼ ./snow init
Welcome to snow 0.1.0.
> Where do you want to create your new web site? [.] mysnow
> What will be the title of this web site? [snow]
> Who will be the author of this web site?
The input is required
> Who will be the author of this web site? honmaple
> What is your URL prefix? (no trailing slash) [http://127.0.0.1:8000]
> Do you want to create first page? [Y/n]

编译和预览

└──╼ cd mysnow
└──╼ ../snow server -D
DEBU Copying @theme/static/css/main.css to output/static/css/main.css
INFO Done: Static Processed 1 static files in 588.705µs
DEBU Writing output/categories/index.html
DEBU Writing output/authors/index.html
DEBU Writing output/tags/index.html
DEBU Writing output/posts/index.html
DEBU Writing output/authors/snow/index.html
DEBU Writing output/tags/snow/index.html
DEBU Writing output/categories/linux/index.html
DEBU Writing output/tags/linux/index.html
DEBU Writing output/tags/emacs/index.html
DEBU Writing output/categories/linux/emacs/index.html
INFO Done: Page Processed 1 normal pages, 0 hidden pages, 0 section pages in 10.087804ms
INFO Done: Section Processed 1 posts in 10.1831ms
INFO Done: Taxonomy Processed 1 authors, 3 tags, 1 categories in 10.18788ms

安装(Installation)

└──╼ go install https://github.com/honmaple/snow

编译(Build)

└──╼ git clone https://github.com/honmaple/snow --depth=1
└──╼ cd snow
└──╼ go mod tidy
└──╼ go build .

命令行(Cli usage)

└──╼ ./snow --help
NAME:
   snow - snow is a static site generator.

USAGE:
   snow [global options] command [command options] [arguments...]

VERSION:
   0.1.0

COMMANDS:
   init     init a new site
   build    build and output
   server   server local files
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config FILE, -c FILE  load configuration from FILE (default: "config.yaml")
   --help, -h            show help (default: false)
   --version, -v         print the version (default: false)

init

└──╼ ./snow init
└──╼ ./snow init myblog

如果不指定 myblog 目录,默认会在当前目录下生成一个 config.yaml 文件和一个 content 目录

build

该命令会构建站点内容内写入到 {output_dir} 目录, 如果该目录已经有文件存在,除非制定 -C 参数,否则不会自动清理

  • 清理输出目录
    └──╼ ./snow build --clean
    └──╼ ./snow build -C
        
  • 显示输出详情
    └──╼ ./snow build --debug
    └──╼ ./snow build -D
        
  • 指定输出目录
    └──╼ ./snow build --output {output_dir}
    └──╼ ./snow build -o {output_dir}
        
  • 指定mode
    └──╼ ./snow build --mode {mode}
    └──╼ ./snow build -m {mode}
        

server

build 支持的命令 server也同样支持, 除此之外,还有

  • 指定监听地址
    └──╼ ./snow server --listen 127.0.0.1:8088
    └──╼ ./snow server -l 127.0.0.1:8088
        

    默认监听地址是 site.url

  • 监听文件修改并重新构建
    └──╼ ./snow server --autoload
    └──╼ ./snow server -r
        

hooks

显示所有hooks

└──╼ ./snow hooks
assets(enabled), encrypt(enabled), filter, minify, pelican(enabled), rewrite(enabled), shortcode(enabled)

目录结构(Driectory structure)

.
├── config.yaml
├── content
│   └── posts
│       └── first-page.md
├── static
├── templates
└── themes
│   └── snow
│       └── static
│       └── templates
  • config.yaml: 配置文件
  • content: 内容目录
  • static: 静态文件目录,该目录下的所有文件都会同步到站点的根目录
  • templates: 模版目录
  • themes: 主题目录

配置文件(Configuration)

# 站点配置信息
base_url: "http://127.0.0.1:8000"
title: "Snow"
description: "snow is a static site generator."
author: "honmaple"
language: "zh"

# 发布时使用的配置
modes.publish:
  base_url: "https://honmaple.me"

# 多语言en使用的配置
languages.en:
  base_url: "https://honmaple.me/en"

output_dir: "output"
content_dir: "content"

theme: "snow"

# 按照主题需要进行配置
params.extra:
  menus:
    - name: "关于"
      url: "/pages/about.html"

内容管理

# 指定内容目录
content_dir: "content"

# 忽略的内容,如果是目录则以 / 结尾
ignored_content:
  - "drafts/"

Section

content_dir 目录下以 _index. 开头的文件都将识别为 section 结构,=secion= 下包括多篇文章

content/
├── _index.md           // <- http://127.0.0.1:8000/index.html,包括content下所有默认语言的文章
├── _index.en.md        // <- http://127.0.0.1:8000/en/index.html,包括content下所有语言为en的文章
└── posts              // no url
    ├── post1.org      // <- http://127.0.0.1:8000/posts/2022/02/post1.html
    └── subposts       //
        └── _index.org // <- http://127.0.0.1:8000/posts/subposts/index.html
        └── post2.org  // <- http://127.0.0.1:8000/posts/2023/02/post2.html

配置

sections:
  _default:
    # 页面默认排序, 多字段使用逗号分隔
    sort_by: "date desc"
    # 自定义某个section下的页面筛选
    filter_by: ""
    # 页面默认分页, path必须使用{number}变量, 0表示不分页
    paginate: 10
    # 分页路径
    paginate_path: "{name}{number}{extension}"
    # 分页前筛选pages
    paginate_filter: ""
    # 生成路径, 为空表示禁止生成相关页面
    path: "{section}/index.html"
    # 使用的模版
    template: "section.html"
    # section输出格式
    formats.atom:
      path: "{section:slug}/atom.xml"
  en:
    # en目录下的所有section都是en语言
    lang: "en"

filter_by 格式(下同):

'emacs' in tags and not draft or weight > 1

其中 tags, draft 等都是 FrontMatter

路径变量(sections.xxx.path)

变量描述
{lang}section所属language
{lang:optional}section所属language,如果是默认语言则为空
{path}section所属路径
{path:slug}section所属路径, 转为slug
{section}section名称
{section:slug}section slug, 中国 -> zhong-guo

模版变量(sections.xxx.template)

变量描述
section
section.Langsection语言
section.Slug
section.Titlesection标题
section.Pathsection相对链接
section.Permalinksection绝对链接
section.Contentsection内容
section.RawContentsection原始内容
section.Pages当前section下的页面列表
section.Children子section
section.Formatssection输出的其它格式

页面(Page)

元数据

  • markdown
    ---
    title: "title"
    categories:
      - Snow/Templates
    tags:
      - linux
      - snow
    ---
        
  • orgmode
    #+TITLE: title
    #+DATE: 2022-02-26 17:14:46
    #+CATEGORIES: Snow/Templates
    #+PROPERTY: TAGS linux,snow
    #+PROPERTY: MODIFIED 2023-02-26 14:35:37
        
  • html
    <head>
      <title>Project</title>
      <meta name="categories" content="Snow/Templates" />
      <meta name="tags" content="linux,snow" />
      <meta name="date" content="2015-12-22" />
    </head>
        

配置

可以在配置文件设置页面的 =FrontMatter=,如果页面已有则忽略

pages:
  _default:
    comment: true
  posts:
    path: "/articles/{date:%Y}/{date:%m}/{slug}.html"
    template: "post.html"
    comment: true
  pages:
    hidden: true
    path: "/pages/{slug}.html"
    template: "page.html"
  drafts:
    draft: true
  en:
    lang: "en"
    path: "/en/articles/{date:%Y}/{date:%m}/{slug}.html"
    template: "post.html"
  en/pages:
    hidden: true
    path: "/en/pages/{slug}.html"
    template: "page.html"

路径变量(sections.xxx.page_path)

变量描述
{lang}页面语言
{lang:optional}页面所属language,如果是默认语言则为空
{date:%Y}创建页面的年份
{date:%m}创建页面的月份
{date:%d}创建页面的日期
{date:%H}创建页面的小时
{path}页面所属路径
{path:slug}页面所属路径, 转为slug
{slug}页面标题或自定义slug
{title}页面标题

模版变量(sections.xxx.page_template)

变量描述
page
page.Title页面标题
page.Lang页面语言
page.Date页面创建时间
page.Modified页面修改时间
page.Aliases页面其它链接
page.Path页面相对链接
page.Permalink页面绝对链接
page.Summary页面简介
page.Content页面内容
page.FrontMatter.xxx自定义的元数据

分类系统(Taxonomy)

配置

taxonomies:
  _default:
    # terms排序, 可选name,count
    sort_by: ""
    path: "{taxonomy}/index.html"
    template: "{taxonomy}/list.html"
    term_path: "{taxonomy}/{term:slug}/index.html"
    term_template: "{taxonomy}/single.html"
    # 页面列表筛选
    term_filter_by: ""
    # 页面列表排序
    term_sort_by: "date desc"
    # 页面列表分页
    term_paginate: 0
    term_paginate_path: ""
    term_paginate_filter: ""
  categories:
  authors:
  tags:

路径变量

  • taxonomies.xxx.path
    变量描述
    {lang}分类所属语言
    {lang:optional}分类所属语言,如果是默认语言则为空
    {taxonomy}分类系统名称
  • taxonomies.xxx.term_path
    变量描述
    {lang}分类所属语言
    {lang:optional}分类所属语言,如果是默认语言则为空
    {taxonomy}分类系统名称
    {term}分类具体名称
    {term:slug}分类slug

模版变量

  • taxonomies.xxx.template
    变量描述
    taxonomy
    taxonomy.Name分类系统名称, 如:categories,tags,authors
    taxonomy.Terms
  • taxonomies.xxx.term_template
    变量描述
    term
    term.Name分类名称
    term.Path相对链接
    term.Permalink绝对链接
    term.List页面列表
    term.Children子分类

归档页(Archive)

snow 中的分类系统是基于归档实现的,该功能类似 SQL 中的 group by, 所以如果要实现归档页可以有两种方式:

  1. 添加 taxonomies.{key}, {key} 可以是页面元数据里的任意字段, 比如 categories, tags, 如果需要按照时间归档, 格式为 date:2006/01, 其中 2006/01 为Go时间格式,表示按年月归档, 并生成链接 /archives/2022/10/index.html
    taxonomies:
      date:2006/01:
        path: "archives/index.html"
        template: "archives.html"
        term_path: "archives/{term}/index.html"
        term_template: "period_archives.html"
        
  2. {content_dir} 下添加一个 archives.md 的文件
    path: archives.html
    template: archives.html
    section: true
        

    然后在模板 {templates}/archives.html 使用 pages.GroupBy({key})

    {%- for subterm in pages.GroupBy("date:2006-01").OrderBy("name desc") %}
      {%- set date = subterm.Name | split:"-" %}
      {%- set year = date[0] %}
      {%- set month = date[1] %}
       ...
    {%- endfor %}
        

分页(Pagination)

路径变量

变量描述
{name}路径名称
{extension}路径扩展
{number}页码, 第一页为”1”
{number:optional}页码, 第一页为空
  • 示例一:
    path: "section/index.html"
    paginate_path: "{name}{number:optional}{extension}"
        
    • 第一页: section/index.html
    • 第二页: section/index2.html
    • 第三页: section/index3.html
  • 示例二:
    path: "section/index.html"
    paginate_path: "page/{number}{extension}"
        
    • 第一页: section/page/1.html
    • 第二页: section/page/2.html
    • 第三页: section/page/3.html

模版变量

变量描述
paginator
paginator.Path分页链接
paginator.PageNum当前页
paginator.Total总页数
paginator.HasPrev()是否有上一页
paginator.Prev上一页
paginator.Prev.URL上一页链接
paginator.HasNext()是否有下一页
paginator.Next下一页
paginator.Next.URL下一页链接
paginator.All所有页
paginator.List当前分页下的页面列表

草稿(Draft)

页面中的 FrontMatter 中的 draft: true 将会识别为草稿,如果不想每一篇草稿都添加相应字段,可以添加 pages 配置

pages:
  drafts:
    draft: true

配置表示 {content_dir}/drafts 该目录下的所有页面都将被识别为草稿。

构建时忽略草稿

  1. 忽略草稿目录
    ignored_content:
      - "drafts/"
        
  2. 使用命令行参数
    snow build --include-drafts
        

输出格式(Atom,Rss,JSON)

可以生成 rss ,*atom* 或者其它任意格式(需要自定义模版)

配置

# 设置rss格式的默认值
formats.rss:
  template: "rss.xml"

formats.atom:
  template: "atom.xml"

sections:
  _default:
    # rss生成路径, 模版将会使用默认模版
    formats.rss.path: "{section:slug}/index.xml"
    # 为空时禁止生成
    formats.atom.path: ""

taxonomies:
  tags:
    formats.atom:
      path: "tags/{term:slug}/index.xml"
      # 自定义模版
      template: "custom.atom.xml"

模版变量

变量描述
section仅生成section 有效
term仅生成taxonomy term 有效
pages页面列表

静态文件(Static)

静态文件分 当前目录下静态文件主题静态文件

# 忽略的静态文件,如果是目录则以 / 结尾
ignored_static:
  - "extra/"

static/{filename}themes/{theme}/static/{filename} 同时存在时,优先当前目录下的文件

多语言(Multilingual)

需要配置 languages

languages.en:
  translations: "i18n/en.yaml"
  taxonomies:
    special_tags:
      path: "{taxonomy}/index.html"
languages.fr:
  translations: "i18n/fr.yaml"

页面格式:

  • {title}.en.md
  • {title}.fr.md

或者可以在文件头指定 lang: en

i18n

  • 模版
    {% i18n "tags" %}
    {% T "tags %d" 12 %}
    {{ i18n("authors") }}
    {{ T("authors") }}
    {{ _("authors %f", 3.14) }}
        

    甚至可以直接使用变量 {{ _(term.Name) }}

  • 翻译文件 默认会加载主题下 i18n 目录下的文件
    i18n
    ├── en.yaml
    └── zh.yaml
        

    文件内容

    ---
    - id: "authors"
      tr: "作者"
    - id: "tags"
      tr: "标签"
        

    也可以自定义文件位置或翻译内容覆盖主题原有的翻译

    languages.en:
      translations: "i18n/en.yaml"
    languages.zh:
      translations:
        - id: "authors"
          tr: "作者"
        

模版(templates)

https://github.com/flosch/pongo2

主题(theme)

安装

开发

主题目录结构

其中 templatesstatic 名称不可修改

simple/
├── theme.yaml
├── templates
│   ├── post.html
│   ├── index.html
│   ├── archives.html
├── static
│   ├── main.css

配置

theme:
  # 主题名称, 未设置将使用默认主题
  name: "test-theme"
  # 默认的主题配置,该配置会自动合并,除非设置为空
  config: "theme.yaml"
  # 主题模版覆盖, 增加同名的文件到 *override* 配置的目录, snow将会优先使用该文件
  override: "layouts"

插件(hooks)

rewrite

重写文章的 FrontMatter 字段,不用修改原文章的内容

配置插件

hooks.rewrite:
  enabled: true

配置选项,如果设置 typelist=,将会把原字段以 =逗号 分隔进行转换

hooks.rewrite:
  option:
    - src: "tag"
      dst: "tags"
      type: "list"

encrypt

文章内容加密

配置插件

hooks.encrypt:
  enabled: true

配置选项

hooks.encrypt:
  option:
    password: "默认密码"
    description: "默认描述"

在文章中使用

  • 添加密码到 frontmatter
    ---
    password: "123456"
    ---
        
  • 局部加密:可以使用 shortcodes 中的 encrypt 功能
    <shortcode encrypt password="123456">
    加密的内容
    </shortcode>
        

在模版中使用

{{ page.Content | encrypt:"123456" }}

shortcode

用于快速插入已有模版

配置插件

hooks.shortcode:
  enabled: true

创建新的shortcode

templates 目录下添加 shortcodes/bilibili.html

<div class="shortcodes-bilibili">
  <iframe
    src="https://player.bilibili.com/player.html?bvid={{ params.id }}&page={% if params.page %}{{ params.page }}{% else %}1&high_quality=1&danmaku=0&as_wide=0{% endif %}&autoplay=0"
    scrolling="no"
    border="0"
    frameborder="no"
    framespacing="0"
    allowfullscreen="true"
  >
  </iframe>
</div>

模版内参数

  • name: 当前 shortcode 的名称
  • params.*: 传递的参数,比如 params.id
  • body
  • counter: 统计 shortcode 在当前文章中的使用次数

使用shortcode

<bilibili id="BV1yB4cz8E9y" />

或者

<shortcode bilibili id="BV1yB4cz8E9y" />

assets

静态文件处理,区别于 static 目录, assets 目录支持合并,压缩等功能

mysite/
├── assets
│   ├── js
│   │   ├── main.js
│   │   └── theme.js
│   ├── scss
│   │   ├── _variables.scss
│   │   ├── entry.scss
│   │   ├── prose.scss
│   │   ├── style.scss
│   │   ├── theme.scss
│   ├── css
│   │   ├── custom.css

配置插件

hooks.assets:
  enabled: true

配置选项

hooks.assets:
  ...
  option.css:
    files:
      - "scss/style.scss"
      - "css/custom.css"
    filters:
      - "cssmin"
    output: "static/lib.min.css"

如果文件以 .scss 或者 .sass=,将自动编译为 =.css

在模版中使用

  • 使用配置的名称 css
    {% assets css %}
    <link rel="stylesheet" href="{{ config.base_url }}/{{ asset_url }}">
    {% endassets %}
        
  • 在模版中调用 assets
    {% assets files="css/style.scss" filters="cssmin" output="css/style.min.css" %}
    <link rel="stylesheet" href="{{ config.base_url }}/{{ asset_url }}">
    {% endassets %}
        

minify

minify 允许对写入的=html=、=css=、=js=文件进行压缩

配置插件

hooks.minify:
  enabled: true

配置选项

hooks.minify:
  option:
    js: true
    css: true
    html: true

本地测试和正式发布

snow 提供了 mode 配置用于区分本地测试和正式发布

base_url: "http://127.0.0.1:8000"

modes.publish:
  base_url: "https://example.com"

modes.develop:
  include: "develop.yaml"

只要在构建时使用 snow build --mode publish 即可覆盖本地默认配置

About

static site generator

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors