You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jekyll中创建带自定义上下文的Block Tag查询数据对象

如何在Jekyll中创建根据ID查找对象的自定义Block Tag

首先先确认你的_data/array.yml格式要正确,每个对象的键值对需换行缩进,不然Jekyll没法正确解析:

- id: id1
  name: name1
- id: id2
  name: name2

接下来我们把你写的ItemBlock类补全,实现根据指定ID查找对象并传入上下文的功能:

module Jekyll
  class ItemBlock < Liquid::Block
    def initialize(tag_name, markup, tokens)
      super
      # 提取标记中的ID,去掉前后多余空格
      @item_id = markup.strip
    end

    def render(context)
      # 获取Jekyll的site核心对象
      site = context.registers[:site]
      # 从_data/array.yml中匹配对应ID的项
      item = site.data['array'].find { |item| item['id'] == @item_id }

      # 先保存上下文中原有的item变量(避免覆盖原有数据)
      original_item = context['item']
      # 将找到的目标项传入模板上下文
      context['item'] = item if item

      # 渲染块内的模板内容,此时上下文已包含目标item
      content = super(context)

      # 恢复原来的item变量,防止污染后续模板渲染
      context['item'] = original_item

      content
    end
  end
end

# 注册自定义Block Tag,让Liquid能识别{% item %}标签
Liquid::Template.register_tag('item', Jekyll::ItemBlock)

代码细节解释:

  1. initialize方法:

    • 调用super继承Liquid::Block的基础初始化逻辑
    • 把传入的标记内容(比如示例里的id1)清理掉前后空格,保存为@item_id,后续用来匹配数组项
  2. render方法:

    • 通过context.registers[:site]拿到Jekyll的site实例,以此访问site.data下的数组数据
    • 用find方法遍历数组,精准匹配id一致的对象
    • 先缓存上下文中原有的item变量(如果存在的话),避免自定义逻辑覆盖原有模板变量
    • 将找到的对象赋值给上下文的item,这样块标签内部就能用{{ item.name }}直接访问属性
    • 调用super(context)渲染块内的模板内容,此时上下文已经携带了目标item
    • 最后恢复原来的item变量,保证后续模板渲染不受影响

示例用法:

你可以像这样在模板中使用这个自定义标签:

{% item id1 %}
  <p>数组总长度:{{ site.data.array.length }}</p>
  <p>当前项名称:{{ item.name }}</p>
{% enditem %}

渲染后的HTML会是:

<p>数组总长度:2</p>
  <p>当前项名称:name1</p>

如果指定的ID不存在,item会是nil,此时{{ item.name }}不会输出任何内容。你也可以在render方法里加个判断逻辑,比如没找到时输出提示信息,或者直接返回空内容,完全可以根据自己的需求调整。

内容的提问来源于stack exchange,提问作者kbariotis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:38:04