项目结构与实现细节
项目概览
这是一个基于 PHP 的静态博客生成器。它读取带 YAML Front Matter 的 Markdown 文章,转换为 HTML,并生成首页、文章页、标签页、分类页、归档页等静态页面。构建结果输出到 dist/ 目录,可直接部署到任意静态服务器。
核心特点:
- 文章源为 Markdown,支持 Front Matter
- 生成首页、文章页、标签页、分类页、归档页
- 主题切换、代码高亮、目录、阅读进度、图片增强等前端能力
- 构建过程有日志输出
运行方式
生成新文章模板(输出到标准输出):
php main.php new "文章标题"
构建静态站点:
php main.php build
构建后,dist/ 目录下会生成所有静态文件,在 dist 目录下开启 web 服务,访问 http://localhost:8000 进行预览:
php -S localhost:8000 -t dist/
目录结构与职责
- assets/
- 前端静态资源(CSS/JS/Prism)。构建时复制到 dist/assets/
- config/
- 站点配置(如标题、描述等)
- logs/
- 构建日志输出目录
- posts/
- Markdown 文章源文件,支持子目录
- public/
- 原样拷贝的静态资源(构建时复制到 dist/ 根目录)
- images/
- 文章图片目录(构建时复制到 dist/images/)
- src/
- 核心 PHP 逻辑(解析、校验、渲染、生成)
- templates/
- 页面模板(首页、文章、标签、分类、归档等)
- dist/
- 构建输出目录(生成后出现)
- main.php
- CLI 入口
构建流程
入口:main.php
- 初始化配置
- 创建 Generator 实例
- 执行 Generator::run()
Generator::run() 主要步骤:
- cleanup
- 删除 dist/ 目录并重新创建
- copyStaticAssets
- assets/ -> dist/assets/
- public/ -> dist/
- images/ -> dist/images/
- loadAndProcessPosts
- 读取 posts/ 下 Markdown
- 解析 Front Matter
- 过滤 draft: true 的文章
- validatePosts
- 校验必填字段与类型
- 校验 permalink 合法性和冲突
- prepareData
- Markdown 转 HTML
- 按日期排序
- 聚合 tags/categories/archives
- generatePages
- 生成文章页
- 生成首页分页
- 生成标签页、分类页、归档页、404
- (可选)生成 sitemap.xml(依赖 config/site.php 的 site.url)
说明:如果 site.url 未配置或为空,会跳过 sitemap 生成并输出 warning 日志。
Front Matter 规范
必需字段:
- title: 标题
- date: 日期(字符串或可解析格式)
- permalink: 固定链接(如 /posts/hello-world/)
可选字段:
- tags: 标签数组
- categories: 分类数组(支持单个字符串)
- pin: 置顶优先级,0-3,数字越小越靠前
- draft: 草稿,true 表示构建时跳过
- sidebar: 是否显示文章目录侧边栏
示例:
---
title: Hello World
date: 2026-03-20 12:00:00
permalink: /posts/hello-world/
tags:
- 示例
categories:
- 笔记
pin: 1
draft: false
sidebar: true
---
分类与标签逻辑
- tags: 每篇文章可多个,聚合为标签页数据
- categories: 每篇文章可多个,聚合为分类页数据
- 分类与标签页面为下拉式展开列表(不跳转)
置顶逻辑
- pin > 0 表示置顶,1 优先级最高
- 置顶文章最多 3 篇
- 首页分页仅第一页显示置顶文章
- 置顶文章按 pin 升序、日期降序排序
分页逻辑
- 首页分页大小为 15 篇
- /index.html 为第一页
- /page/{n}/index.html 为后续分页
- 分页导航为上一页 / 当前页 / 下一页
Sitemap
构建时会在 dist/ 下生成 sitemap.xml,用于 SEO。
- 域名来源:config/site.php 的 site.url(会自动去掉末尾的 /)
- 输出位置:dist/sitemap.xml
- 收录的页面:
- 首页:/
- 分页:/page/{n}/(从第 2 页开始,第一页为 /)
- 系统页:/tags/、/categories/、/archives/
- 全部文章 permalink(Front Matter 的 permalink)
- lastmod 规则:
- 文章:优先用文章 date 转 ISO8601(format 'c'),不可解析则退回构建时间
- 系统页/分页:使用构建时间
模板结构
- templates/layout.php
- 基础布局,包含导航、主题切换、脚本样式引入
- templates/index.php
- 首页文章列表 + 分页
- templates/post.php
- 文章页,支持目录与元信息显示
- templates/tags.php / templates/categories.php
- 标签/分类页(下拉展示文章列表)
- templates/archive.php
- 归档页
- templates/404.php
- 404 页面
前端能力
- assets/js/site.js
- 返回顶部 + 文章页目录生成与滚动定位
- assets/js/navReveal.js
- 滚动时导航栏显隐
- assets/js/readingProgress.js
- 阅读进度条
- assets/js/imageEnhance.js
- 图片增强(懒加载/点击放大)
- assets/js/ThemeSwitch.js
- 主题切换
样式入口:assets/css/site.css
博客样式自定义
博客文章由 markdown 转 html 后,样式大多数由 /assets/css/github-markdown-css.css 直接提供,部分博客样式在 /assets/css/site.css 中定义,site.css导入顺序位于 /assets/css/github-markdown-css.css 之后,因此,可以在 site.css 中覆盖或自定义样式来调整博客的外观。
静态资源映射
- assets/ -> dist/assets/
- public/ -> dist/
- images/ -> dist/images/
文章中推荐使用绝对路径:
- /images/xxx/1.png
日志
- 构建日志写入 logs/build.log
- 控制台输出带时间戳与中文等级
补充:
- 日志默认追加写入,并在每次构建开始写入分隔线(便于区分多次构建)。
- 默认保留 14 天:当 build.log 文件超过 14 天未更新,会自动清空重写。
- 入口 main.php 固定时区为 Asia/Shanghai,保证日志与日期输出为北京时间。
permalink 冲突校验
构建时会校验文章 permalink 不与以下路径冲突:
- 系统页:/tags/、/categories/、/archives/
- public/ 下的静态文件路径(会被视为站点根路径下的真实文件)
- images/ 下的静态文件路径(会被视为 /images/... 的真实文件)