尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
al-folio 博客列表页深度解析:Liquid 模板、分页、精选文章与标签归档的完整实现
al-folio 博客列表页深度解析Liquid 模板、分页、精选文章与标签归档的完整实现【免费下载链接】al-folioA beautiful, simple, clean, and responsive Jekyll theme for academics项目地址: https://gitcode.com/GitHub_Trending/al/al-folioal-folio 是一个面向学术工作者的 Jekyll 主题其博客功能由_pages/blog.md这个单文件模板驱动。本文以该文件为骨架逐段拆解其 Front Matter、分页配置、精选文章卡片、标签分类导航、文章列表渲染与外部博客源聚合机制并结合_config.yml、Gemfile与真实帖子示例如_posts/2015-07-15-code.md让你完全掌握这个列表页的每一行代码并能自由定制属于自己的学术博客首页。上图来自仓库readme_preview/目录是 al-folio 博客列表页的实际渲染效果。一、blog.md 在 al-folio 中的角色定位_pages/blog.md是 al-folio 站点的博客列表页Blog Index所有博客文章位于_posts/目录都通过这个页面统一聚合展示。它本身不包含任何正文内容全部页面结构都由 YAML Front Matter 和 Liquid 模板代码组成。文件开头定义了页面的基本属性--- layout: default permalink: /blog/ title: blog nav: true nav_order: 1 ---字段作用layout: default套用主题默认布局页面会包含导航栏、页脚等站点外壳permalink: /blog/固定该页面的最终 URL 为站点根路径下的/blog/title: blog页面标题同时用于浏览器标签与站点导航nav: true将该页面加入顶部导航栏nav_order: 1控制导航栏中的排序数字越小越靠前所以博客是 al-folio 默认导航的第一项正是因为nav: true与nav_order: 1访问站点首页时博客入口会出现在导航栏最显眼的位置。若想调整顺序只需修改nav_order的数值即可。二、Front Matter 中的分页配置jekyll-paginate-v2_pages/blog.md的 Front Matter 中嵌入了 al-folio 博客列表页的分页核心配置pagination: enabled: true collection: posts permalink: /page/:num/ per_page: 5 sort_field: date sort_reverse: true trail: before: 1 # The number of links before the current page after: 3 # The number of links after the current page这份配置由 Jekyll 官方分页插件的增强版 jekyll-paginate-v2 解析在 Gemfile 的:jekyll_plugins组中可以找到对应依赖gem jekyll-paginate-v2。各参数含义如下enabled: true开启分页。这是 jekyll-paginate-v2 的开关页面模板中会通过page.pagination.enabled判断是否使用分页数据源collection: posts分页的数据来源是posts集合即_posts/目录下所有文章permalink: /page/:num/第 2 页及之后的 URL 形如/blog/page/2/:num会被替换为页码per_page: 5每页展示 5 篇文章超过则自动翻页sort_field: date/sort_reverse: true按发布日期排序并倒序展示即最新的文章排在最前trail控制分页页码条两侧的链接数量。before: 1表示当前页之前显示 1 个页码链接after: 3表示当前页之后显示 3 个页码链接。在模板正文中分页的开关逻辑如下_pages/blog.md{% if page.pagination.enabled %} {% assign postlist paginator.posts %} {% else %} {% assign postlist site.posts %} {% endif %}也就是说当分页开启时文章列表的数据源是paginator.posts当前页对应的文章子集关闭分页后则退化为直接遍历site.posts全部文章。paginator对象由插件在构建期自动注入。三、页头区域blog_name 与 blog_description页面顶部通过一段条件判断决定是否显示博客名称与副标题{% assign blog_name_size site.blog_name | size %} {% assign blog_description_size site.blog_description | size %} {% if blog_name_size 0 or blog_description_size 0 %} div classheader-bar h1{{ site.blog_name }}/h1 h2{{ site.blog_description }}/h2 /div {% endif %}这里先计算site.blog_name与site.blog_description的字符长度只要任意一个非空就渲染页头区域。对应的配置位于_config.yml的# Blog区块blog_name: al-folio # blog_name will be displayed in your blog page blog_description: a simple whitespace theme for academics因此你只需要修改这两个字段即可为博客列表页换上自己的名称和一句话简介。将两者都置空则可以完全隐藏页头。四、标签与分类快捷导航display_tags / display_categories页头下方是一个标签/分类导航列表用于让访客快速跳转到特定主题的归档页{% if site.display_tags and site.display_tags.size 0 or site.display_categories and site.display_categories.size 0 %} div classtag-category-list ul classp-0 m-0 {% for tag in site.display_tags %} li i classfa-solid fa-hashtag fa-sm/i a href{{ tag | slugify | prepend: /blog/tag/ | relative_url }}{{ tag }}/a /li {% endfor %} {% for category in site.display_categories %} li i classfa-solid fa-tag fa-sm/i a href{{ category | slugify | prepend: /blog/category/ | relative_url }}{{ category }}/a /li {% endfor %} /ul /div {% endif %}注意这里的三个 Liquid 过滤器slugify把标签文本转换为 URL 友好的 slug如Sample Posts→sample-postsprepend: /blog/tag/拼出/blog/tag/slug的路径前缀relative_url自动补上站点baseurl在_config.yml中默认是/al-folio保证链接在子路径部署时依然正确。标签/分类列表项本身由_config.yml底部的display_tags与display_categories控制display_tags: [formatting, images, links, math, code, blockquotes] # these tags will be displayed on the front page of your blog display_categories: [external-services] # these categories will be displayed on the front page of your blog这些链接之所以能指向真实的归档页面是因为站点启用了 jekyll-archives-v2 插件Gemfile 中声明了gem jekyll-archives-v2并在_config.yml中配置了归档的 permalink 规则jekyll-archives: posts: enabled: [year, tags, categories] # enables year, tag and category archives permalinks: year: /blog/:year/ tags: /blog/:type/:name/ categories: /blog/:type/:name/其中:type会被替换为tag或category:name替换为具体的标签/分类名与模板中拼出的/blog/tag/...、/blog/category/...路径一一对应。模板中还使用pbull;/p作为条目之间的分隔符并用unless forloop.last保证最后一个条目后不出现多余的分隔点。五、精选文章Featured Posts卡片区列表页顶部会优先展示被标记为featured: true的精选文章。这段逻辑先过滤出全部精选文章再按数量决定卡片列数{% assign featured_posts site.posts | where: featured, true %} {% if featured_posts.size 0 %} br div classcontainer featured-posts {% assign is_even featured_posts.size | modulo: 2 %} div classrow row-cols-{% if featured_posts.size 2 or is_even 0 %}2{% else %}3{% endif %}列数规则可以拆解为精选文章数 2时使用 2 列文章数为偶数is_even 0时使用 2 列其他情况奇数且大于 2使用 3 列。这个设计保证了卡片区不会出现单列悬空的孤卡。每张精选卡片展示标题、描述、阅读时长与年份链接div classcard hoverable div classrow g-0 div classcol-md-12 div classcard-body div classfloat-right i classfa-solid fa-thumbtack fa-xs/i /div h3 classcard-title text-lowercase{{ post.title }}/h3 p classcard-text{{ post.description }}/p {% if post.external_source blank %} {% assign read_time post.content | number_of_words | divided_by: 180 | plus: 1 %} {% else %} {% assign read_time post.feed_content | strip_html | number_of_words | divided_by: 180 | plus: 1 %} {% endif %} {% assign year post.date | date: %Y %} p classpost-meta {{ read_time }} min read nbsp; middot; nbsp; a href{{ year | prepend: /blog/ | relative_url }} i classfa-solid fa-calendar fa-sm/i {{ year }} /a /p /div /div /div /div细节亮点包括右上角的图钉图标fa-thumbtack直观标识置顶精选阅读时长的估算公式为文章总词数 ÷ 180 1按每分钟阅读 180 词估算plus: 1用于向上取整兜底对于外部来源文章post.external_source非空改用post.feed_content抓取到的 RSS 正文计算词数并先strip_html去除 HTML 标签避免把标签当正文计数年份链接指向/blog/年份/正好对应 jekyll-archives 配置中的year: /blog/:year/归档页。仓库中现成的精选文章示例包括_posts/2015-07-15-code.md和_posts/2018-12-22-distill.md它们的 Front Matter 中都带有featured: true字段。你也可以在自己的文章 Front Matter 中加入同样的字段来置顶某篇文章。六、文章列表post-list的完整渲染逻辑精选区之后是博客的主体文章列表。对每一篇文章模板都会计算阅读时长、提取年份、拼接标签与分类字符串{% for post in postlist %} {% if post.external_source blank %} {% assign read_time post.content | number_of_words | divided_by: 180 | plus: 1 %} {% else %} {% assign read_time post.feed_content | strip_html | number_of_words | divided_by: 180 | plus: 1 %} {% endif %} {% assign year post.date | date: %Y %} {% assign tags post.tags | join: %} {% assign categories post.categories | join: %}tags post.tags | join: 的目的是把标签数组拼接成字符串以便用{% if tags ! %}判断文章是否声明了标签——空数组 join 后为空字符串从而跳过标签渲染。标题链接与 redirect 三级跳转文章标题链接的处理是整个列表页最精细的部分_pages/blog.mdh3 {% if post.redirect blank %} a classpost-title href{{ post.url | relative_url }}{{ post.title }}/a {% elsif post.redirect contains :// %} a classpost-title href{{ post.redirect }} target_blank{{ post.title }}/a svg ....../svg {% else %} a classpost-title href{{ post.redirect | relative_url }}{{ post.title }}/a {% endif %} /h3它按优先级处理三种情况post.redirect为空正常链接到站内文章页post.url | relative_urlpost.redirect包含://判定为外部绝对 URL新窗口打开target_blank并在标题旁渲染一个 SVG 外链箭头图标其他情况视为站内相对路径重定向套用relative_url后链接到该路径。这种设计让一篇文章既可以指向站内其他页面如_posts/2022-02-01-redirect.md演示的场景也可以直接外链到其他站点。元信息行时间、来源、年份、标签与分类p classpost-meta {{ read_time }} min read nbsp; middot; nbsp; {{ post.date | date: %B %d, %Y }} {% if post.external_source %} nbsp; middot; nbsp; {{ post.external_source }} {% endif %} /p p classpost-tags a href{{ year | prepend: /blog/ | relative_url }} i classfa-solid fa-calendar fa-sm/i {{ year }} /a {% if tags ! %} nbsp; middot; nbsp; {% for tag in post.tags %} a href{{ tag | slugify | prepend: /blog/tag/ | relative_url }} i classfa-solid fa-hashtag fa-sm/i {{ tag }}/a {% endfor %} {% endif %} {% if categories ! %} nbsp; middot; nbsp; {% for category in post.categories %} a href{{ category | slugify | prepend: /blog/category/ | relative_url }} i classfa-solid fa-tag fa-sm/i {{ category }}/a {% endfor %} {% endif %} /p日期格式为%B %d, %Y渲染如July 15, 2015若文章带有external_source外部来源名会追加在日期之后年份、标签fa-hashtag图标、分类fa-tag图标各自链接到对应的归档页。可选缩略图两列布局当文章 Front Matter 中声明了thumbnail字段时列表项切换为左文右图的两列布局{% if post.thumbnail %} div classrow div classcol-sm-9 {% endif %} !-- 标题与元信息 -- {% if post.thumbnail %} /div div classcol-sm-3 img classcard-img src{{ post.thumbnail | relative_url }} styleobject-fit: cover; height: 90% altimage /div /div {% endif %}文字占 9 列、缩略图占 3 列图片通过object-fit: cover与height: 90%保持裁剪比例统一。缩略图路径同样经过relative_url处理兼容子路径部署。七、聚合外部博客源external_sources 与 al_ext_postsal-folio 允许把 Medium、Google Blog 等外部博客的帖子聚合到同一列表页中这也是模板中反复出现post.external_source与post.feed_content的原因。配置位于_config.yml的# External sources区块external_sources: - name: medium.com rss_url: https://medium.com/al-folio/feed categories: [external-posts] tags: [medium] - name: Google Blog posts: - url: https://blog.google/technology/ai/google-gemini-update-flash-ai-assistant-io-2024/ published_date: 2024-05-14 categories: [external-posts] tags: [google]每种外部源支持两种数据来源rss_url提供 RSS Feed 地址站点构建时自动拉取并解析其中的文章posts直接列出具体文章的 URL 与发布日期。两种方式都可以配置默认的categories与tags让外部文章自动获得与站内文章一致的归档分类。这一能力的底层实现由 al-folio 自研插件al_ext_posts提供Gemfile 中gem al_ext_posts, 1.0.3。当列表页渲染外部文章时模板自动切换到feed_content计算阅读时长并在元信息行展示external_source如medium.com同时在标签区呈现为外部源配置的默认标签如medium。外部文章还会与站内文章一起参与分类归档——仓库中_config.yml的display_categories: [external-services]就是为此预留的分类入口。八、分页条组件与整体数据流文章列表渲染完毕后模板在末尾引入分页条组件{% if page.pagination.enabled %} {% include pagination.liquid %} {% endif %}pagination.liquid是 al-folio 主题内的分页导航组件由jekyll-paginate-v2的paginator对象驱动。它配合 Front Matter 中的trail.before: 1与trail.after: 3生成带前后页码的导航条。由此可以梳理出整个博客列表页的完整数据流_config.ymlblog_name / display_tags / display_categories / external_sources │ ▼ _pages/blog.mdFront Matter: pagination 配置 │ ├── site.blog_name / site.blog_description ──► 页头 header-bar ├── site.display_tags / display_categories ──► 标签分类导航 ├── site.posts | where: featured ──────────► 精选卡片区 ├── paginator.posts / site.posts ────────────► 文章列表 post-list └── pagination.liquid ───────────────────────► 分页条模板中每个区块的渲染都受_config.yml或文章 Front Matter 中对应字段控制改配置即可改变页面形态无需触碰模板代码。九、实战如何个性化你的博客列表页基于以上源码分析下面是针对常见需求的最小改动方案1. 更换博客名称与简介编辑_config.ymlblog_name: 我的学术博客 blog_description: 记录研究与工程实践2. 控制每页文章数量与分页样式修改_pages/blog.mdFront Matterpagination: enabled: true collection: posts permalink: /page/:num/ per_page: 10 # 每页 10 篇 sort_field: date sort_reverse: true trail: before: 2 # 当前页前显示 2 个页码 after: 2 # 当前页后显示 2 个页码3. 决定页头显示哪些标签与分类编辑_config.ymldisplay_tags: [research, tutorial, review] display_categories: [papers]4. 置顶某篇文章在目标文章的 Front Matter 中添加featured: true5. 为文章添加缩略图在文章 Front Matter 中声明thumbnail: assets/img/blog-thumb.jpg6. 聚合外部博客在_config.yml的external_sources列表中加入新源external_sources: - name: My Medium rss_url: https://medium.com/feed/my-account categories: [external-posts] tags: [medium]文章 Front Matter 字段速查表字段作用可选值示例title文章标题用于列表与标题链接A Post with Codedate发布日期参与排序与年份归档2015-07-15 15:09:00description列表页展示的文章摘要一句话描述tags标签数组链接到/blog/tag/slug/[formatting, code]categories分类数组链接到/blog/category/slug/[sample-posts]featured置顶为精选卡片trueredirect跳转目标支持站内路径与外部 URLhttps://...或/other-page/thumbnail列表页右侧缩略图路径assets/img/xxx.jpgexternal_source外部来源名由插件注入也可手动声明medium.com十、常见问题排查分页不生效所有文章堆在一页检查_pages/blog.mdFront Matter 中pagination.enabled是否为true并确认 Gemfile 中已包含jekyll-paginate-v2同时注意 jekyll-paginate-v2 要求_config.yml中也声明pagination: enabled: trueal-folio 已默认配置。标签/分类链接 404确认_config.yml中jekyll-archives的enabled列表包含tags与categories且 permalink 规则与模板中的/blog/tag/、/blog/category/前缀一致。精选区不显示检查文章 Front Matter 是否写入了字面量featured: true注意必须是布尔值true字符串true可能不被where过滤器匹配。外部文章阅读时长异常外部文章依赖feed_content字段确认external_sources的rss_url可正常访问且al_ext_posts插件Gemfile 中gem al_ext_posts, 1.0.3已启用。通过以上源码级拆解你现在应该能完全理解_pages/blog.md的每一段 Liquid 代码并能按需定制 al-folio 的博客列表页了。想要继续深入了解可以阅读 docs/CUSTOMIZE.md 中的站点定制章节或参考仓库 docs/ARCHITECTURE.md 了解整体架构设计。【免费下载链接】al-folioA beautiful, simple, clean, and responsive Jekyll theme for academics项目地址: https://gitcode.com/GitHub_Trending/al/al-folio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

本地化AI编程工作流:Claude Code与Codex CLI实战指南

本地化AI编程工作流:Claude Code与Codex CLI实战指南

1. 这不是魔法,是开发者正在用的“超能力”工作流最近在几个技术社区和内部开发群聊里,“superpowers”这个词出现频率高得有点反常——不是漫威新片预告,也不是某款游戏DLC名称,而是真实出现在终端命令行、IDE状态栏和团队协作文…

📅 2026/9/14 4:05:37
Greenplum 6.19.0源码编译与集群部署实战指南

Greenplum 6.19.0源码编译与集群部署实战指南

简介:Greenplum 6.19.0 完整源码包面向数据库内核开发者、数据平台运维人员及希望深入理解MPP架构的进阶学习者。作为全球首个开源、多云大数据分析平台,Greenplum在经典与实时数据分析产品中占据独特地位,源码可用于二次开发、编译部署及源码…

📅 2026/9/14 4:05:37
C#入门必读:六个小游戏源码逐行拆解,从游戏循环到碰撞判定

C#入门必读:六个小游戏源码逐行拆解,从游戏循环到碰撞判定

简介:一套面向C#初学者的七合一游戏开发实战资源,包含飞机大战、俄罗斯方块、贪吃蛇、拼图游戏、连连看、五子棋等经典小游戏完整项目,所有代码均配有详细注释,覆盖窗体设计、游戏循环、碰撞检测、坐标变换、事件监听等核心知识点…

📅 2026/9/14 4:00:37
MORE NEWS

更多资讯

📰

从零搭建基于RAG的本地知识库:llm_wiki架构与调优实践

1. 传统Wiki为什么最后都变成了“僵尸库”1.1 传统知识库的三个死穴先说一个很多团队都遇到过的场景:刚搭建知识库的时候热情高涨,分工明确,文档模板都设计得漂漂亮亮,目录结构三层起步。一个月后,更新频率开始下降&am…

📰

yq 递归下降(Recursive Descent / Glob)操作符 `..` 与 `...` 完全指南

yq 递归下降(Recursive Descent / Glob)操作符 .. 与 ... 完全指南 【免费下载链接】yq yq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor 项目地址: https://gitcode.com/GitHub_Trending/yq/yq 本文以 …

📰

SDL3 iOS 开发指南:基于 SDL3.xcframework 与 Xcode 工程的构建、集成与系统级适配

SDL3 iOS 开发指南:基于 SDL3.xcframework 与 Xcode 工程的构建、集成与系统级适配 【免费下载链接】SDL Simple DirectMedia Layer 项目地址: https://gitcode.com/GitHub_Trending/sd/SDL Simple DirectMedia Layer(SDL3)为 iOS、tv…

📰

Claude Code 配 TaoToken:调通 Prompt Caching 的 cache_control 缓存断点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

GLM-5.3-Flash实测:多模态应用成本降至1/40的落地指南

最近大模型圈子有个很明显的风向:拼参数的年代正在过去,拼落地成本的年代已经来了。我手里刚拿到 GLM-5.3-Flash 的测试权限,深度跑了大概两周,从基础的图文理解到复杂的长视频解析,再到结合 RAG 的知识库问答&#xf…

📰

MuJoCo MJX Barkour v0 四足模型解析:为 JAX 后端定制的高动态四足机器人 MJCF 配置

MuJoCo MJX Barkour v0 四足模型解析:为 JAX 后端定制的高动态四足机器人 MJCF 配置 【免费下载链接】mujoco Multi-Joint dynamics with Contact. A general purpose physics simulator. 项目地址: https://gitcode.com/GitHub_Trending/mu/mujoco 本文以 M…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬