Möchte man eine statische, leicht zu wartende und moderne Webseite erstellen, ohne sich dabei an “Baukastensysteme” diverser Anbieter zu binden, gibt es hierfür beispielsweise folgende Lösung:
“Jekyll” ist ein äußerst anpassbarer Website-Generator, mit dessen Hilfe sich nahezu alle erdenklichen Aufbauten einer Webseite erzeugen lassen. In Verbindung mit Twitters Frontend-CSS-Framework “Bootstrap” kann ein zeitgemäßes responsive mobile-first Design realisiert werden. Schöne Icons liefert FontAwesome.
Dieser Artikel beschreibt unter Verwendung von Windows 10 und PowerShell, wie sich dies miteinander verbinden lässt, ohne dass ein spezielles “Entwicklersystem” dafür eingerichtet werden muss. Vorausgesetzt wird lediglich eine Docker-Installation. Mit kleineren Anpassungen der Docker-Aufrufe sollte das Ganze auch auf anderen Systemen funktionieren.
(Zwecks Versionsverwaltung bei einer Weiterentwicklung bietet sich git mit einer speziell angepassten .gitignore an.)
Bootstrap mit Icons und FontAwesome einbinden
Eine direkte Einbindung der Bootstrap-Sourcen, insbesondere der SASS-Dateien, bietet mehr Anpassungsmöglichkeiten hinsichtlich des Designs. Die Auslieferung der Bootstrap-Dateien vom eigenen Webserver eliminiert Abhängigkeiten zu externen CDNs und kommt damit dem Datenschutz entgegen. Gleiches gilt für FontAwesome.
Die Verwendung von Jekyll erfordert eine bestimmte (teils konfigurierbare) Datei-/Ordner-Struktur, die es zu beachten gilt. Zur Einbindung von Boostrap mit Icons und FontAwesome müssen verschiedene SASS-, CSS-, JavaScript- und Font-Dateien an geeignete Stellen kopiert und verfügbar gemacht werden. Hier bietet sich die Verwendung des nachfolgenden, selbsterklärenden Shell-Scripts .install_bootstrap_and_icons.sh
an:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/bin/sh
###########################################################################################################
# Installs bootstrap, bootstrap icons and fontawesome icons via docker's alpine image
# to be used in a jekyll context.
#
# - Copies bootstrap scss files to _sass/ext/bootstrap/
# - Copies bootstrap js files to assets/ext/bootstrap/js/
# - Creates assets/ext/bootstrap/css/bootstrap.scss with front matter
# - Copies bootstrap-icons font files to assets/ext/bootstrap-icons/css/fonts/
# - Copies bootstrap-icons font/bootstrap-icons.css /jekyll/assets/ext/bootstrap-icons/css/
# - Copies fontawesome scss files to _sass/ext/fontawesome/
# - Copies fontawesome font files to assets/ext/fontawesome/webfonts/
# - Creates assets/ext/fontawesome/css/fontawesome.scss with front matter
#
# In Windows PowerShell, you can use this script by executing:
# docker run --rm -v="$(pwd)":/jekyll -it alpine /bin/sh /jekyll/.install_bootstrap_and_icons.sh
#
# The installed styleshets can be included by:
# <link rel="stylesheet" href="{{ '/assets/ext/bootstrap/css/bootstrap.css' | relative_url }}">
# <link rel="stylesheet" href="{{ '/assets/ext/bootstrap-icons/css/bootstrap-icons.css' | relative_url }}">
# <link rel="stylesheet" href="{{ '/assets/ext/fontawesome/css/fontawesome.css' | relative_url }}">
#
# Configure versions here:
BOOTSTRAP_VERSION="v5.1.3"
BOOTSTRAP_ICONS_VERSION="v1.7.2"
FONT_AWESOME_VERSION="5.15.4"
###########################################################################################################
##### Install git #####
apk add git
##### Bootstrap #####
# Clone bootstrap and checkout the specified version
git clone https://github.com/twbs/bootstrap.git
cd bootstrap
git checkout $BOOTSTRAP_VERSION
# Cleanup (= remove old bootstrap)
rm -r /jekyll/_sass/ext/bootstrap
rm -r /jekyll/assets/ext/bootstrap
# Copy SASS files to _sass/ext/bootstrap/
mkdir -p /jekyll/_sass/ext/bootstrap
cp -r scss/* /jekyll/_sass/ext/bootstrap/
# Copy JS files to assets/ext/bootstrap/js/
mkdir -p /jekyll/assets/ext/bootstrap/js
cp dist/js/bootstrap.bundle.min.js /jekyll/assets/ext/bootstrap/js/
cp dist/js/bootstrap.bundle.min.js.map /jekyll/assets/ext/bootstrap/js/
# Create assets/ext/bootstrap/css/bootstrap.scss with front matter
mkdir -p /jekyll/assets/ext/bootstrap/css
cat >/jekyll/assets/ext/bootstrap/css/bootstrap.scss <<EOL
---
---
@import "ext/bootstrap/bootstrap";
EOL
# Go back
cd ..
##### Bootstrap icons #####
# Clone bootstrap icons and checkout the specified version
git clone https://github.com/twbs/icons.git
cd icons
git checkout $BOOTSTRAP_ICONS_VERSION
# Cleanup (= remove old bootstrap-icons)
rm -r /jekyll/assets/ext/bootstrap-icons
# Copy fonts to assets/ext/bootstrap-icons/css/fonts/
mkdir -p /jekyll/assets/ext/bootstrap-icons/css/fonts
cp font/fonts/bootstrap-icons.woff /jekyll/assets/ext/bootstrap-icons/css/fonts/
cp font/fonts/bootstrap-icons.woff2 /jekyll/assets/ext/bootstrap-icons/css/fonts/
# Copy CSS file to assets/ext/bootstrap-icons/css/
cp font/bootstrap-icons.css /jekyll/assets/ext/bootstrap-icons/css/
# Go back
cd ..
##### Font Awesome #####
# Clone fontawesome and checkout the specified version
git clone https://github.com/FortAwesome/Font-Awesome.git
cd Font-Awesome
git checkout $FONT_AWESOME_VERSION
# Cleanup (= remove old fontawesome)
rm -r /jekyll/_sass/ext/fontawesome
rm -r /jekyll/assets/ext/fontawesome
# Copy SASS files to _sass/ext/fontawesome/
mkdir -p /jekyll/_sass/ext/fontawesome
cp scss/* /jekyll/_sass/ext/fontawesome/
# Copy fonts to assets/ext/fontawesome/webfonts/
mkdir -p /jekyll/assets/ext/fontawesome/webfonts
cp webfonts/fa-*woff* /jekyll/assets/ext/fontawesome/webfonts/
# Create assets/ext/fontawesome/css/fontawesome.scss with front matter
mkdir -p /jekyll/assets/ext/fontawesome/css
cat >/jekyll/assets/ext/fontawesome/css/fontawesome.scss <<EOL
---
---
@import "ext/fontawesome/fontawesome.scss";
@import "ext/fontawesome/brands.scss";
@import "ext/fontawesome/solid.scss"
EOL
# Go back
cd ..
Im Ordner der zu erstellenden Webseite kann dieses Script wie folgt mit Docker ausgeführt werden:
docker run --rm -v="$(pwd)":/jekyll -it alpine /bin/sh /jekyll/.install_bootstrap_and_icons.sh
Hier wird das aktuelle Arbeitsverzeichnis (pwd) im alpine-Container unter /jekyll
eingehängt. Das .install_bootstrap_and_icons.sh
wird dann im Container selbst ausgeführt und schreibt dabei die benötigten Daten wiederum in das aktuelle Arbeitsverzeichnis - unterhalb von _sass/ext/
und assets/ext/
. Lediglich zum Wechseln auf eine andere Bootstrap- oder FontAwesome-Version ist ein erneutes Ausführen des Scripts notwendig. In diesem Fall müssen die im Script angegebenen Versionen entsprechend angepasst werden.
Minimales Jekyll-Beispiel
Dieses minimale Beispiel demonstriert, dass Jekyll-Generator, Bootstrap und FontAwesome funktionieren. Folgende Dateien werden hierfür zusätzlich benötigt:
1
2
3
4
5
6
7
8
9
├── Gemfile
├── _config.yml
├── _layouts
│ └── default.html
├── _posts
│ ├── 2021-12-29-this-is-a-first-post.md
│ └── 2021-12-30-my-second-post.md
├── about.md
└── index.md
Nun zum Inhalt dieser Dateien.
Jekyll ist in der Programmiersprache Ruby geschrieben. Das Gemfile
dient der Beschreibung von Abhängigkeiten. Hier können beispielsweise benötigte Jekyll-Plugins eingetragen werden:
1
2
3
4
5
6
7
8
9
10
11
source "https://rubygems.org"
gem "jekyll", "~> 4.2.0"
# Plugins
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.12"
end
# Watching directories on Windows
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
Mittels der _config.yml
-Datei im YAML-Format lässt sich die Erzeugung der statischen Webseite konfigurieren. In diesem Beispiel wird lediglich der SASS-Converter zur Generierung komprimierter CSS-Daten angewiesen:
1
2
sass:
style: compressed
Grundlegendes Konzept in Jekyll ist die Verwendung von Templates in Verbindung mit Programmanweisungen in der Template-Programmiersprache Liquid. Damit können komplexere Seiten aus Bausteinen generiert werden. Der Einfachheit halber wird hier ein einzelnes Template verwendet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!doctype html>
<html lang="de">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="{{ '/assets/ext/bootstrap/css/bootstrap.css' | relative_url }}">
<link rel="stylesheet" href="{{ '/assets/ext/bootstrap-icons/css/bootstrap-icons.css' | relative_url }}">
<link rel="stylesheet" href="{{ '/assets/ext/fontawesome/css/fontawesome.css' | relative_url }}">
<title>Hello, world!</title>
</head>
<body>
<!-- Example header: Bootstrap navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">Example</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navAltMarkup" aria-controls="navAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navAltMarkup">
<div class="navbar-nav">
{%- for p in site.pages -%}
<a class="nav-link {% if page.url==p.url -%}active{%- endif -%}" href="{{ p.url }}">{{ p.title }}</a>
{%- endfor -%}
</div>
</div>
</div>
</nav>
<!-- Example content: Bootstrap container with the content -->
<div class="container">
<h1>{{ page.title }}</h1>
{{ content }}
</div>
<!-- Posts -->
<div class="container">
<h3>Posts:</h3>
<ul>
{%- for post in site.posts -%}
<li>
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
<a class="post-link" href="{{ post.url | relative_url }}">
{{ post.title | escape }}
</a>
</li>
{%- endfor -%}
</ul>
</div>
<!-- Bootstrap Bundle with Popper -->
<script src="{{ '/assets/ext/bootstrap/js/bootstrap.bundle.min.js' | relative_url }}"></script>
</body>
</html>
Mit den Konfigurationsdateien und dem Template können nun wie folgt Inhalte in Markdown (standardmäßig kramdown) formuliert werden. Die Verwendung von HTML ist ebenfalls möglich.
1
2
3
4
5
6
---
layout: default
title: This is a first post
---
Content of first post
1
2
3
4
5
6
---
layout: default
title: My second post
---
Content of second post
1
2
3
4
5
6
---
layout: default
title: About
---
Content of "About" page
1
2
3
4
5
6
7
8
9
10
---
layout: default
title: Home
---
Content of "Home" page
Examples of the installed icons:
* FontAwesome icon "phone": <i class="fas fa-phone"></i>
* Bootstrap Icon "journal-bookmark-fill": <i class="bi bi-journal-bookmark-fill"></i>
Lokales Bereitstellen der Webseite (mittels docker)
Nachfolgender Befehl hängt das aktuelle Arbeitsverzeichnis (pwd) im jekyll-Container unter /srv/jekyll
ein, erzeugt die Webseite im aktuellen Arbeitsverzeichnis im Ordner _site
und startet einen Webserver, sodass die Webseite mittels Browser unter http://localhost:4000 betrachtet werden kann. Änderungen am Inhalt sind nach kurzer erneuter Generierung automatisch verfügbar. (Dies trifft nicht auf die Konfigurationsdateien zu, wie z.B. _config.yml
; hier ist ein erneutes Ausführen des Befehls erforderlich).
docker run --rm -v="$(pwd)":/srv/jekyll -p 4000:4000 -it jekyll/jekyll:latest jekyll serve --force_polling
Ist die Webseite (vorerst) wunschgemäß gestaltet und fertiggestellt, kann der Inhalt im Ordner _site
auf einen “echten” Webserver kopiert werden.
Weiterführendes
Die leicht verständliche Jekyll-Dokumentation ist lesenswert und bietet viele Möglichkeiten, eine Webseite nahezu beliebig anzupassen. Ebenso empfiehlt sich die Bootstrap-Dokumentation, zumal hiermit ein responsive mobile-first Design einfach umgesetzt werden kann.