首页
/ Hakyll静态网站生成器教程:规则、路由与编译器详解

Hakyll静态网站生成器教程:规则、路由与编译器详解

2025-07-10 06:56:22作者:蔡丛锟

前言

Hakyll是一个基于Haskell的静态网站生成器,它采用声明式配置方式,让开发者能够高效地构建静态网站。本文将深入解析Hakyll中的三个核心概念:规则(Rules)、路由(Routes)和编译器(Compilers),帮助开发者掌握Hakyll的核心工作机制。

Hakyll基础配置

Hakyll的配置主要在site.hs文件中完成,使用Rules单子(Monad)来定义网站构建规则。典型的配置入口如下:

main :: IO ()
main = hakyll $ do
    -- 这里放置各种规则定义

hakyll函数用于执行这些规则,而hakyllWith则提供了额外的配置选项,允许开发者自定义构建过程。

规则(Rules)系统

匹配规则(match)

Hakyll使用match函数来定义文件处理规则,它采用声明式DSL,顺序无关紧要,Hakyll会自动处理依赖关系。

match "images/*" $ do
    route   idRoute
    compile copyFileCompiler

这里match的第一个参数是文件模式(Pattern),可以使用简单的glob模式匹配文件。OverloadedStrings扩展允许直接使用字符串作为模式。

创建规则(create)

当需要生成的文件在项目目录中不存在时,应使用create而非match

create ["archive.html"] $ do
    route idRoute
    compile $ do
        -- 编译逻辑

create确保指定的文件一定会被生成,即使源目录中没有对应文件。

路由(Routes)系统

路由决定了输出文件的路径和名称。Hakyll提供了多种路由策略:

常用路由类型

  1. idRoute:保持文件名不变

    route idRoute
    
  2. setExtension:修改文件扩展名

    route $ setExtension "html"
    
  3. customRoute:完全自定义路由逻辑

    route $ customRoute $ reverse . toFilePath
    

编译器(Compilers)系统

编译器负责内容的转换和处理,compile函数接收一个Compiler (Item a)类型的值。

常用编译器

  1. copyFileCompiler:直接复制文件,不做任何处理
  2. compressCssCompiler:压缩CSS文件
  3. pandocCompiler:将Markdown等格式转换为HTML

编译器组合

由于Compiler是Monad而Item是Functor,编译器可以灵活组合:

pandocCompiler >>= relativizeUrls

relativizeUrls编译器将HTML中的绝对URL转换为相对URL,非常适合部署在子目录中的网站。

实际应用示例

图片和CSS处理

match "images/*" $ do
    route   idRoute
    compile copyFileCompiler

match "css/*" $ do
    route   idRoute
    compile compressCssCompiler

Markdown转HTML

match "posts/*.md" $ do
    route $ setExtension "html"
    compile $ pandocCompiler
        >>= relativizeUrls
        >>= loadAndApplyTemplate "templates/post.html" postCtx

进阶技巧

  1. 自定义Pandoc选项:使用pandocCompilerWith传递特定选项
  2. 复杂路由逻辑:结合customRoute实现特殊命名需求
  3. 编译器管道:利用Monad特性构建复杂的处理流程

总结

Hakyll的规则、路由和编译器系统构成了其强大的静态网站生成能力。通过声明式的配置方式,开发者可以轻松定义网站构建逻辑。掌握这三个核心概念后,你将能够:

  • 精确控制哪些文件需要处理
  • 灵活定义输出文件的位置和名称
  • 实现各种内容转换和处理逻辑

在下一篇教程中,我们将探讨如何使用模板系统为生成的页面添加统一的布局和样式,进一步提升Hakyll的使用体验。