菜单

媒体类型处理

相关源文件

目的与范围

本文档解释了 Hugo 如何根据其 MIME(多用途互联网邮件扩展)类型,也称为媒体类型,来识别、处理和管理不同类型的内容。媒体类型处理是 Hugo 的核心子系统,它能够正确识别和处理各种文件格式,如 HTML、CSS、JavaScript、图像等。这些知识构成了 Hugo 管道中资源转换、输出格式选择和内容协商的基础。

有关更广泛的资源管理系统的相关信息,请参阅 资源管理资源管道

媒体类型结构

Hugo 媒体类型系统的核心是 `media` 包中定义的 `Type` 结构体。

来源: media/mediaType.go35-58 media/mediaType.go60-67

`Type` 结构体代表一个媒体类型,包含以下关键组件:

字段描述
类型完整的 MIME 类型字符串(例如,“application/rss+xml”)
MainType顶级类型名称(例如,“application”)
SubType子类型名称(例如,“rss”)
Delimiter后缀之前的分隔符,通常是“.”
FirstSuffix有关此 MediaType 定义的第一个后缀的信息
mimeSuffixMIME 类型中“+”后面的可选后缀(例如,“application/rss+xml”中的“xml”)
SuffixesCSV逗号分隔的文件扩展名列表(例如,“jpg,jpeg”)

`SuffixInfo` 结构体包含媒体类型后缀的信息

字段描述
Suffix不带分隔符的后缀(例如,“xml”)
FullSuffix带分隔符的后缀(例如,“.xml”)

来源: media/mediaType.go35-58 media/mediaType.go60-67

媒体类型集合

Hugo 通过 `Types` 切片维护媒体类型集合,该切片提供通过各种标准查找媒体类型的方法。

来源: media/mediaType.go229-378

这些查找方法可以方便地找到合适的媒体类型。

  • GetByType:按完整的 MIME 类型字符串查找媒体类型
  • BySuffix / GetFirstBySuffix / GetBySuffix:按文件扩展名查找媒体类型
  • GetByMainSubType:按主类型和子类型查找媒体类型
  • GetBySubType:仅按子类型查找媒体类型

内置媒体类型

Hugo 在 `Builtin` 变量中提供了一组内置媒体类型。这些涵盖了 Hugo 处理的常见文件格式。以下是重要的内置类型示例:

媒体类型MIME 类型文件扩展名
HTMLTypetext/html.html, .htm
CSSTypetext/css.css
JavascriptTypeapplication/javascript.js
JSONTypeapplication/json.json
XMLTypeapplication/xml.xml
RSSTypeapplication/rss+xml.rss, .xml
CSVTypetext/csv.csv
CalendarTypetext/calendar.ics
MarkdownTypetext/markdown.md, .markdown
TextTypetext/plain.txt
ImageType (各种)image/*.jpg, .png, .gif 等

这些内置类型在 Hugo 中被用来正确识别和处理文件。

来源: media/mediaType.go220-227 output/outputFormat.go86-220

媒体类型检测

Hugo 拥有复杂的机制来检测文件或内容的媒体类型。此检测通过 `media` 包中的 `FromContent` 函数进行。

来源: media/mediaType.go69-118

检测过程遵循以下步骤:

  1. 使用 Go 的 http.DetectContentType 来获取初始内容类型
  2. 如果类型是“application/octet-stream”(二进制数据),则返回零 Type
  3. 如果类型在提供的 Types 集合中找到,则使用该类型
  4. 对于基于文本的格式,尝试使用扩展名提示来获得更具体的类型
  5. 返回最具体的匹配项,如果未找到匹配项,则返回零 Type

这使得 Hugo 即使在文件扩展名与其实际内容不匹配时也能正确处理文件。

媒体类型和输出格式

媒体类型与 Hugo 的输出格式系统紧密集成。每个输出格式都有一个关联的媒体类型,该媒体类型决定了该格式的特性。

来源: output/outputFormat.go26-82 output/outputFormat.go86-220 output/outputFormat.go223-240 hugolib/site_output.go25-55

Hugo 定义了一组常用的默认输出格式:

输出格式媒体类型描述
HTMLFormattext/html标准的 HTML 输出
RSSFormatapplication/rss+xmlRSS feed 输出
AMPFormattext/html (Path="amp")加速移动页面
JSONFormatapplication/jsonJSON 数据输出
CSSFormattext/cssCSS 样式表
CalendarFormattext/calendar日历输出(iCalendar)
SitemapFormatapplication/xmlXML 站点地图

输出格式决定了内容的渲染方式以及输出使用的媒体类型和相关属性。

来源: output/outputFormat.go86-220 hugolib/site_output.go25-55

媒体类型在资源处理中的作用

媒体类型在 Hugo 的资源处理系统中起着至关重要的作用。资源的识别和处理均基于其媒体类型。

来源: resources/resource_factories/create/create.go124-152 resources/resource_factories/create/remote.go166-308 tpl/resources/resources.go183-205

资源中媒体类型处理流程:

  1. 当创建资源(通过 `resources.Get` 或 `resources.GetRemote`)时,Hugo 会确定其媒体类型。
  2. 对于本地文件,媒体类型主要由文件扩展名确定。
  3. 对于远程资源,Hugo 使用基于内容的检测和 HTTP 标头。
  4. 在资源转换过程中,媒体类型可能会被保留或更改。
  5. 媒体类型决定了资源的如何处理和发布。

远程资源的媒体类型检测

Hugo 拥有一个复杂的系统来检测远程资源的媒体类型。

来源: resources/resource_factories/create/remote.go241-286

对于远程资源,Hugo:

  1. 检查响应中的 Content-Type HTTP 标头
  2. 查看 URL 或文件名以获取指示媒体类型的扩展名
  3. 分析内容本身以确定媒体类型
  4. 使用最具体可靠的信息

这种方法确保 Hugo 能够正确识别和处理远程资源,即使 HTTP 标头不正确或不完整。

创建自定义媒体类型

Hugo 允许站点作者在其配置文件中定义自定义媒体类型。这对于处理专门的文件格式或覆盖 Hugo 的内置媒体类型非常有用。

自定义媒体类型定义包括:

  • MIME 类型字符串
  • 与类型关联的文件后缀
  • 可选的分隔符字符

一旦定义,自定义媒体类型就能与 Hugo 的资源处理系统无缝集成。

来源: media/mediaType.go120-162 media/mediaType.go216-227

实际应用

媒体类型处理影响 Hugo 的许多方面:

  1. 资源转换链:不同的转换适用于不同的媒体类型。
  2. 模板选择:媒体类型有助于确定使用哪些模板。
  3. 输出格式协商:媒体类型对于内容协商至关重要。
  4. 内容处理:根据媒体类型,不同的内容类型会被不同地处理。
  5. 文件扩展名处理:媒体类型决定了生成文件的适当扩展名。

理解媒体类型处理对于高级 Hugo 用途至关重要,尤其是在处理自定义资源类型或输出格式时。

来源: hugolib/resource_chain_test.go374-392 tpl/resources/resources.go290-303

媒体类型实用工具

Hugo 提供了一些处理媒体类型的实用函数:

功能目的
FromString从 MIME 类型字符串创建 Type
FromStringAndExt从 MIME 字符串和扩展名创建 Type
FromContent通过检查内容和提示来创建 Type
InitMediaType初始化媒体类型的内部结构
IsText确定媒体类型是否表示文本内容
IsHTML检查媒体类型是否为 HTML
IsMarkdown检查媒体类型是否为 Markdown

这些实用工具简化了 Hugo 代码库中处理媒体类型的工作。

来源: media/mediaType.go69-118 media/mediaType.go119-162 media/mediaType.go178-201