Forked from official Beautiful Jekyll theme, with changes moving faster forward, since Dean Attali desires a more stable theme as it has a large user base. Intended and finished changes include:
- Delegating most JavaScript and CSS loading to fast CDN with best worldwide presence (jsDelivr and Cloudflare cdnjs)
- Require.JS integration, loading JavaScripts asynchronously with dependency tracking
- loadCSS integration, delays loading of non-critical style sheets
- Bootstrap updated to 3.4.1
- jQuery updated to 3.4.1 (Bootstrap 3.4 series supports it)
- Font Awesome updated to 5.8.2 webfont version
- Not using SVG due to problem in IE for CSS pseudo element
- (planning) Use Bootstrap 4.x, either with SASS integration or old fashioned CSS override
- Remote theme support
- (planning) Enable extra feature with config toggle (like katex)
- (under progress) Reusable include fragments for common components
- Currently implementing figure and slide show
- (planning) Support for Jekyll custom collection
- URL settings follow Jekyll guideline (available upstream)
- (about 40% done) SASS migration, upstream theme only uses raw CSS
- (under progress) Layout reorganization, code cleanup and bug fixes
- (under progress) Some parts rewritten (e.g. tag page, footer)
- (planning) Localization related feature and cleanup
Hopefully some of the modifications can be merged upstream in the future. For any issues not mentioned here, please visit upstream theme repository for info.
Due to switching to SCSS from raw CSS and Require.JS integration (see below), the appropriate place for user customization has deviated from upstream theme.
CSS | Javascript | |
---|---|---|
Original |
|
Modify js/main.js directly |
Now |
|
|
The intention of change is to keep upstream main CSS / script body intact, while modularizing user changes as much as possible. It would be relatively easier to sync from upstream change without messing up with one's own customizations.
Please check out my example repository on how to use this theme as remote theme. Only limited files need to be copied, mainly config and some top level files. No template and no asset are needed, unless you want to override them. Some additional files are needed for Staticman support though. Anyway, remember:
No forking!
Forking would copy each and every file, which defeats the purpose of remote theme per se.
With require.js, it is possible to load all required javascript libraries
asynchronously with dependencies fulfilled. Major part of relevant config
is available under requirejs
variable in _config.yml
. There are 2
subkeys under requirejs
:
subkey | explanation |
---|---|
mods |
Script module name, usually the base script file name without .js extension. |
libs |
Dependencies used by script modules. Only specified in _config.yml . |
Each library dependency in turn contains 3 properties: name
, href
and
sri
(optional, see this mozilla web doc for explanation). Here is part
of default config:
requirejs:
mods:
- beautiful-jekyll
libs:
- name: jquery
href: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min'
sri: 'sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ'
- name: bootstrap
href: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min'
sri: 'sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd'
One can write additional script for customization, without touching
the upstream theme script. This customization can be as granular as
per-layout or even per-page level. All of them uses requirejs.mods
variable just like how it is used in global config. In exchange,
all manual javascript loading facilities (js
, ext-js
etc) are dropped.
Following examples assume you have added your AMD style javascript
as assets/js/myscript.js
:
Additional site script | Per-layout or per-page script |
---|---|
Add your script beside the main one in `_config.yml`, for example:
requirejs:
mods:
- beautiful-jekyll
- myscript |
Define relevant script inside front matter of layout or post file:
---
requirejs:
mods:
- myscript
---
(post content or layout content) |
All scripts are assumed to be placed under assets/js/
subfolder
(see _includes/head-scripts.html
); for overriding single script,
it is possible to use relative path when specifying script module
name like:
requirejs:
mods:
- ../myscript
Although RequireJS can load traditional scripts and specify dependencies manually, it is recommended to write your module in Asynchronous Module Definition style. TL;DR:
define (['jquery'], function($){
// your code here
});
In the example above, the first argument (module ID) is omitted. It suffices to write your script as an anonymous module. Second argument is array of dependencies your script would use. Finally argument is factory function, with dependent modules as arguments.
Merit for using AMD and usage details are out of scope of this document; RequireJS website and AMD JS Group already provide nice roundup about everything related to AMD.
Note: for traditional scripts one has no control over (or loaded from
CDN), there is shim config under requirejs. For example, Bootstrap
3.x jQuery modules have no support for AMD (only supported for 4.x), thus
this fragment is used inside _includes/head-scripts.html
:
shim: {
bootstrap: { deps: ['jquery'] }
}
loadCSS is chosen to attempt loading non-critical style sheets
asynchronously, like what require.js
is doing for javascripts.
There are not much user related changes, except that an extra boolean key
critical
is added to denote a style sheet being important, and must be loaded
in a blocking manner. Here is the default config demonstrating its use
in Bootstrap style sheet:
common-css:
- "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css":
sri: "sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu"
critical: true
Since most JavaScript and CSS libraries have been offloaded externally, it is
essential that they were not tempered, compromising user experience. The
common-css
variable fragment above shows the usage of Subresource Integrity (SRI),
which accompanies relevant resource with checksums to guarantee they are not changed
in any way. Once resource is loaded and checksum doesn't match, browser would refuse
to use the resource.
This is already available upstream; please visit upstream README for a summary of relevant changes.
Layouts are a bit different from upsteram theme:
Upstream | This fork |
---|---|
base |
default |
default |
minimal |
minimal |
(removed) |
There are 2 reasons:
- Upstream
minimal
theme seems to be abandoned and completely out of place when compared with any site theme template; while itsdefault
layout does not contain any bells and whistles yet included enough elements to be considered as part of site. - Another reason is,
default.html
is the convention adopted by Jekyll as the base template file name.
The variables list here only includes those not available from Jekyll or from original beautiful-jekyll theme.
- Jekyll defaults: they are already available from Jekyll variable documentation page. Won't be mentioned here unless there is significant deviation from Jekyll default.
- Beautiful Jekyll variables: please refer to YAML parameter section in upstream readme
Parameter | Scope | Notes |
---|---|---|
category |
Page | This is already natively supported in Jekyll but completely unused in beautiful-jekyll. However, this fork has enabled its use when generating permalinks (using permalink: pretty ). Future work is also planned on making category more useful. |
meta-description , meta-title |
Page | Removed. Originally undocumented upstream, they were used during social media sharing. Now social sharing would use original page title and description instead. |
requirejs |
Site, Layout, Page | Added. See require.js support above. |
js , ext-js , common-js , common-ext-js |
Layout, Page | Removed due to require.js integration. |
ext-css , common-ext-css |
Layout, Page | Removed. No more distinction between external and internal resource. |
css , common-css |
Layout, Page | Structure for subsettings are different from upstream. In this fork the URL itself is used as hash key. See loadCSS section for reference. |
googlefonts |
Layout, Page | Removed. All Google font resource are actually CSS and thus merged into css settings above. |
title-separator |
Site | Removed, now using bullet (U+2022) |
link-tags |
Site | Removed, now setting is enforced |
url-pretty |
Site | Removed, deemed redundant. Link to landing page already exists in navigation bar. |
gh-repo , gh-badge |
Page | Removed, of little use to bloggers. Even software project maintainers may choose other ways to showcase their projects. |
social-share |
Page | Renamed to shareabale |
share-links-active |
Site | Renamed to shareable-link |
excerpt_length |
Site | Removed. Users are encouraged to manually specify excerpt or use custom excerpt marker. |
This section has its own wiki page. The advantage for using Docker for local development is that, one don't need to install Ruby, Jekyll and all sorts of stuff in order to preview and test your Github pages. Besides the repo can be freed from artifacts resulting from local software management and dependencies.