网页网站您现在的位置是:首页 > 博客日志 > 网页网站

如何自己写一个静态站点生成器

<a href='mailto:'>微wx笑</a>的头像微wx笑2019-09-06 14:13:09网页网站人已围观关键字:生成器,generator

简介一直很想自己写一个静态博客,但总是觉得比较麻烦。直到看到 Writing a small static site generator ,才发现原来写一个静态博客竟如此简单。

为什么要自己动手写一个静态博客?

众所周知,随着Github Pages这样的服务越来越流行,现在像Hexo、Hugo、Pelican这样的静态博客越来越多, 像我以前就是用Pelican的,但因为Pelican的依赖比较多(其实是想自己造轮子), 自从见过Nim就一直很想自己写一个静态博客,但总是觉得比较麻烦,E23编程技术_踩坑日志_进阶指南 - 无知人生

直到看到 Writing a small static site generator , 才发现原来写一个静态博客竟如此简单。E23编程技术_踩坑日志_进阶指南 - 无知人生

废话不多说,那我们就开始动手做吧!E23编程技术_踩坑日志_进阶指南 - 无知人生

准备工作

  • 安装好Nim编译器,如果你用Debian GNU/Linux,apt install nim即可E23编程技术_踩坑日志_进阶指南 - 无知人生

  • 安装依赖E23编程技术_踩坑日志_进阶指南 - 无知人生

nimble install markdown
nimble install nwt

收集markdown列表

静态博客大多是使用markdown这样的源格式来编写文章,然后输出成HTML,E23编程技术_踩坑日志_进阶指南 - 无知人生

因为最近几年写markdown比较多,这里就只支持markdown。E23编程技术_踩坑日志_进阶指南 - 无知人生

这段代码比较简单,遍历srcs目录中的*.md文件,然后交给md_processor去解析E23编程技术_踩坑日志_进阶指南 - 无知人生

proc write_posts(): seq[JsonNode] = 
  var
    post: JsonNode  for file in walkDirRec "./srcs/":
    if file.endsWith ".md":
      echo file
      post = md_processor(file)
      write_post(post)
      result.add post

解析markdown源

因为不像Python里有好用的frontmatter,所以我们这里用pegs来解析markdown中的元信息(如Title、Tags等)。E23编程技术_踩坑日志_进阶指南 - 无知人生

这里的markdown解析是用nim-markdown ,这在准备工作中已经安装好了E23编程技术_踩坑日志_进阶指南 - 无知人生

proc md_processor(file_path: string): JsonNode = 
  var
    file_meta = splitFile(file_path)
    head = true
    post = initTable[string, string]()
    matches: array[0..1, string]
    src = ""
  for line in file_path.open().lines:

    if head and line.match(peg"\s* {\w+} \s* ':' \s* {.+}", matches):
      post[matches[0]] = matches[1]
    elif head and line.strip.len == 0:
      discard
    else:
      head = false    if head == false:
      src.add line & "\n"
  if not post.contains"Slug":
    post["Slug"] = file_meta.name  if "Category" in post:
    if "Tags" in post:
      post["Tags"].add "," & post["Category"]
    else:
      post["Tags"] = post["Category"]
  post["content"] = markdown(src)
  result = %* post

生成博客文章

现在我们已经完成了对markdown的解析,接着我们把它输出到HTML中供浏览器查看,E23编程技术_踩坑日志_进阶指南 - 无知人生

在这里,我选择了类似jinja2nwt模板引擎,得以兼容Thea模板的大部分内容。E23编程技术_踩坑日志_进阶指南 - 无知人生

这是一个简化后的模板样例:E23编程技术_踩坑日志_进阶指南 - 无知人生

{% block title %}{{title}}{% endblock %}

{% block content %}<article>
  <aside>
    <time>{{Date}}</time>
    Tags: {{tag_links}}
    · <a href="/">view all posts</a>
  </aside>
  <h1>{{title}}</h1>
  <content>
    {{content}}  </content></article>{% endblock %}

接着,我们在Nim中根据这个模板去输出HTML,我把HTML输出到./public这个目录:E23编程技术_踩坑日志_进阶指南 - 无知人生

proc write_post(post: JsonNode)=
    var
      p: string
      new_post = initTable[string, string]()
    new_post["Tags"] = ""
    for k, v in post:
      new_post[k] = v.getStr
    new_post["tag_links"] = ""
    if "Tags" in post:
      for tag in post["Tags"].getStr.split(","):
        p = """
        <a href="/tags/$1.html">
        $1
        </a>
        """ % tag.strip()
        new_post["tag_links"].add p    var json_post = %* new_post    var content = templates.renderTemplate("post.html", json_post)

    writeFile("public/" & post["Slug"].getStr & ".html", content)

生成博客首页索引

现在我们已经完成了对博客文章的解析和生成,接下来我们去更新一下首页吧!E23编程技术_踩坑日志_进阶指南 - 无知人生

首页的模板如下:E23编程技术_踩坑日志_进阶指南 - 无知人生

{% block content %}<nav>
  <h1>My blog posts</h1>
  <dl class="posts-list">
    {{content}}  </dl></nav>{% endblock %}

在Nim中去生成index.html(因为nwt不支持for循环,所以只好在Nim中去循环了):E23编程技术_踩坑日志_进阶指南 - 无知人生

proc write_index(posts: seq[JsonNode]) =
    var
      seq_post : seq[string]
      tags = initCountTable[string]()
      p, summary, tag_cloud: string    for key, post in posts:
      if "Summary" in post:
        summary = post["Summary"].getStr      else:
        summary = ""
      p = """
    <a href="/$1.html">
      <dt>$2</dt>
      <dd>
        <time>$3</time>
      </dd>
    </a>
    <div class="summary">
    $4
    </div>
    """ % [
          post["Slug"].getStr,
          post["Title"].getStr,
          post["Date"].getStr,
          summary,
          ]
      seq_post.add p      if "Tags" in post:
        for tag in post["Tags"].getStr.split(","):
          tags.inc tag.strip()

    for tag, count in tags:
      p = """
      <a href="/tags/$1.html">
      $1
      </a>
      """ % tag
      tag_cloud.add p
    seq_post.add tag_cloud    var index_post = %* {
        "content": seq_post.join("\n")
      }
    var content = templates.renderTemplate("index.html", index_post)

    writeFile("public/" & "index.html", content)

最后的工作,写个main函数

proc main()= 
  var
    posts = write_posts()
  posts = sort_posts(posts)
  write_index(posts)

开始编译吧!

nim c -r build.nim

完整代码

kunE23编程技术_踩坑日志_进阶指南 - 无知人生

感谢

感谢 Thea ,在我想用Nim编写自己的静态博客时, 看到了 Writing a small static site generator , 惊叹竟然可以如此简洁,所以此篇文章基本也是和她一样的思路,只是实现的语言换成了NimE23编程技术_踩坑日志_进阶指南 - 无知人生

本文转自:http://muxueqz.top/a-small-static-site-generator.htmlE23编程技术_踩坑日志_进阶指南 - 无知人生

很赞哦! () 有话说 ()

点击排行

站点信息

  • 建站时间:2018-10-24
  • 服务期限阿里云ECS 2027年到期
  • 主题模板:基于《今夕何夕》修改
  • 文章统计:188篇
  • 文章评论:27条
  • 文章阅读:2117次
  • 文章点赞:874次
  • 微信公众号:扫描二维码,关注我们