资讯动态

Jekyll 博客写作实战:基于 `_posts` 目录的纯文本博客系统

发布时间:2026/9/19 22:21:22 来源:尧图企业网站定制
Jekyll 博客写作实战基于_posts目录的纯文本博客系统【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll核心主题Jekyll 是博客感知的静态站点生成器其博客功能完全由文本文件驱动——无需数据库、无需后端只需按约定命名文章文件并放到_posts目录Jekyll 就会自动解析日期、标题与正文并生成对应页面。本篇技术指南以官方分步教程 08-blogging.md 为主体结合 Jekyll 源码深入讲解博文文件命名规范、Post 布局与布局继承、site.posts列表渲染、摘要excerpt与永久链接permalink的底层实现。读完本文你将能在自己的 Jekyll 站点中完整搭建文章创建 → 布局渲染 → 列表聚合 → 导航接入的博客闭环并理解这些行为背后源码级的运行原理。无数据库的博客文本文件即内容在没有数据库的前提下Jekyll 的博客完全由 Markdown / HTML 文本文件驱动。每篇博文就是一个带 YAML Front Matter 的普通文本文件Jekyll 在构建build阶段读取它们、解析元数据、渲染为独立页面再连同站点其他页面一起静态导出。源码层面_posts目录是一个名为posts的特殊集合Collection在 site.rb 中通过collections[posts]惰性创建def posts collections[posts] || Collection.new(self, posts) end与其他自定义集合不同posts集合默认开启输出output: true相关默认值在 configuration.rb 中强制写入这意味着_posts下的每篇文章都会被渲染成独立的静态页面。Posts_posts目录与文件命名规范博文存放在站点根目录下的_posts文件夹中。文件名必须遵循特殊格式发布日期 标题 扩展名例如2018-08-20-bananas.md。这一约定由 document.rb 中的正则严格定义DATE_FILENAME_MATCHER %r!^(?./)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.])$!从源码结构看该正则将文件名拆解为三部分捕获组含义示例(\d{2,4}-\d{1,2}-\d{1,2})发布日期年 2~4 位月、日 1~2 位以-分隔2018-08-20([^/]*)文章标题 slug不含路径分隔符bananas(\.[^.])$文件扩展名.md其中日期是必填项这正是博文与普通页面Page的根本区别——博文天然拥有时间维度Jekyll 可以按时间排序、按年月归档、生成 RSS 时间戳。该正则同时用于 post_reader.rb 中_posts目录的读取而草稿目录_drafts则使用不要求日期的DATELESS_FILENAME_MATCHER。创建第一篇博文在站点根目录创建_posts/2018-08-20-bananas.md内容如下--- layout: post author: jill --- A banana is an edible fruit – botanically a berry – produced by several kinds of large herbaceous flowering plants in the genus Musa. In some countries, bananas used for cooking may be called plantains, distinguishing them from dessert bananas. The fruit is variable in size, color, and firmness, but is usually elongated and curved, with soft flesh rich in starch covered with a rind, which may be green, yellow, red, purple, or brown when ripe.这份文件与你在教程前几步创建的about.md结构类似Front Matter Markdown 正文区别在于它指定了layout: post并新增了自定义变量author: jill。关于author变量原文档特别强调它是自定义变量并非 Jekyll 内置必填项你完全可以命名为creator或任何其他名字。它的值通过page.author在模板中访问也可以在 Front Matter Defaults 中统一配置。从文件名到页面元数据阅读源码 document.rb 中的populate_title与modify_date方法可以看到文件名中的信息会自动注入页面数据标题若 Front Matter 未显式写titleJekyll 会将文件名中的 slug 按Utils.titleize_slug规则转换为人类可读的标题连字符转空格、首字母大写等日期文件名中的日期会自动成为page.date除非 Front Matter 中显式声明了date覆盖它slug 与 ext同样被提取并存入page.slug、page.ext。这就是post.title默认取自文件名但可在 Front Matter 中覆盖的底层机制。LayoutPost 布局与布局继承文档中的layout: post指向一个尚不存在的布局文件需要在站点根目录创建_layouts/post.html--- layout: default --- h1{{ page.title }}/h1 p{{ page.date | date_to_string }} - {{ page.author }}/p {{ content }}这是一个典型的**布局继承layout inheritance**示例post.html自身声明layout: default因此它输出的标题、日期、作者与正文内容会被再次包裹进default布局后者通常包含html、head、页头页脚等站点公共骨架。渲染时 Jekyll 先处理post.html的{{ content }}即博文正文再把结果作为content交给default布局形成层层嵌套。date_to_string过滤器详解代码中的date_to_string是 Jekyll 内置日期过滤器之一实现在 date_filters.rb。默认输出形如20 Aug 2018的短日期格式%d %b %Y比原始2018-08-20更易读。从源码看它还支持两个可选参数参数取值效果示例typeordinal输出序数词日期20th Aug 2018styleUS切换为美式月-日-年顺序Aug 20th, 2018即{{ page.date | date_to_string: ordinal, US }}可得到美式序数格式。同族过滤器还包括输出全月名长格式的date_to_long_string、供 XML 使用的date_to_xmlschema如2011-04-24T20:34:4608:00以及 RFC-822 格式的date_to_rfc822RSS 2.0 feed 常用。List posts用site.posts聚合文章列表目前博客页面还没有入口。与静态页面不同博文通常需要一个列表页来聚合展示。Jekyll 将全部已发布文章以数组形式暴露为site.posts按日期倒序、时间新者在前。在站点根目录创建blog.html--- layout: default title: Blog --- h1Latest Posts/h1 ul {% for post in site.posts %} li h2a href{{ post.url }}{{ post.title }}/a/h2 {{ post.excerpt }} /li {% endfor %} /ul这个列表页值得注意的要点均为原文档明确说明并由源码印证post.url由 Jekyll 自动生成是文章的输出路径。默认 permalink 风格为date在 configuration.rb 中映射为模板/:categories/:year/:month/:day/:title:output_ext即2018-08-20-bananas.md默认输出到/2018/08/20/bananas.html。最终 URL 的生成逻辑见 url.rb它依据template中的:year、:month、:day、:title、:categories等占位符拼接并做路径清理post.title取自文件名见上文populate_title可在 Front Matter 中用title覆盖post.excerpt默认是正文第一段。摘要Excerpt的底层实现post.excerpt的默认取段逻辑在 excerpt.rb 中实现def extract_excerpt(doc_content) head, _, tail doc_content.to_s.partition(doc.excerpt_separator) return head if tail.empty? ... end即用分隔符partition切分正文取前半部分。默认分隔符由 configuration.rb 设为\n\n两个连续换行因此默认摘要就是第一个空行之前的第一个段落。你可以自定义分隔符来精确定义摘要边界例如在_config.yml中excerpt_separator: !-- more --此时正文中的!-- more --之前的内容即为摘要。分隔符也可以在单篇博文的 Front Matter 中用excerpt_separator覆盖相关取值逻辑见 document.rb。源码还处理了一些边界情况若 Liquid 块标签中出现了分隔符Jekyll 会为摘要自动补全闭合标签并打印警告见 excerpt.rb并会把正文中引用到的 Markdown 链接引用定义追加到摘要之后避免链接失效。接入主导航博客列表页还没有入口。打开站点数据文件_data/navigation.yml位于你的站点根目录_data/下追加一条 Blog 记录- name: Home link: / - name: About link: /about.html - name: Blog link: /blog.html导航菜单中即会出现指向/blog.html的入口与 Home、About 并列。More posts扩充内容与本地预览单篇文章撑不起一个博客原文档建议继续添加更多博文以验证列表效果_posts/2018-08-21-apples.md--- layout: post author: jill --- An apple is a sweet, edible fruit produced by an apple tree. Apple trees are cultivated worldwide, and are the most widely grown species in the genus Malus. The tree originated in Central Asia, where its wild ancestor, Malus sieversii, is still found today. Apples have been grown for thousands of years in Asia and Europe, and were brought to North America by European colonists._posts/2018-08-22-kiwifruit.md--- layout: post author: ted --- Kiwifruit (often abbreviated as kiwi), or Chinese gooseberry is the edible berry of several species of woody vines in the genus Actinidia. The most common cultivar group of kiwifruit is oval, about the size of a large hens egg (5–8 cm (2.0–3.1 in) in length and 4.5–5.5 cm (1.8–2.2 in) in diameter). It has a fibrous, dull greenish-brown skin and bright green or golden flesh with rows of tiny, black, edible seeds. The fruit has a soft texture, with a sweet and unique flavor.启动本地服务jekyll serve后打开http://localhost:4000即可看到blog.html按时间倒序列出全部三篇文章bananas最旧排最后、kiwifruit最新排最前每篇均显示标题、日期作者行与第一段摘要。site.posts的排序由Document#比较器与集合的sort_docs!逻辑共同完成见 collection.rb。延伸日期优先级、发布控制与永久链接围绕博客主题源码还揭示了几个原文档未展开、但对实战至关重要的行为1. 日期来源的优先级_posts文件名中的日期会作为page.date的默认值document.rb 的modify_date但Front Matter 中显式声明的date拥有更高优先级可覆盖文件名日期。这常用于补发历史文章或修正时区影响。2. 发布控制与未来文章每篇博文是否真正发布由 publisher.rb 决定Front Matter 中published: false会阻止文章发布除非以--unpublished构建配置项future默认为falseconfiguration.rb日期晚于当前构建时间的文章默认不发布并在读取时打印has a future date警告见 post_reader.rb。若需要支持定时发布可在_config.yml中开启future: true或为集合单独配置future元数据。3. 永久链接风格post.url的形态完全由permalink配置决定。除默认的date外Jekyll 还内置了pretty/:categories/:year/:month/:day/:title/结尾无扩展名、利于短链接、ordinal按年中的第几天、weekdate按周、none/:categories/:title:output_ext等风格也可直接传入自定义模板如/:year/:title.html。自定义时需注意输出路径仍需与site.url配合避免站点内部链接错乱。小结至此一个完整的纯文本博客闭环已经建成_posts目录存放带日期的文章文件 → 文件名自动解析出日期、slug 与标题 →post布局渲染单篇页面并经default布局二次包裹 →blog.html通过site.posts聚合全部文章并展示标题、链接与摘要 → 导航文件接入入口。整个过程无数据库参与内容即文件。在此基础上下一教程步骤将聚焦为每篇文章作者创建独立页面即按author分组展示而 Jekyll 内置的site.tags、site.categories聚合能力实现在 site.rb 的post_attr_hash可作为继续探索的起点。想要验证本文所述行为可查看仓库测试 test_post_reader.rb 与 test_tag_post_url.rb以及test/source/_posts/下的真实测试文章夹具。【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价