Rust项目Zola的源码分析
更新日期:
Zola是一个快速的静态站点生成工具,使用Rust语言实现。阅读源代码是很好的学习Rust的方式,今天将探索下Zola项目的源代码。
zola命令行只有4个命令,代码分析也将从命令行开始。
init创建site目录结构build构建site内容,生成目标位于public目录下serve构建site并启动本地访问的服务器,服务地址默认为`127.0.0.1:1111`check构建site但并不生成文件,同时会检查markdown文件中的外部链接
zola 源码
Zola的github源码,2个重要的目录是src与components, src下是主要是命令行参数解析,components才是站点内容的核心逻辑。

先来大概看下Cargo.toml 中的依赖关系,其内容如下。clap、clap_complete是用于命令行参数解析与bash脚本自动完成; hyper、tokio用于构建serve命令使用的本地web服务器; 使用相对路径方式依赖于components目录下的site、errors、console、utils、libs, components/site将会是分析的重点。
1 | [[bin]] |
命令行参数解析
src目录的内容如下, src/main.rs是程序运行的起点,src/cmd/下的文件是实现各个子命令。
1 | $ tree src |
如下是简化的main.rs, 删除了一些参数检查逻辑与判断。先使用Cli::parse()解析命令行参数,将解析结果cli.command使用match匹配枚举类型Command,匹配时再执行模块cmd下的命令。
子命令为Build时,执行的方法为cmd::build()。命令行参数解析逻辑,使用库clap来实现。
1 | use cli::{Cli, Command}; |
构建命令build的实现
构建命令cmd::build()的实现方法在src/cmd/build.rs文件中。主要逻辑是: 先创建Site对象,然后调用其方法site.load(), site.build()。
1 | use std::path::Path; |
Site::new()方法
Site结构体及其实现的方法在src/components目录下。先看下components目录下的内容,每一个子目录都是一个Rust项目目录。site负责整个构建过程,config管理配置,content管理内容如下, markdown负责markdown内容解析与转换,templates加载模板文件。模块的功能划分还是比较明确的。
1 | $ tree -L 1 components |
接下来看下结构体Site的实现,位于文件src/components/site/src/lib.rs中。创建Site时有2个参数,一个是站点site的根目录,另一个是配置文件名,Site::new()方法中通过config::get_config解析配置文件config.toml,templates::load_tera()加载模板文件,由init命令创建的目录结构会转成完整路径后传给Site。
1 | use config::{get_config, Config, IndexFormat}; |
Site::load()方法
Site::load() 读取目录content下所有文件,创建pages与sections实例。 这里只列出重要的代码行。主要逻辑是: 遍历content文件夹进行循环处理,是子目录且有_index.md时新增section, 普通文件新增page, 加载时会将md转换成html文件。
1 | pub fn load(&mut self) -> Result<()> { |
Site::build()方法
Site::build() 将生成的内容写入public目录,主体就是调用各种render方法生成文件。 其中生成内容在render_sections()方法中,一个section会包含多个page,所以是由render_section方法调用render_page方法。
render_sections()是生成section列表,循环调用render_section()方法;render_section()中又对section.page循环调用render_page()render_section()与render_page()方法将分别调用两个结构体Section与Page的render_html()方法。
1 | pub fn build(&self) -> Result<()> { |
参考: