项目结构与实现细节

发布于: 2026-03-24 22:14

项目概览

这是一个基于 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

  1. 初始化配置
  2. 创建 Generator 实例
  3. 执行 Generator::run()

Generator::run() 主要步骤:

  1. cleanup
    • 删除 dist/ 目录并重新创建
  2. copyStaticAssets
    • assets/ -> dist/assets/
    • public/ -> dist/
    • images/ -> dist/images/
  3. loadAndProcessPosts
    • 读取 posts/ 下 Markdown
    • 解析 Front Matter
    • 过滤 draft: true 的文章
  4. validatePosts
    • 校验必填字段与类型
    • 校验 permalink 合法性和冲突
  5. prepareData
    • Markdown 转 HTML
    • 按日期排序
    • 聚合 tags/categories/archives
  6. 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/... 的真实文件)