Jekyll
A static site generator (SSG) (see https://www.staticgen.com/ is a compromise between using a hand-coded static site and a full content management system (CMS). You generate an HTML-only website using raw data (such as Markdown files) and templates. The resulting build is transferred to your live server.
Jekyll, Elevently and hexo are examples of SSG.
Recuerda que GitHub provee un servicio de Hosting de páginas estáticas (GitHub Pages) que se sirven mediante Jekyll.
Jekyll Documentation and Tutorials
- Pages
- Posts
- Front Matter
- Collections
- Page Sections in Jekyll - Separating Content from Layout
- Explain like I’m five: Jekyll collections
- Data Files
- Why I love Jekyll Data Files - Chen Hui Jing // JekyllConf 2019 YouTube
- Assets
- Static Files
Site Structure
- Directory Structure
- Liquid
- Liquid Sandbox: You can test your Liquid code here. This sandbox only loads the default Liquid methods
- Variables
- Includes
- Layouts
- Permalinks
- Themes
- Pagination
Using Jekyll with Docker
File docker-compose.yml
:
version: '3'
services:
site:
image: jekyll/jekyll:3.8.6
command: bundle exec jekyll serve --future --incremental --watch --livereload --drafts --host 0.0.0.0 --port 4000
ports:
- 4000:4000
volumes:
- .:/srv/jekyll
- ./vendor/bundle:/usr/local/bundle
En el Rakefile
:
task :docker do
# sh 'docker run --rm --volume="$PWD:/srv/jekyll" --volume="$PWD/vendor/bundle:/usr/local/bundle" --env JEKYLL_ENV=development -p 4000:4000 jekyll/jekyll:3.8 jekyll serve'
sh 'docker compose up'
end
o bien:
➜ apuntes git:(main) ✗ cat jekyll-up
#!/bin/bash
docker compose up
➜ apuntes git:(main) ✗ cat jekyll-down
#!/bin/bash
docker compose down
Jekyll: Como preparar un informe de Prácticas usando GitHub Pages
Tutorials
Tutorials
Video Walkthroughs
Navigation
Order of interpretation
Custom 404 Page
An Example of a 404 page
~/.../pl1920/apuntes(master)]$ cat 404.md
---
layout: error
title: Error
---
# Error: ¡Ay Diós mío!
## Aún no he escrito esta página.
<div>
<style>
img, #quote, #comment-cat {
display: block;
margin-left: auto;
margin-right: auto;
}
#author {
float: right;
}
</style>
<div id="comment-cat"></div>
<div id="cat"></div>
<br/>
<div id="quote"></div>
<div id="author"></div>
<script type="text/javascript">
/*
https://docs.thecatapi.com/
*/
const URL = 'https://api.thecatapi.com/v1/images/search?size=full';
(async function() {
try {
// CAT
let divTitle = document.getElementById("comment-cat");
let divcat = document.getElementById("cat");
let response = await fetch(URL, {
headers: {
'x-api-key': "56a4f1cc-7f60-468d-9dba-e4b6f04b7c7d"
}
});
let cat = await response.json();
// console.log(cat);
let img = document.createElement("img");
let title = document.createElement("h2");
title.innerText = "Consuélate con un gatito";
divTitle.append(title);
img.src = cat[0].url;
divcat.appendChild(img);
// QUOTE
const quoteDiv = document.getElementById("quote");
const authorDiv = document.getElementById("author");
const quoteRes = await fetch('https://api.quotable.io/random');
const data = await quoteRes.json();
quoteDiv.innerHTML = `<h2>${data.content}</h2>`;
authorDiv.innerHTML = `<h3>—${data.author}</h3>`;
}
catch(e) {
console.log(e);
}
})();
</script>
</div>
Convert an HTML site to Jekyll
Using Jekyll with Bundler
The Jekyll Conference
- The free, online global conference for all things Jekyll Best Practices, Advanced Case Studies, The Future of Jekyll
CloudCannon: The Cloud CMS for Jekyll
CloudCannon is cloud content management system and hosting provider for Jekyll websites. The way it works is this:
- A developer uploads a Jekyll site in the browser or syncs with GitHub, Bitbucket or Dropbox.
- CloudCannon builds the site, hosts it and
- provides an interface for non-technical people to update content.
Editors
- Forestry is an editor-friendly interface over Git. This means that developers and editors can now use the same workflow and tool set.
Themes
With gem-based themes, some of the site’s directories (such as the assets
, _layouts
, _includes
, and _sass
directories) are stored in the theme’s gem, hidden from your immediate view. Yet all of the necessary directories will be read and processed during Jekyll’s build process.
You can run bundle update <THEME>
, replacing <THEME>
with the theme name, such as minima
, to just update the theme gem:
~/.../sytws1920/apuntes(master)]$ bundle update jekyll-theme-midnight
Fetching gem metadata from https://rubygems.org/...........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using concurrent-ruby 1.1.5
...
Bundler attempted to update jekyll-theme-midnight but its version stayed the same
Bundle updated!
- Themes documentation
- Jekyll and Project Documentation Themes
- documentation-theme-jekyll Un tema muy interesante
Converting a Jekyll Web Site to PDF
- Prince
- PDFKit
- GitHub repo wkhtmltopdf: Convert HTML to PDF using Webkit (QtWebKit) see https://wkhtmltopdf.org
Blog: A Collection of Music Albums
- How to maintain a collection of music albums online, using Jekyll and Github Pages. See it at http://adrienjoly.com/album-shelf/
React and Jekyll
- A npm package providing a Jekyll Boilerplate with React using Webpack (Not supported by GitHub Pages)
Auth and Jekyll
E-commerce
- Jekyll E-Commerce Tutorial: Add a Shopping Cart to Your Static Website 2019
- Headless E-Commerce: What, Why, & How (Tools Included) 2018
- GitHub repo:A Jekyll based shopping cart built with simpleCart(js)
- Jekyll Cart Demo Video en YouTube
Developing
”
This is a common problem between different Jekyll environments.
Some explanations
We need to understand site.url
and site.baseurl
and in which situation we need them. Those variables don’t serve the same purpose.
site.url
By default, this variable is only used in page head for the canonical
header and the RSS link
. It’s also used in the xml feed to point to site resources as the software that will manage this feed doesn’t know resource’s urls.
This variable is only necessary for external systems.
site.baseurl
This variable indicates the root folder of your Jekyll site. By default it is set to ""
(empty string). That means that your Jekyll site is at the root of http://example.com
.
If your Jekyll site lives in http://example.com/blog
, you have to set site.baseurl
to /blog
(note the slash). This will allow assets (css, js) to load correctly.
See how assets are loaded in you head :
<link rel="stylesheet" href="/css/main.css">
that can also be :
<link rel="stylesheet" href="/css/main.css">
Working in different environments
Now you have to test your site locally and to deploy it in production. Sometimes, the baseurl
is different and the jekyll build
may not work out of the box in one of those environment.
Here we have two solutions :
Use jekyll serve
Let’s imagine that your site lives in a github repository and is served at https://username.github.io/myProject
.
You can setup the baseurl
to /myProject
. and test your site locally with jekyll serve
, your site will be served at http://127.0.0.1:4000/myProject/
Use multiple configuration files
If, for one reason or another, you cannot use jekyll serve
, you can set a configuration file for both environment and jekyll build
depending on where you are deploying.
Let’s say we have the local site served at http://localhost
and the production site served at https://username.github.io/myProject
.
We leave the _config.yml
with url: https://username.github.io
and baseurl: /myProject
We create a new _config_dev.yml
with only url: https://localhost
and baseurl: ""
Now to test locally :
jekyll build --config _config.yml,_config_dev.yml
or
jekyll build --config _config.yml,_config_dev.yml --watch
When pushed on production, the jekyll build
command will use the default _config.yml
.
Testing HTML pages
HTMLProofer
When testing Jekyll output, there is no better tool than html-proofer. This tool checks your resulting site to ensure all links and images exist. Utilize it either with the convenient
htmlproofer
command-line executable, or write a Ruby script which utilizes the gem
usuario@ubuntu:~/src/ull-mii-sytws-1920.github.io$ bundle exec htmlproofer ./_site --disable-external
Running ["ImageCheck", "ScriptCheck", "LinkCheck"] on ["./_site"] on *.html...
Ran on 158 files!
- ./_site/2019/09/30/leccion.html
* internally linking to /practicas, which does not exist (line 31)
<a href="/practicas" title="Prácticas">✍</a>
* internally linking to /practicas, which does not exist (line 129)
<a href="/practicas" title="Prácticas">✍</a>
- ./_site/404.html
* internally linking to /practicas, which does not exist (line 31)
<a href="/practicas" title="Prácticas">✍</a>
... many more entries
Let us see if its true. Instead of running with jekyll
serve, I use a static server to see if the build
is really consistent:
usuario@ubuntu:~/src/ull-mii-sytws-1920.github.io/_site$ static-server -p 8080
options.index is now deprecated please use options.templates.index instead.
* Static server successfully started.
* Serving files at: http://localhost:8080
* Press Ctrl+C to shutdown.
<-- [GET] /2019/09/30/leccion.html
--> 200 OK /2019/09/30/leccion.html 5.63 KiB (15.964ms)
...
<-- [GET] /practicas/
--> 403 /practicas/ (2.199ms)
<-- [GET] /favicon.ico
See the 403 /practicas/ (2.199ms)
warning.
It seems htmlproofer
is right in spite that it works in github.io
We use HTMLProofer to test our web site. Here is an example of use:
Rakefile task for testing
~/.../sytws1920/ull-mii-sytws-1920.github.io(master)]$ cat Rakefile
desc "sytws: bundle exec jekyll serve --watch"
task :serve do
sh "bundle exec jekyll serve --future --watch --port 8080 --host 10.6.128.216"
end
... # more tasks
require 'html-proofer'
desc "test links in the build web site"
task :test do
sh "bundle exec jekyll build"
options = {
:assume_extension => true,
:disable_external => true,
:empty_alt_ignore => true,
:file_ignore => [ %r{categories} ]
}
HTMLProofer.check_directory("./_site", options).run
end
Testing with GitHub Actions
Here is an example of using the action Proof-HTML to check the health of our site:
➜ apuntes git:(main) ✗ cat .github/workflows/testHTML.yml
name: CI
on:
push:
schedule:
- cron: '0 8 * * 6'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-ruby@v1
with:
ruby-version: 2.7.x
- uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- run: bundle exec jekyll build
- uses: anishathalye/proof-html@v1
with:
directory: ./_site
enforce_https: false
tokens: |
{"https://github.com": "${{ secrets.GITHUB_TOKEN }}"}
url_ignore: |
http://www.example.com/
https://en.wikipedia.org/wiki/Main_Page
url_ignore_re: |
^https://twitter.com/
Testing with HTMLProofer and Travis
Jekyll as a Web Service
Maths y Jekyll
See the tutorial:
Summarizing, the simplest way is to add a line like:
<!-- Mathjax Support -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script>
at then end of your layout.
Here is an example of what you can do:
$$ r = h = \sqrt{\frac {1} {2}} = \sqrt{\frac {N} {N+1}} \sqrt{\frac {N+1} {2N}} $$
that renders as:
\[r = h = \sqrt{\frac {1} {2}} = \sqrt{\frac {N} {N+1}} \sqrt{\frac {N+1} {2N}}\]Working with upcoming posts in Jekyll
We used to work on more than one post at a time and publish them in future. So you just want to test them while writing the blog, but you don’t want publish them to your live blog immediately. There are different ways to achieve this in jekyll. This article discuss several workflows:
Cursos en YouTube de Jekyll and NetlifyCMS por Thomas Bradley
- Jekyll
- Jekyll + NetlifyCMS 14 Youtube videos
- Jekyll + Patternbot
Chen Hui Jing Talks on Jekyll
- Chen Hui Jing talks on Jekyll
- Chen Hui Jing talks Slides in reveal.js