Table of Contents
hello zola/Rust!
年后第二天上班,给自己定了一个目标,今年要从c++过渡到rust,恰巧发现阿里云续费还是99一年,果断续费一年,又恰巧在看GitHub热点项目时发现了zola
仔细对比了hugo和zola(其实是刚开工比较闲。。。),考虑到zola的rust属性,最后选择了zola(其实我也想搭建一个hugo的网站对比一下,但是有点懒)。
如果没有意外,这篇博客会成为流水账,记录我是如何安装zola,设置zola,运行demo,如何修改某些地方,如何添加其他功能。事实上我确实就是在不知不觉中这样写的,但是第三天吃完午饭脑子里突然蹦出一句话:博客不是流水账!!!
zola原理探究
zola源码主要存放在src和components中,其中components是核心底层代码,每个子文件夹是一个功能模块,具体含义可以问gpt,我们的目标是探究基于rust的静态网页生成器的核心功能和原理。因此我们选用一个核心功能来学习:site。
build.rs
//src/cmd/build.rs
let mut site = Site::new(root_dir, config_file)?;
site.load()?;
site.build()
Site模块是负责整个网站生成的接口
site
site结构体:
pub struct Site {
// 站点的基础路径
pub base_path: PathBuf,
// 解析后的配置文件参数,例如base_url,themes等
pub config: Config,
// 用于渲染模板的 Tera 实例
pub tera: Tera,
// 用于处理图像的处理器,采用 Arc 和 Mutex 以支持多线程安全
imageproc: Arc<Mutex<imageproc::Processor>>,
// 如果启用了实时重载功能,存储其端口号
pub live_reload: Option<u16>,
// 生成的静态文件输出路径
pub output_path: PathBuf,
// 内容文件的路径,通常是存放 Markdown 文件的目录
content_path: PathBuf,
// Sass 文件的路径,用于样式表的编译。
pub sass_path: PathBuf,
// 静态资源的路径,如图片、JavaScript 文件等。
pub static_path: PathBuf,
// 模板文件的路径。
pub templates_path: PathBuf,
// 站点的分类和标签等分类法。
pub taxonomies: Vec<Taxonomy>,
/// A map of all .md files (section and pages) and their permalink
/// We need that if there are relative links in the content that need to be resolved
pub permalinks: HashMap<String, String>,
/// Contains all pages and sections of the site
pub library: Arc<RwLock<Library>>,
/// Whether to load draft pages
include_drafts: bool,
build_mode: BuildMode,
shortcode_definitions: HashMap<String, ShortcodeDefinition>,
}
接下来就是对site的实现,包括了页面生成器核心的功能,例如render_page核心的渲染页面流程。
pub fn render_page(&self, page: &Page) -> Result<()> {
//首先检查页面的 meta 数据中是否允许渲染,如果不允许则直接返回
if !page.meta.render {
return Ok(());
}
//使用 Tera 模板引擎渲染页面 HTML
let output = page.render_html(&self.tera, &self.config, &self.library.read().unwrap())?;
//注入 livereload 脚本
let content = self.inject_livereload(output);
//将页面路径分割成组件数组,用于构建输出路径
let components: Vec<&str> = page.path.split('/').collect();
//将渲染后的内容写入到对应的 index.html 文件中
let current_path = self.write_content(&components, "index.html", content)?;
// 将页面相关的资源文件(如图片等)复制到输出目录中
self.copy_assets(page.file.path.parent().unwrap(), &page.assets, ¤t_path)?;
Ok(())
}
渲染完成之后就可以执行add_page函数,向站点添加新的页面。
再例如add_section向站点添加新的分区
pub fn add_section(&mut self, mut section: Section, render_md: bool) -> Result<()> {
// 将分区的相对路径和永久链接添加到站点的 permalinks 映射中,这些链接信息后续会用于处理内部链接和生成 URL
self.permalinks.insert(section.file.relative.clone(), section.permalink.clone());
if render_md {
section.render_markdown(
&self.permalinks,
&self.tera,//使用 Tera 模板引擎渲染分区的 Markdown 内容
&self.config,//应用站点配置中的 Markdown 相关设置
&self.shortcode_definitions,//处理分区中的短代码
)?;
}
let mut library = self.library.write().expect("Get lock for add_section");
library.sections.remove(§ion.file.path);
library.insert_section(section);
Ok(())
}
其他核心功能函数包括set_base_url设置url,load导入所有的md文件并生成分区,render_xxx渲染生成各种通用文件,build构建功能(很多render_xxx函数都在build中被执行),等等。
rust小结
zola作为笔者第一次实际意义上接触的rust项目,既是为了搭建一个简单高效的静态博客网站,更是为了学习rust(当然最开始的目标就是和rust混个脸熟😅)
很好!
加油!
流水账
其实有时候还是有用的🤪
zola demo
- 安装zola
- zola init myblogdemo
- 选择一个现成的主题下载到myblogdemo/themes下
- 将主题文件夹内的config.toml文件中的内容,按需设置到根目录下的config.toml中,并将url等参数设置好
- zola serve运行
添加评论系统giscus
评论系统使用github的giscus,又恰巧我使用的主题apollo中留出了giscus接口,因此我只需要在giscus上设置好我的评论仓库然后将代码导入到_giscus_script.html中就可以。
重点是需要在每个博客md中设置评论使能:
+++
...
[extra]
version = "1.0.1"
comment = true
+++
云服务器部署
- 部署Nginx
- 设置域名
- 强制https
- 设置不缓存
问题记录
阿里云部署后无法渲染
config.toml要设置好,另外nginx的配置文件要设置正确。
页面更新后浏览器依然不刷新
- 设置nginx
# HTML 文件,禁用缓存
location ~* \.html$ {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
try_files $uri $uri/ /index.html;
}
# 静态资源(JS、CSS、图片等),使用版本控制(如 ?v=1.0.0)
location ~* \.(css|js|jpg|jpeg|png|gif|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
try_files $uri $uri/ /index.html;
}
- 添加版本号
+++
...
[extra]
version = "1.0.1"
+++