Generators

You can create a generator when you need Jekyll to create additional content based on your own rules.

A generator is a subclass of Jekyll::Generator that defines a generate method, which receives an instance of Jekyll::Site. The return value of generate is ignored.

Generators run after Jekyll has made an inventory of the existing content, and before the site is generated. Pages with front matter are stored as instances of Jekyll::Page and are available via site.pages. Static files become instances of Jekyll::StaticFile and are available via site.static_files. See the Variables documentation page and Jekyll::Site for details.

For instance, a generator can inject values computed at build time for template variables. In the following example, the template reading.html has two variables ongoing and done that are filled in the generator:

module Reading
  class Generator < Jekyll::Generator
    def generate(site)
      ongoing, done = Book.all.partition(&:ongoing?)

      reading = site.pages.detect {|page| page.name == 'reading.html'}
      reading.data['ongoing'] = ongoing
      reading.data['done'] = done
    end
  end
end

The following example is a more complex generator that generates new pages. In this example, the generator will create a series of files under the categories directory for each category, listing the posts in each category using the category_index.html layout.

module Jekyll
  class CategoryPageGenerator < Generator
    safe true

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

  # A Page subclass used in the `CategoryPageGenerator`
  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
end

Generators need to implement only one method:

Method Description

generate

Generates content as a side-effect.

If your generator is contained within a single file, it can be named whatever you want but it should have an .rb extension. If your generator is split across multiple files, it should be packaged as a Rubygem to be published at https://rubygems.org/. In this case, the name of the gem depends on the availability of the name at that site because no two gems can have the same name.

By default, Jekyll looks for generators in the _plugins directory. However, you can change the default directory by assigning the desired name to the key plugins_dir in the config file.

© 2020 Jekyll Core Team and contributors
Licensed under the MIT license.
https://jekyllrb.com/docs/plugins/generators/