Hooks

使用 Hooks,您的外掛程式可以對建置程序的各個面向進行細微的控制。如果您的外掛程式定義任何 Hooks,Jekyll 會在預先定義的點呼叫它們。

Hooks 會註冊到一個擁有者和一個事件名稱。若要註冊一個,您可以呼叫 Jekyll::Hooks.register,並傳遞 Hook 擁有者、事件名稱和觸發 Hook 時要呼叫的程式碼。例如,如果您想在 Jekyll 每次渲染頁面時執行一些自訂功能,您可以這樣註冊一個 Hook

Jekyll::Hooks.register :pages, :post_render do |page|
  # code to call after Jekyll renders a page
end

注意:此後提到的 :post_convert 事件是 v4.2.0 中引入的功能。

開箱即用,Jekyll 已為擁有者預先定義掛鉤點 :site:pages:documents:clean。此外,為 :documents 定義的掛鉤點僅可透過呼叫集合類型來使用於個別集合。例如,:posts 用於集合 _posts 中的文件,而 :movies 用於集合 _movies 中的文件。在所有情況下,Jekyll 會以擁有者物件作為第一個回呼參數來呼叫您的掛鉤。

每個已註冊的掛鉤擁有者都支援以下事件 — :post_init:pre_render:post_convert:post_render:post_write — 不過,:site 擁有者已設定為回應特殊事件名稱。有關詳細資訊,請參閱後續部分。

所有 :pre_render 掛鉤和 :site, :post_render 掛鉤也會提供 payload hash 作為第二個參數。在 :pre_render 事件的情況下,payload 讓您能完全控制渲染期間可用的變數,而對於 :site, :post_render 事件,payload 會在渲染整個網站後包含最終值(適用於網站地圖、饋送等)。

內建掛鉤擁有者和事件

可用掛鉤的完整清單

擁有者 事件 觸發於

:site

涵蓋整個網站

:after_init

網站初始化後。適合修改網站組態。每個建置/服務階段觸發一次

:after_reset

重新產生期間,網站重設後

:post_read

所有原始檔已從磁碟讀取並載入後

:pre_render

整個網站渲染前

:post_render

整個網站渲染後,但寫入任何檔案前

:post_write

所有已渲染檔案寫入磁碟後

:pages

允許精細控制網站中的所有頁面

:post_init

每當頁面初始化時

:pre_render

渲染頁面前

:post_convert

轉換頁面內容後,但渲染頁面配置前

:post_render

渲染頁面後,但寫入磁碟前

:post_write

寫入頁面至磁碟後

:documents

允許精細控制網站中的所有文件,包括文章和使用者定義集合中的文件

:post_init

每當任何文件初始化時

:pre_render

渲染文件前

:post_convert

轉換文件內容後,但渲染文件配置前

:post_render

渲染文件後,但寫入磁碟前

:post_write

寫入文件至磁碟後

:posts

允許精細控制網站中的所有文章,而不影響使用者定義集合中的文件

:post_init

每當文章初始化時

:pre_render

渲染文章前

:post_convert

轉換文章內容後,但渲染文章配置前

轉換文章內容後,但渲染文章配置前

:post_render

渲染文章後,但寫入磁碟前

:post_write

寫入文章至磁碟後

:clean

在網站清理階段中,精細地控制已決定刪除的過時檔案清單。

:on_obsolete

在建置網站目的地之前,進行清理

自訂 Jekyll 物件的掛鉤

您也可以為外掛程式所引入的 Jekyll 物件註冊並觸發掛鉤。您只需要將 trigger 呼叫置於適當的 owner 名稱底下,並在自訂類別中放置於您想要的位置,然後由您的外掛程式註冊 owner 即可。

舉例來說,考慮以下外掛程式,它為每個初始化的自訂 Excerpt 物件實作自訂功能

module Foobar
  class HookedExcerpt < Jekyll::Excerpt
    def initialize(doc)
      super
      trigger_hooks(:post_init)
    end

    def output
      @output ||= trigger_hooks(:post_render, renderer.run)
    end

    def renderer
      @renderer ||= Jekyll::Renderer.new(
        doc.site, self, site.site_payload
      )
    end

    def trigger_hooks(hook_name, *args)
      Jekyll::Hooks.trigger :excerpts, hook_name, self, *args
    end
  end
end

Jekyll::Hooks.register :excerpts, :post_init do |excerpt|
  Jekyll.logger.debug "Initialized:",
                      "Hooked Excerpt for #{excerpt.doc.inspect}"
end

Jekyll::Hooks.register :excerpts, :post_render do |excerpt, output|
  return output unless excerpt.doc.type == :posts
  Foobar.transform(output)
end