Jekyll: How to use custom plugins with GitHub pages?
Asked Answered
F

5

24

It turns out that custom ruby plugins don't work on GitHub pages because of security concerns.

I'm trying to add a plugin (this one) to the _plugins folder of my Jekyll project, but when I deploy it to GitHub it is ignored.

Question: Is there a way to workaround this? Has anyone found a solution?

Note: Obviously I can generate html files locally and commit them to my repository. But that's not what I want.

Frumpy answered 8/11, 2018 at 20:6 Comment(3)
You can use an hosting like Netlify.Isolde
Move to Gitlab pages today!Vittoria
Hey Sasha, would you consider accept an answer? yegor256's one was helpful to my searchLimitless
C
7

Without a plugin

A reading time script does not require a plugin. I have created a collection of scripts that can be added without using a plugin. You can find them here. A reading time script is one of them.

Here you find the code:

{% capture words %}
{{ content | number_of_words | minus: 180 }}
{% endcapture %}
{% unless words contains '-' %}
{{ words | plus: 180 | divided_by: 180 | append: ' minutes to read' }}
{% endunless %}

Note that this code contains only Liquid and no Ruby. Therefore it can be used in your layout or in an include (without a plugin).

Optimizing the script

Suppose you have something like this:

<p>lorem ipsum</p>
<p>lorem ipsum</p>
<code>lorem ipsum</code>
<p>lorem ipsum</p>
<code>lorem ipsum</code>
<p>lorem ipsum</p>

Then you could remove the above code blocks like this:

{% assign preprocessed_content=post.content | replace: '<p>', '__p__' %}
{% assign preprocessed_content=preprocessed_content | replace: '</p>', '__/p__' %}
{% assign truncated_content=preprocessed_content | strip_html %}
{% assign cleaned_content=truncated_content | replace: '__p__', '<p>' %}
{% assign cleaned_content=cleaned_content | replace: '__/p__', '</p>' %}

Ofcourse this can be extended to support more tags.

Using the plugin anyway

If you REALLY want to use a plugin you can let your local machine or CloudCannon build your site and push the result to Github Pages. See also: https://learn.cloudcannon.com/jekyll/using-jekyll-plugins/

Cruet answered 11/11, 2018 at 18:3 Comment(7)
Thank you. number_of_words was the first thing I tried. Unfortunately it doesn't satisfy my needs. My articles often contain code blocks but number_of_words doesn't provide any mechanism to filter page content. Excluding code, pre, script etc might help but it is currently not possible. That's why for some articles it shows 2-3times more words than needed. Do you know how to fix this?Frumpy
You could try to split your content on code blocks. Are you sure that you can read code faster than normal words? I would say the opposite is true.Cruet
It is not about performance. I don't want my code to be included to words count, it doesn't make sense. For instance, this article of mine sashashpota.com/2018/10/30/… contains around 800 words, but number_of_words shows 1400 words as it counts code blocks as well.Frumpy
No, it is not about performance. It is about the speed at which humans read text and code. I do not think that you can read code faster than normal words/text. Code blocks are no images and should not be considered as such (IMO).Cruet
I see your point and probably it works in many cases. But I think that in my case a user doesn't need to read the code word-by-word, they might just copy and paste it. Or in case if there is a log it is also nor required to read it, you can just quickly go through. But there is more than just code - if I remove images from my article number_of_words shows 25 symbols less. Did I remove some words? I guess not. I think number_of_words is good for some very basic cases, but not in my case. At the same time the plugin I mentioned in the question covers all corner cases. I wish I could use it.Frumpy
Only 25 characters? Probably in one word. That adds less than 1 second to the reading time. I think you are trying very hard to find a reason to use a plugin. However, you can easily use plugins if you let your local machine or CloudCannon build your site/plugin code and push the result to Github Pages. See also: learn.cloudcannon.com/jekyll/using-jekyll-pluginsCruet
Thank you for suggesting replace and strip_html. I solved my problem using your suggestion github.com/Shpota/shpota.github.io/commit/… It is not ideal but it works.Frumpy
G
5

If you want to use your custom plugins, you have to "build" your site locally and then deploy it to the gh-pages branch yourself, as a collection of HTML, CSS and other files (not Markdown files anymore). You may want to try jgd command line to to help you do it all automatically. Just install it and then run:

$ jgd

The site will be packaged and then deployed to the gh-pages branch of your repo. More about it in this blog post of mine: Deploy Jekyll to GitHub Pages

Goshorn answered 21/6, 2019 at 13:31 Comment(0)
P
2

A better and straightforward solve to use custom plugins on Github Pages is using Github Actions. All the steps are documented on the official page of Jekyll: https://jekyllrb.com/docs/continuous-integration/github-actions/. Reproducing the steps from the article above here:

  1. Go to the Settings tab on your repository.
    1. Under Code and automation, click Pages (last option).
    2. Change Source under Build and deployment from Deploy from a branch to GitHub Actions.
  2. Go to the Actions tab on your repository.
    1. Start a New workflow and search for Jekyll.
    2. Click Configure under the Jekyll workflow (NOT GitHub Pages Jekyll workflow).
    3. Review the change and click Commit changes.

On pushing any local changes onto the default branch, the action will be triggered and the build will start.

The build might fail because of an error as below:

 Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/cache/gems/jekyll-3.2.1/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter.

To fix this, place the line exclude: [vendor] in _config.yml. More discussion here: https://github.com/jekyll/jekyll/issues/5267.

Pterosaur answered 5/12, 2023 at 21:32 Comment(1)
This is the preferred method and works.Aorta
B
1

If you don't what a local solution because it's time consuming, you could automate a process so that when you push changes to master it will automatically build your website locally and push the changes to the gh-pages branch.

You can achieve this by creating a pre-push hook in your repo (.git/hooks/pre-push) with the following content:

#!/bin/sh

# If any command fails in the bellow script, exit with error
set -e

# Set the name of the folder that will be created in the parent
# folder of your repo folder, and which will temporarily
# hold the generated content.
temp_folder="_gh-pages-temp"

# Make sure our main code runs only if we push the master branch
if [ "$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)" == "master" ]; then
    # Store the last commit message from master branch
    last_message=$(git show -s --format=%s master)

    # Build our Jekyll site
    jekyll build

    # Move the generated site in our temp folder
    mv _site ../${temp_folder}

    # Checkout the gh-pages branch and clean it's contents
    git checkout gh-pages
    rm -rf *

    # Copy the site content from the temp folder and remove the temp folder
    cp -r ../${temp_folder}/* .
    rm -rf ../${temp_folder}

    # Commit and push our generated site to GitHub
    git add -A
    git commit -m "Built \`$last_message\`"
    git push

    # Go back to the master branch
    git checkout master
else
    echo "Not master branch. Skipping build"
fi

For more details please see my blog post.

Bowens answered 7/2, 2020 at 0:27 Comment(0)
W
0

You need an alternative to those plugins.

As detailed in "Building a Series List with Hugo Shortcodes":

Ruby plugin execution is disabled altogether on Github pages:

Plugins on GitHub Pages GitHub Pages is powered by Jekyll.
However, all Pages sites are generated using the -safe option to disable custom plugins for security reasons. Unfortunately, this means your plugins won’t work if you’re deploying to GitHub Pages.

You can still use GitHub Pages to publish your site, but you’ll need to convert the site locally and push the generated static files to your GitHub repository instead of the Jekyll source files.

I understand you mention:

Obviously I can generate html files locally and commit them to my repository. But that's not what I want.

Still, a static website generator (compatible with GitHub pages) like Hugo is to be considered in your case.

R.J Lorimer adds:

Hugo has the concept of Shortcodes, which are much like “Liquid Tags” in Jekyll.
Also like Jekyll, you can create custom shortcode tags.

However, the major difference is that in Hugo you can create them without resorting to actually writing Go code - see Create Your Own Shortcodes.
Because Hugo uses Go Templates for rendering the pages, shortcodes can use any and all Go template functions inside of them, as well as a whole list of custom Hugo functions added to help. This makes it arguably more powerful than a liquid-template solution, but still in a template file that can be easily updated on the fly.

Plus, Hugo does support MathJax, as seen in this article.

Update Nov. 2018: with Hugo 0.52, this tweet confirms (referencing this thread):

The inline shortcode is similar to the way Jekyll allows you to use Liquid tags within Markdown

Wellrounded answered 11/11, 2018 at 0:30 Comment(1)
Thank you for proposing an alternative solution. But I'm afraid switching from Jekyll to Hugo is even bigger pain. Alternatively I could host my blog on GitLab where custom plugins are supported.Frumpy

© 2022 - 2024 — McMap. All rights reserved.