Simple Jekyll plugin that enables including resources from non-Jekyll gems into the site build.
When enabled, the plugin scans certain, configurable parts of your _config.yml
file for references of the form "gem:package:path/in/package"
(or "gem:package/path/in/package"
) and replaces them with absolute paths to the correct Gem directory/file, using the Gem version specified in your Gemfile
/ Gemfile.lock
.
The origin of this plugin is that I wanted to build Bootstrap
from source using Jekyll's SASS processor and the boostrap gem. But there is no easy way to reference the external files of the bootstrap
gem
in your _config.yml
, except for using absolute paths, which feels unsatisfying for a number of reasons.
This plugin was born to resolve this problem, as described in this blog post.
This plugin is available as a RubyGem.
Add this line to your application's Gemfile
:
gem 'jekyll-gem-resoler'
And then execute the bundle
command to install the gem.
Alternatively, you can also manually install the gem using the following command:
$ gem install jekyll-gem-resolver
After the plugin has been installed successfully, add the following lines to your _config.yml
in order to tell Jekyll to use the plugin:
plugins:
- jekyll-gem-resolver
gem_resolver:
transform:
- sass.load_paths
A typical configuration could look like this:
# Excerpt from <your_directory>/Gemfile
source "https://rubygems.org"
# Or whatever version of Jekyll you are using
gem "jekyll", "~> 4.3.3"
# Declare the gems that you want to reference
gem "bootstrap", "~> 5.3.2"
group :jekyll_plugins do
gem "jekyll-gem-resolver", "~> 1.0"
end
# Excerpt from <your_directory>/_config.yml
plugins:
- jekyll-gem-resolver
# A configuration for another plugin that references files and/or folders from a Gem
sass:
load_paths:
- 'gem:bootstrap/assets/stylesheets'
# Tell jekyll-gem-resolver where in the configuration to look for
# "gem:" references. The format is explained below.
gem_resolver:
transform:
- sass.load_paths"
The usage of the plugin is split into two parts:
-
Specifying where in the configuration
gem:
paths might appear using a JSONPath-like language. -
Using a
gem:<..>
reference in those places in the configuration.
Gem references are written like this "gem:package_name:path/in/package"
(or "gem:package_name/path/in/package"
, if package_name
does not contain a '/'
character), which is resolved to something like:
/home/<your_username>/.gems/gems/<package_name>@<version_from_gemfile>/<path_in_package>
Note that you have to use double or single quotes around the gem:
references in your YAML file,
because without it, the gem:
prefix would erroneously be parsed as a hash by the YAML parer.
A path consists of multiple segments separated by a '.'
character.
Each segment is either:
- an identifier (e.g.
myplugin.config_setting
, for hash elements), - a number (e.g.
myplugin.items.1
, for array elements), or - the string
*
(e.g.myplugin.items.*.ident
, meaning "all elements of this array or hash").
Each segment can optionally be wrapped in [brackets]
,
which is just syntatic sugar for the same thing without brackets. By convention, we write array indidces and *
in brackets, and hash elements without:
my_plugin.array.[1]
my_plugin.array.[*]
my_plugin.hash.something
my_plugin.hash.[*]
When referring to all items of an array as the last segment of a path (e.g. my_plugin.array.[*]
), you can omit the final *
and just write it as: my_plugin.array
.
# You can process global settings
global_setting: "gem:example" # Matched by: "global-setting"
# You process items in arrays
global_array:
- "gem:package1/assets/js" # Matched by "global_array", "global_array.[*]" and "global_array.[0]"
- "gem:package2/assets/css" # Matched by "global_array", "global_array.[*]" and "global_array.[1]"
- "gem:package3/assets/js" # Matched by "global_array", "global_array.[*]" and "global_array.[2]"
# You can transform items in nested arrays as well
my_plugin:
- name: "I don't know"
children:
# Matched by:
# "my_plugin.[*].children"
# "my_plugin.[*].children.[*]"
# "my_plugin.[*].children.[1]
# "my_plugin.[0].children.[*]
# "my_plugin.[0].children.[1]"
- "gem:package1/assets/js"
- name: "I don't know either"
children:
# Matched by:
# "my_plugin.[*].children"
# "my_plugin.[*].children.[*]"
# "my_plugin.[*].children.[0]
# "my_plugin.[1].children.[*]
# "my_plugin.[1].children.[0]"
- "gem:package2/assets/css"
# Matched by:
# "my_plugin.[*].children"
# "my_plugin.[*].children.[*]"
# "my_plugin.[*].children.[1]
# "my_plugin.[1].children.[*]
# "my_plugin.[1].children.[1]"
- "gem:package3/assets/js"
# You can even process items in hashes
categories:
category_a:
# Matched by:
# "categories.category_a.template_styles
# "categories.[*].template_styles
template_styles: "gem:package4/templates/"
category_b:
# Matched by:
# "categories.category_a.template_styles
# "categories.[*].template_styles
template_styles: "gem:package4/templates/"
# Note that omission of the final ".[*]" only works for arrays,
# not for hashes:
my_other_plugin:
config_dict:
# The string values below are matched by "my_other_plugin.config_dict.[*]",
# but NOT by "my_other_plugin.config_dict".
entry_a: "gem:package5/abc"
entry_b: "gem:package5/def"
entry_c: "gem:package5/ghi"
Fork this repository, make your changes and then issue a pull request. If you find bugs or have new ideas that you do not want to implement yourself, file a bug report.
Copyright (c) 2024 Lukas Waslowski.
License: MIT