Welcome to Alex’s Blog
This blog is powered by Jekyll, themed by jekyll-theme-yat and hosted on Github Pages.
To avoid info fragmentation, this page is being continuously updated as this blog evolves.
Links
Search Box
Server-side site search (Elasticsearch) is added by the guidance in this blog post, but I have to rebuild the Searchkit client parts since the tech world has been moving forward.
As a temporary solution, the code is integrated into my fork of jekyll-theme-yat: https://github.com/alexforks/jekyll-theme-yat. The demo is available on the current site and the config can be found here.
Indexing
Searchyll is used to index the site.
Searchyll seems to be out of maintenance, the master branch is not merged and released for years.
You will be happy to refer to the below repo to get the recent fixes, at least until they are merged and released to official Gem.
This repo is based on omc/Searchyll
master plus my fix
to overcome the annoying updating alias error when running into multiple indices.
# _config.yml
group :jekyll_plugins do
gem "searchyll", git: "https://github.com/alexforks/searchyll", ref: "fix-update-alias-404"
end
Search UI
Searchkit is used to search the Elasticsearch server to build the search result.
I built a new search UI component with Searchkit v2
.
The layout and style are sticky with Searchkit as much as possible,
but being overridden to suit well with jekyll-them-yat
.
I’m not a React guy, just knowing enough to get it to work. Hope this universal solution is coming soon.
Credential
There are two places where the Elasticsearch URL and credential will be needed.
-
Searchyll
An URL with a credential with
write
permission is necessary. Don’t put the credential within_config.yml
, use environment variable to test locally, like below:$ bundle update && ELASTICSEARCH_URL="https://yourusername:yourpassword@yourserver.com" bundle exec jekyll serve
And configure the same URL and credential as environment variables in the
yourname.github.io -> Github Environments -> github-pages
for the server-side. -
Searchkit
An URL and a credential with read-only permission are enough.
# _config.yml elasticsearch: readonly_url: https://yourusername:yourpassword@yourserver.com
⚠️ WARNING: The
readonly_url
:- will be exposed to the Internet in site source.
- should only have the read-only permission to the Elasticsearch server.
Elasticsearch Service
Where to get an Elasticsearch service? To minimize the maintenance needs, mine is powered by Bonsai for free.
Use my referral link to sign up, the free plan is enough. But when you start using a paid plan, you and I will both get $50 credit.
Development
If you would like to make changes to the SearchUI, you will need to deal with
https://github.com/alexforks/jekyll-theme-yat.
All you need is npm
, get it ready. And run in your site root, to get your own search.js
.
$ npm install
$ webpack
Related environment:
$ ruby --version
ruby 2.7.3p183 (2021-04-05 revision 6847ee089d) [x86_64-darwin20]
$ npm --version
7.10.0
Links
- https://github.com/alexforks/jekyll-theme-yat
- https://blog.omc.io/elasticsearch-for-jekyll-part-1-ab456ac7c093
- https://github.com/searchkit/searchkit
- https://github.com/omc/searchyll
- https://app.bonsai.io/
Plugins with Github Pages
There are a lot of Jekyll plugins out there giving you the features that Jekyll and your theme don’t have. But the truth is most of them won’t work with Github Pages.
Github Pages has this dependency list.
The unlisted Jekyll plugins will work only if you run jekyll build
locally.
Github Pages is ignoring them on remote as they are don’t exist.
But this is not all the picture.
If you are using the yourusername.github.io
repo,
the only thing you want to be pushed to the configured branch is the generated _site
, nothing else.
If the Jekyll source is pushed to this branch, the remote Jekyll build is overriding your pushed local build.
To what end? you end up with a solution without the remote build capability!
Solution
To get the unlisted Jekyll plugins functional on Github Pages, you need a CI, such as Travis and Github Workflow, to gain control of the remote build.
Here it is, jekyll-deploy-action, a Github Action, will help to simplify the process with Github Workflow.
Just follow the usage document, after that, your plugins will work both LOCALLY AND REMOTELY, like a charm!
Links
Responsive Images
Responsive Images is good, to the readers. But it’s hard, to the publishers. It costs me days to come out with a satisfied solution. All difficulties are related to Github Pages.
Solution
⚠️ WARNING:The Zero-Width Space (ZWSP) is used in below code to workaround the liquid tags rendering issue. So, don’t simply copy & paste the code, the ZWSP must be removed.
I tried two well used responsive images plugins:
I take jekyll_picture_tag
for now. I like its presets
idea and the way of handling output directory structure.
Both plugins don’t support markdown image tags. This is quietly surprising me.
I don’t like the responsive image liquid tags within my content. That is just not the way to write.
To overcome this, I need a transformer to translate markdown image tags, like:
![Thinkpad](/assets/images/banners/thinkpad.png)
to the responsive image liquid tags, like:
{% picture banners/thinkpad.png --alt Thinkpad %}
I wrote this universal hook plugin jekyll-hooks, which does the job.
Then here is jekyll_picture_tag
. It’s rendering the liquid tag to HTML code as below:
<picture><source srcset="/assets/images/resized/banners/thinkpad-640-237e1d.webp 640w, /assets/images/resized/banners/thinkpad-800-237e1d.webp 800w, /assets/images/resized/banners/thinkpad-1024-237e1d.webp 1024w" type="image/webp"><source srcset="/assets/images/resized/banners/thinkpad-640-237e1d.png 640w, /assets/images/resized/banners/thinkpad-800-237e1d.png 800w, /assets/images/resized/banners/thinkpad-1024-237e1d.png 1024w" type="image/png"><img src="/assets/images/resized/banners/thinkpad-800-237e1d.png" alt="Thinkpad"></picture>
And your browser is rendering the HTML as below. Change your browser window size and reload the page, to see the different images are being downloaded.
The jekyll-hooks
can do more, such as letting the images be previewable while writing.
I write the markdown image like this:
![Thinkpad](../assets/images/banners/thinkpad.png)
This way the image is referring to a valid relative local path and is previewable while writing.
Then one action will remove the part ..
from the path in a pre_render
hook.
Which makes it a valid absolute web path.
Image Compress Lib
Choose vips or ImageMagick? With Github Pages, we don’t have a choice.
By now (Oct 2021), Github Pages’s pages-gem v221 is locking down Jekyll 3.9.0
.
The latest jekyll_picture_tag has dropped the support of Jekyll v3 because of a
cache_dir issue.
We stuck at jekyll_picture_tag 1.10.2
. And this version doesn’t support vips
, it supports ImageMagick
only.
Sample Config
jekyll-hooks is not in the official gem yet, for now, use the git URL.
# Gemfile
group :jekyll_plugins do
...
gem "jekyll-hooks", git: "https://github.com/alexzhangs/jekyll-hooks"
gem "jekyll_picture_tag", "~> 1.10.2"
end
# _config.yml
plugins:
- jekyll-hooks
- jekyll_picture_tag
# jekyll_picture_tag
picture:
source: assets/images
output: assets/images/resized
# jekyll-hooks
hooks:
actions:
- type: posts
exts: [markdown,mkdown,mkdn,mkd,md]
find: >
(!\[[^\]]*\]\()/assets/images/(.+)
replace: >
\1\2
disabled: false
- type: posts
exts: [markdown,mkdown,mkdn,mkd,md]
# ![alt](/path/to/image "title"){:.class}
find: >
!\[([^\]]*)\]\(((?!http[s]?://)[^"'\n]+)(?:\s['"]([^'"]*)['"])?\)(?:\{:\.([^{]+)\})?
# both present and non-present quotes matter
replace: >
{% picture \2 --alt \1 --img class="\4" title="\3" %}
case-insensitive: true
disabled: false
disabled: false
Of course, we need jekyll-deploy-action
.
The last three lines are important, to get ImageMagick and its dependency installed on the docker.
The jekyll-deploy-action
is running in a separate docker, so the dependencies must be installed with pre_build_commands
.
I’m using webp format for my images.
It has an amazing compression ratio in most situations. So it’s included in the installation list.
# .github/workflows/build-jekyll.yml
...
- uses: jeffreytse/jekyll-deploy-action@v0.3.1
with:
...
pre_build_commands: | # Installing additional dependencies (Arch Linux)
pacman -S --noconfirm imagemagick libwebp
identify --version
Links
- jekyll_picture_tag
- jekyll-responsive-image
- jekyll-hooks
- Images, Correctly
- Applying srcset: choosing the right sizes for responsive images at different breakpoints
- Automatic Responsive Images on Jekyll without Plugins
- Run and debug Github actions locally
- a Ruby regular expression editor