Flexible_include
is a Jekyll plugin that includes the contents of a file
or the result of a process into a generated page.
Flexible_include
is useful because Jekyll's built-in include
tag only
supports the including of files residing within the _includes/
subfolder of a Jekyll project,
and because flexible_include
offers additional ways of including content.
Originally called include_absolute
,
this plugin has been renamed to flexible_include
because it no longer just
includes absolute file names.
This plugin is available as a Ruby gem. More information is available on my website about my Jekyll plugins.
This plugin supports 4 types of includes:
-
Absolute filenames (recognized by filename paths that start with
/
). -
Filenames relative to the top-level directory of the Jekyll website (relative paths do not start with
.
or/
). -
Filenames relative to the user home directory (recognized by filename paths starting with
~/
). -
Executable filenames on the
PATH
(recognized by filename paths that begin with!
).
In addition, filenames that require environment expansion because they contain a
$
character are expanded according to the environment variables
defined when jekyll build
executes.
A file from a git repository can also be included. Files can be retrieved from at a given commit or tag. Two new options are provided for this purpose:
repo
- directory where git repo resides; environment variables are expanded; defaults to current directory.git_ref
- Git ref of commit or tag to be examined for the file; defaults toHEAD
.
Configuration parameters can be added to a section in _config.yml
called flexible_include
, like this:
flexible_include:
die_on_file_error: true
die_on_path_denied: true
die_on_run_error: true
die_on_other_error: true
The default values for all of these parameters is false
,
except for die_on_other_error
, which defaults to true
.
-
If
die_on_file_error
is enabled, then an attempt to include a file that fails will cause Jekyll to die with an error message. -
If
die_on_path_denied
is enabled (see Restricting Directory Access), then an attempt to include a file that should be blocked will cause Jekyll to die with an error message. -
If
die_on_run_error
is enabled, then an attempt to run a process that fails will cause Jekyll to die with an error message. -
If
die_on_other_error
is enabled, then any other exception will cause Jekyll to die with an error message.
The following are all equivalent, however, the first two are recommended:
{% flexible_include file="path" [ OPTIONS ] %}
{% flexible_include file='path' [ OPTIONS ] %}
{% flexible_include path [ OPTIONS ] %}
{% flexible_include 'path' [ OPTIONS ] %}
{% flexible_include "path" [ OPTIONS ] %}
Note that the [square brackets] merely indicate optional parameters and are not intended to be written literally.
-
attribution
seejekyll_plugin_support
-
do_not_escape
keyword option caused the content to be included without HTML escaping it. By default, the included file will escape characters<
,{
and}
unless thedo_not_escape
keyword option is specified. -
from='regex'
specifies that the beginning of the output should discarded until the matching string or regex is encountered. -
highlight='regex pattern here'
wraps content matching the regex pattern within a<span class='bg_yellow'></span>
tag. Note that the pattern can simply consist of the exact text that you want to highlight. -
pre
is a keyword option that causes the included file to be wrapped inside a <pre></pre> tag; no label is generated. The <pre></pre> tag has andata-lt-active="false"
attribute, so LanguageTool will not attempt to check the spelling or grammar of the contents. -
to='regex'
specifies that the output should discarded after the matching string or regex is encountered (includes the matched line). -
until='regex'
specifies that the output should discarded after the matching string or regex is encountered (excludes the matched line).
The following options imply pre
:
-
dark
keyword option applies thedark
class to the generated <pre></pre> tag. You can define thedark
anddarkLabel
classes as desired. This CSS is a good starting point. -
download
keyword option uses the name of the file as a label, and displays it above the <pre></pre> tag. Clicking the label causes the file to be downloaded. -
copyButton
keyword option draws an icon at the top right of the <pre></pre> tag that causes the included contents to be copied to the clipboard. -
label
keyword option specifies that an automatically generated label be placed above the contents. There is no need to specify this option ifdownload
orcopy_button
options are provided. -
label="blah blah"
specifies a label for the contents; this value overrides the default label. The value can be enclosed in single or double quotes.
By default, flexible_include
can read from all directories according to the permissions of the
user account that launched the jekyll
process.
For security-conscience environments, the accessible paths can be restricted.
Defining an environment variable called FLEXIBLE_INCLUDE_PATHS
prior to launching Jekyll will
restrict the paths that flexible_include
will be able to read from.
This environment variable consists of a colon-delimited set of
file and directory glob patterns.
For example, the following restricts access to only the files within:
-
The
~/my_dir
directory tree of the account of the user that launched Jekyll. -
The directory tree rooted at
/var/files
. -
The directory tree rooted at the expanded value of the
$work
environment variable.
export FLEXIBLE_INCLUDE_PATHS='~/.*:$sites/.*:$work/.*'
Note that the above matches dot (hidden) files as well as regular files. To just match visible files:
export FLEXIBLE_INCLUDE_PATHS='~/my_dir/**/*:/var/files/**/*:$work/**/*'
The specified directories are traversed when the plugin starts, and the filenames are stored in memory. Directories with lots of files might take a noticable amount of time to enumerate the files.
By default, flexible_include
can execute any command.
You can disable that by setting the environment variable DISABLE_FLEXIBLE_INCLUDE
to any non-empty value.
export DISABLE_FLEXIBLE_INCLUDE=true
If a potential command execution is intercepted,
a big red message will appear on the generated web page that says
Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.
,
and a red error message will be logged on the console that says something like:
ERROR FlexibleInclude: _posts/2020/2020-10-03-jekyll-plugins.html - Arbitrary command execution denied by DISABLE_FLEXIBLE_INCLUDE value.
-
Add the following to
Gemfile
, inside thejekyll_plugins
group:group :jekyll_plugins do gem 'jekyll_flexible_include', '~> 2.0.15' end
-
Add the following to
_config.yml
. This is necessary because the name of the plugin does not match the name of the entry point file:plugins: - flexible_include
-
Copy
demo/assets/images/clippy.svg
to a directory that resolves toassets/images/
in your Jekyll website. -
Copy the CSS from
demo/assets/css/jekyll_flexible_include.css
to your Jekyll project's CSS file. -
Install the
jekyll_flexible_include
Ruby gem and mark it as a dependency of your project:$ bundle
-
Include files, escaping any HTML markup, so it appears as written; all four types of includes are shown.
{% flexible_include '../../folder/outside/jekyll/site/foo.html' %} {% flexible_include 'folder/within/jekyll/site/bar.js' %} {% flexible_include '/etc/passwd' %} {% flexible_include '~/.ssh/config' %} {% flexible_include '!jekyll help' %} {% flexible_include '$HOME/.bash_aliases' %}
-
Include a JSON file (without escaping characters).
{% flexible_include do_not_escape file='~/folder/under/home/directory/foo.html' %}
More information is available on Mike Slinn’s website.
GitHub Pages only allows these plugins.
That means flexible_include
will not work on GitHub Pages.
Following is a workaround.
-
Let's assume your git repository that you want to publish as GitHub Pages is called
mysite
. This repository cannot be the source of your GitHub Pages because you are using theflexible_include
plugin. -
Make a new git repository to hold the generated website. Let's call this git repository
generated_site
. -
Generate
mysite
locally as usual. -
Copy the generated HTML in the
mysite/_site/
directory togenerated_site
. -
Run
git commit
ongenerated_site
. -
Tell GitHub that you want the
generated_site
repository to hold your GitHub pages. -
A moment later, your website will now be visible as GitHub Pages, with the included content, just as you saw it locally.
If the plugin does not work:
-
Ensure
_config.yml
doesn't havesafe: true
set. That prevents all plugins from working. -
If you have version older than v2.x.x, delete the file
_plugins/flexible_include.rb
, or you will have version conflicts.
After checking out the repo, run bin/setup
to install dependencies as binstubs in the exe
directory.
You can also run bin/console
for an interactive prompt that will allow you to experiment.
To build and install this gem onto your local machine, run:
$ bundle exec rake install
Examine the newly built gem:
$ gem info jekyll_flexible_include
*** LOCAL GEMS ***
jekyll_flexible_include (2.0.4)
Authors: Mike Slinn, Tan Nhu, Maarten Brakkee
Homepage: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#flexibleInclude
License: MIT
Installed at (2.0.4): /home/mslinn/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0
Jekyll plugin supports various ways to include content into the
generated site.
A test/demo website is provided in the demo
directory.
You can run it under a debugger, or let it run free.
The demo/_bin/debug
script can set various parameters for the demo.
View the help information with the -h
option:
$ demo/_bin/debug -h
debug - Run the demo Jekyll website.
By default the demo Jekyll website runs without restriction under ruby-debug-ide and debase.
View it at http://localhost:4444
Options:
-e Restrict the allowable directories to read from to the following regexes:
jekyll_flexible_include_plugin/.*
/dev/.*
/proc/.*
/run/.*
-h Show this error message
-r Run freely, without a debugger
-x Disable the ability to execute arbitrary commands
To run under a debugger, for example Visual Studio Code:
-
Set breakpoints.
-
Initiate a debug session from the command line:
$ demo/bin/debug
-
Once the
Fast Debugger
signon appears, launch the Visual Studio Code launch configuration calledAttach rdbg
. -
View the generated website at
http://localhost:4444
.
To release a new version,
-
Update the version number in
version.rb
. -
Add a comment to the top of
CHANGELOG.md
. -
Commit all changes to git; if you don't the next step will fail.
-
Run the following:
$ bundle exec rake release
The above creates a git tag for the version, commits the created tag, and pushes the new
.gem
file to RubyGems.org.
- Fork the project
- Create a descriptively named feature branch
- Add your feature
- Submit a pull request
The gem is available as open source under the terms of the MIT License.