添加README.md 说明hugo是一个spf13钟爱的静态站点生成器, 特点是高效/灵活
对应的文档: docs下执行 hugo -p ~/code/src/github.com/spf13/hugo/docs -w -s -port 8000 看代码之前先看
搭建了一个可运行的基本架子出来
- 添加license
- 添加基本运行的架子
- 添加附加说明文档
源码阅读:
- main.go 可执行:
- 处理配置Config, 实际是用hugolib工具去实现,下面几个方法也是
- 利用Config构造Site对象, 其中默认模板是post,索引默认支持分类和标签
- 依次调用Site.Build 和 Site.Stats
- hugolib工具库:
- config.go 读取配置文件,将配置存在一个Config结构体中
- hugo会根据配置,创建一个站点, 用Site对象表示, 站点生成之后还可以进行运行
- site.go 主要描述的是Site对象,这个对象包含了站点相关的所有元素
- 分析Site.Build:
- Site.Process
- Site.initialize
- 查看layout和source(就是指content)目录是否存在;查看publish目录是否创建
- 遍历source下的文件, 把文件和目录都保存在Site的map中
- 初始化Site里的部分元素
- Site.prepTemplates
- 创建一个新的template对象, 名字为"",这个对象用于处理html, 函数表中添加函数
- 遍历layout下的文件, 对于每一个文件,依据文件名创建一个template对象,解析layout文件
- 新建的模板对象都挂在名字为""的模板对象下,意味着: ""模板中可以引用layout下的所有模板
- Site.CreatePages
- 之前遍历source,数据放在Site.Files map中,遍历,为每个文件创建一个Page对象
- Site.Pages 的类型是[]*Page, 具体的Page创建和排序,放在page.go中去分析
- 在看下一个函数之前,需要先了解page.go中的创建/排序/获取参数
- 这个函数会创建一个page对象,并添加到site对象中
- Site.BuildSiteMeta
- Site中存着两个map,一个是string-Pages,一个是string-Index,具体看代码可以分析
- hugo中存在两类索引,一类分类,一类是自定义索引.分类可理解为按大类分,自定义索引就是标签
- 分类可以是学习 生活 电影 美食,标签可以是编程 方法论 golang, 一个content可以是学习,也可以是 编程 golang
- BuildSiteMeta第一件事就是将分类和标签理出来,整理出来的page,还按照发布日期排序
- section作为渲染时的一个分类,默认取的是content type, 按section的不同,将page也做了分类和排序
- 这个函数将 分类 标签 section 都做了整理和排序
- Site中存着两个map,一个是string-Pages,一个是string-Index
- 更多的是将索引和分类排序了一下
- Site.initialize
- Site.Render
- Site.RenderIndexes
- 遍历所有的分类和标签,如果content对应着分类和标签,就创建一个html来管理
- Site.RenderLists
- list就是导航,按section分,如果有就创建一个导航页
- Site.RenderPages
- 渲染页面,对于每个content page,如果不指定模板,就使用/layout/content type/single.html模板
- Site.ProcessShortcodes
- 先找出shortcode的名称和参数,然后替换,将所有的全部替换完,shortcode不能嵌套
- Site.RenderHomePage
- Site.RenderIndexes
- Site.Write
- Site.WritePages
- 至此,静态站点的生成就ok了
- Site.WritePages
- Site.Process
- 分析Site.Stats
- page.go 分析
- NewPage, 参数是一个content的路径,将文件头 front matter读出来,丢给page结构体, 其中,md内容读出来分3块存储:原始md,解析之后的md,还有摘要md(就是md前多少字)
- NewPage 创建一个page对象
- initializePage 用文件初始化一个page对象, 文件目录也有讲究,非content目录下的文件要特殊处理
- buildPageFromFile 解析文件头,有两种文件头
- json格式: 读取第一个{}, 读取头信息
- md格式: 读取两个---之间的数据, 解析
- 除了解析文件头,还做了两件事:设置输出文件名/将文件内容md,转换成page对象的内容
- analyzePage 统计md中还多少字,几百字
源码单步:
- 在main.go同级目录执行: dlv debug main.go -- -p ./docs 即可调试站点生成过程
- 如果要是启用http服务来查看生产结果,使用http包即可
- 默认模板叫post
回顾:
- hugo项目目标:一个静态站点生成工具
- 应用场景:非交互式站点的生存,eg:使用时,只使用页面资源,而不走通信的,叫静态站点.项目站点/博客都很适用
- 静态站点生成关注的2大点:内容和样式分离/内容快速添加到站点
- 内容一般用md来写,因为md特别适合纯文本写作,缺点是样式不够丰富
- 如果写md的同时也要写html,这样就不够简洁,因为多数人对html不熟
- 所以大部分静态站点生成器都选择了md写内容,用模板/主题等概念来完成样式的处理
- hugo相对jekyll等,优势在于生成快/golang实现,使用技术栈少/更加灵活的样式设置
- 下面讲讲hugo是怎么处理的:
- 站点生成前:
- 内容放在content,一个content最后会渲染成一个page,模板放在layout
- 通过目录结构/配置文件/front matter来进行配置,配置的内容主要有以下几个:
- 一个content用哪个模板来渲染
- 零碎的页面的包括:分类 标签 主页
- 零碎的content属性包括:发布日期 过期日期 草稿状态 渲染模板 分类 标签 页面参数
- 零碎的渲染后访问包括:url相关的设置
- 零碎的模板相关包括:组成也是由小块组成大块,也包括shortcode
- 站点生成顺序:
- 一个content生存的顺序:
- content会包含3部分: front matter/ md内容 / shortcode
- 处理第一步是将front matter分离出来,这部分是属性,不是内容
- 将md的内容通过工具转换成html文件,这个工具是blackfriday,一个go编写的工具
- 最后将html中存在的shortcode替换成对应的html代码块,这就是最后的html页面
- 索引(分类/标签/导航) 首页
- 这里重点讲了一个content生成的过程,并未详细写整个站点生成的过程.
- 一个content生存的顺序:
- 站点生成前:
总结:
- hugo主要是利用golang的html/template包,也利用了blackfriday包
- 来实现md嵌html来,达到"md写,样式丰富易修改"的目的
- 样式(html代码)封装成shortcode, 方便单独扩展
- 相比jekyll,文档实在不够清楚
- 主要修改的是README.md, 基本就是将文档中的内容移到了README.md
- 主要是在文档中添加了从源码生成hugo可执行的方法
- 针对文档,补充了一些说明,修改只有一样,对参数的说明 -p -port做了正确的区分:
- -p是站点目录
- --port是http服务的端口
- 针对文档,将启动参数 port 的变动写入了README.md
之前渲染站点的顺序是: 索引/导航/页面/shortcode/首页, 现在改为 索引/导航/shortcode/页面/首页
修改理由是更高的性能
忽略当前目录下的hugo文件和publish下的所有文件,因为这个是输出目录,除了里面的静态文件
这第九次是一个分支,后面合进到主干了