debbbbie Writings

深藏功与名

Follow me onGitHub

Jekyll 文档翻译之插件

Jekyll 支持插件功能,你可以很容易的加入自己的代码。

在 GitHub Pages 使用插件

GitHub Pages是由Jekyll提供技术支持的,考 虑到安全因素,所有的 Pages 通过 --safe 选项禁用了插件功能,因此如果你的网 站部署在 Github Pages ,那么你的插件不会工作。

不过仍然有办法发布到 GitHub Pages,你只需在本地做一些转换,并把生成好的文件上传到 Github 替代 Jekyll 就可以了。

安装插件

在网站根下目录建立 _plugins 文件夹,插件放在这里即可。 Jekyll 运行之前,会加载此目录下所有以 *.rb 结尾的文件。

通常,插件最终会被放在以下的目录中:

  1. Generators
  2. Converters
  3. Tags

生成

你可以像下边这样编写一个生成器:

module Jekyll

  class CategoryPage < Page
    def initialize(site, base, dir, category)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'

      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'category_index.html')
      self.data['category'] = category

      category_title_prefix = site.config['category_title_prefix'] || 'Category: '
      self.data['title'] = "#{category_title_prefix}#{category}"
    end
  end

  class CategoryPageGenerator < Generator
    safe true

    def generate(site)
      if site.layouts.key? 'category_index'
        dir = site.config['category_dir'] || 'categories'
        site.categories.keys.each do |category|
          site.pages << CategoryPage.new(site, site.source, File.join(dir, category), category)
        end
      end
    end
  end

end

本例中,生成器在 categories 下生成了一系列文件。并使用布局 category_index.html 列出所有 的文章。

生成器只需要实现一个方法:

Method Description

generate

String output of the content being generated.

转换器

如果想使用一个新的标记语言,可以用你自己的转换器实现,Markdown 和 Textile 就是这样实现的。

记住你的 YAML 头信息

Jekyll 只会转换带有 YAML 头信息的文件,即使你使用了插件也不行。

下边的例子实现了一个转换器,他会用 UpcaseConverter 来转换所有以 .upcase 结尾的文件。

module Jekyll
  class UpcaseConverter < Converter
    safe true
    priority :low

    def matches(ext)
      ext =~ /^\.upcase$/i
    end

    def output_ext(ext)
      ".html"
    end

    def convert(content)
      content.upcase
    end
  end
end

转换器需要最少实现以下 3 个方法:

方法 描述

matches

检查文件后缀名是否是所要的,传入的参数是文件的后缀名(包括点号),接受的返回值是 truefalse

output_ext

生成文件的后缀名(包括点号),通常是 ".html"

convert

转换逻辑,传入原始文件内容(不包含YAML头信息),返回值需要是 String 。

在上边的例子中, UpcaseConverter#matches 检查文件后缀名是不是 .upcase ; UpcaseConverter#convert 会处理检查成功文件的内容,即将所有的字符串变成大写;最终,保存的结果 将以作为后缀名 .html

标记

如果你想使用 liquid 标记,你可以这样做。 Jekyll 官方的例子有 highlightinclude 等 标记。下边的例子中,自定义了一个 liquid 标记,用来输出当前时间:

module Jekyll
  class RenderTimeTag < Liquid::Tag

    def initialize(tag_name, text, tokens)
      super
      @text = text
    end

    def render(context)
      "#{@text} #{Time.now}"
    end
  end
end

Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)

liquid 标记最少需要实现如下方法:

方法 描述

render

输出标记的内容。

你必须同时用Liquid模板引擎注册自定义标记,比如::

Liquid::Template.register_tag('render_time', Jekyll::RenderTimeTag)

对于上边的例子,你可以把如下标记放在页面的任何位置:

<p>{% render_time page rendered at: %}</p>

我们在页面上会得到如下内容:

<p>page rendered at: Tue June 22 23:38:47 –0500 2010</p>

Liquid 过滤器

你可以像上边那样在 Liquid 模板中加入自己的过滤器。过滤器会把自己的方法暴露给 liquid 。所有的方法 都必须至少接收一个参数,用来传输入内容;返回值是过滤的结果。

module Jekyll
  module AssetFilter
    def asset_url(input)
      "http://www.example.com/#{input}?#{Time.now.to_i}"
    end
  end
end

Liquid::Template.register_filter(Jekyll::AssetFilter)
提示™:用 Liquid 访问 site 对象

Jekyll 允许通过 Liquid 的context.registers 特性来访问 site 对象。比如可以用 context.registers.config 访问配置文件 _config.yml

Flags

当写插件时,有两个标记需要注意:

标记 描述

safe

告诉 Jekyll 此插件是否可以安全的执行任意代码。 GitHub Pages 用他来决定那个插件可以 使用,哪些不可以使用。如果你的插件不允许执行任意代码,把它设为 true 即 可。 GitHub Pages 仍然不会加载你的插件,但是如果你把他夹杂到核心中,最后保证此值设置 的正确!

priority

此标记决定加载插件的顺序。可以是这些值: :lowest, :low, :normal:high ,还有 :highest。 优先级高的先执行,优先级低的后执行。

已上边例子的插件为例,应该这样设置这两个标记:

module Jekyll
  class UpcaseConverter < Converter
    safe true
    priority :low
    ...
  end
end

可用的插件

下边的插件,你可以按需所取:

生成器

转换器

过滤器

标签

集合

其他

期待你的作品

如果你有一个 Jekyll 插件并且愿意加到这个列表中来,可以阅读此须知,并参照着来做。