【问题标题】:Jekyll custom collection hookJekyll 自定义收集钩子
【发布时间】:2018-04-20 09:07:23
【问题描述】:

这个问题困扰了我一段时间。

生成的 Jekyll 站点确实在所需页面上显示了正确的集合及其所有信息。但是除了(默认)posts 集合之外的所有集合都不能在 ruby​​ 插件中使用。

案例:

我们有一个使用 Jekyll 的博客网站。 为了用作者信息丰富博客文章,反之亦然,有一些自定义插件使用Jekyll::Hooks.register

博客文章是用 Markdown 语言编写的,并且都包含一些 YAML 格式的信息:

---
layout: post
authors: [author]
title: 'title'
intro: a short intro text
image: /path/to/image.png
tags: [jekyll, collections]
category: Programming
comments: true
---

这是用作者信息丰富帖子的代码:

Jekyll::Hooks.register :site, :post_read do |site|
    puts 'Enriching posts with link to authors'

    site.posts.docs.each { |post|
        post.data['authors'].collect! { |author_username|
            site.data['authors'][author_username]
        }.compact!
    }
end

下一步:

我在网站上更新了两个集合,因为我们还想展示将要提供的培训课程和讲座。

两个集合都包含一些 Markdown 格式的文件,文件顶部有相同类型的 YAML 信息。

---                               ---
layout: talk                      layout: training
speakers: [author]                trainers: [author]
title: Title                      title: Title
subtitle: Subtitle                subtitle: Subtitle
duration: 120 minutes             duration: 180 minutes
level: beginner                   level: intermediate
image: /path/to/image.png         image: /path/to/image.png
tags: []                          tags: []
category: Talks                   category: Training
comments: false                   comments: false
---                               ---

我将收藏添加到_config.yml

collections:
  training:
      output: true
      permalink: /training/:path/
  talks:
      output: true
      permalink: /talks/:path/

defaults:
  - scope:
      path: "training"
      type: training
    values:
      layout: training
  - scope:
      path: "talks"
      type: talks
    values:
      layout: talk

期望的实现:

现在我也想丰富与作者的讲座和培训课程。

由于帖子、演讲和培训文件都在一个集合中,我假设将posts 对象更改为talkstraining 应该获得所需的对象并循环它们。

所以我把自定义插件改成这样:

Jekyll::Hooks.register :site, :post_read do |site|
    puts 'Enriching posts with link to authors'

    site.posts.docs.each { |post|
        post.data['authors'].collect! { |author_username|
            site.data['authors'][author_username]
        }.compact!
    }

    site.talks.docs.each { |talk|
        talk.data['authors'].collect! { |author_username|
            site.data['authors'][author_username]
        }.compact!
    }
end

然后我得到这个错误:

jekyll 3.7.3 | Error:  undefined method `talks' for #<Jekyll::Site:0x00007f9325268e90>

困扰我的是,当我记录集合内容时,我得到以下结果:(格式化为 json 结构以获得更好的可读性)

{
  "posts"=>
    #<Jekyll::Collection @label=posts docs=[
      #<Jekyll::Document _posts/2017-02-01-page1.md collection=posts>, 
      #<Jekyll::Document _posts/2017-02-02-page2.md collection=posts>,
      #<Jekyll::Document _posts/2018-04-04-page3.md collection=posts>
    ]>, 
  "training"=>
    #<Jekyll::Collection @label=training docs=[
      #<Jekyll::Document _training/page1.md collection=training>, 
      #<Jekyll::Document _training/page2.md collection=training>, 
      #<Jekyll::Document _training/page3.md collection=training>
    ]>, 
  "talks"=>
    #<Jekyll::Collection @label=talks docs=[
      #<Jekyll::Document _talks/page1.md collection=talks>, 
      #<Jekyll::Document _talks/page2.md collection=talks>, 
      #<Jekyll::Document _talks/page3.md collection=talks>
    ]>
}

据我所知,talkstraining 集合与 posts 集合处于同一级别和数据结构中。

问题:

如何在我的自定义插件中获取会谈/培训集合,以便我可以使用作者信息丰富数据。

为了便于阅读,我减少了文件和输出。完整代码库可在 GitHub

获得

【问题讨论】:

    标签: ruby collections jekyll hook


    【解决方案1】:

    你必须查看site.collections

    这可以解决问题:

    Jekyll::Hooks.register :site, :post_read do |site|
    
        ['posts', 'talks'].each do collection{
            site.collections[collections].docs.each { |talk|
                talk.data['authors'].collect! { |author_username|
                    site.data['authors'][author_username]
                }.compact!
            }
        }
    
    end
    

    【讨论】:

    • 这没有成功,但你让我朝着正确的方向前进!谢谢你。
    【解决方案2】:

    David 为我指明了正确的方向。

    我不得不遍历集合

    site.collections.each do |collection|
      collection.each do |item|
        if item.respond_to?("each")
          item.docs.each do |post|
            if post.data['authors']
              post.data['authors'].collect! { |author_username|
                site.data['authors'][author_username]
              }.compact!
            end
          end
        end
      end
    end
    

    我仍然觉得奇怪的是 site 对象上没有其他集合。

    但这对我有用。

    【讨论】:

      猜你喜欢
      • 2013-05-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      • 1970-01-01
      • 1970-01-01
      • 2020-08-27
      • 2020-08-04
      • 2019-06-15
      相关资源
      最近更新 更多