Jekyll - HVboom/HowTo-DigitalOcean GitHub Wiki
Create a dedicated Jekyll user - see Development User
cd $HOME
mkdir -p Live Preview Projects
-
Example Gemfile for the HVKeyGuard product documentation
#ruby=ruby-2.4 #ruby-gemset=HVKeyGuard # source 'https://rubygems.org' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end gem 'jekyll' # This is the default theme for new Jekyll sites. You may change this to anything you like. gem 'minima' # If you have any plugins, put them here! group :jekyll_plugins do gem 'jekyll-feed' gem 'jekyll-haml' gem 'jekyll-admin' end # avoid polling of changed files require 'rbconfig' if RbConfig::CONFIG['target_os'] =~ /(?i-mx:bsd|dragonfly)/ gem 'rb-kqueue', '>= 0.2' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
-
Create additional configuration files for the preview and live versions of the documentation
-
Example:
Projects/HVKeyGuard/_config.preview.yml
baseurl: '/Preview/HVKeyGuard' url: 'https://hvboom.org' source: '/home/jekyll/Projects/HVKeyGuard' destination: '/home/jekyll/Preview/HVKeyGuard' profile: true
-
Example:
Projects/HVKeyGuard/_config.prod.yml
baseurl: 'Projects/HVKeyGuard' url: 'https://hvboom.org' source: '/home/jekyll/Projects/HVKeyGuard' destination: '/home/jekyll/Live/HVKeyGuard'
-
Serve generated pages through Apache
Create following configuration /usr/local/etc/apache24/Includes/060_vhost_443_jekyll.conf
<VirtualHost *:443>
ServerName jekyll.HVboom.org
# fix, if user is lazy and does not add a trailing slash to a directory
DirectorySlash On
ProxyRequests Off <-- this is an important security setting
ProxyPreserveHost On
# LogLevel debug rewrite:trace3
# default to the Homepage project
RewriteEngine On
RewriteRule ^/$ %{REQUEST_SCHEME}://%{HTTP_HOST}/Homepage/ [redirect=permanent,last]
# preview of the generated project
AliasMatch "^/Preview/(.*)$" "/home/jekyll/Preview/$1"
# allow access to the preview directories
<Directory "/home/jekyll/Preview/">
Require all granted
Options none
</Directory>
# allow access to the internal proxy servers
<ProxyMatch "^http://localhost:\d{4}/?">
Require all granted
Options none
</ProxyMatch>
<Macro JekyllProxy ${location} ${port}>
# fix missing trailing slash for accessing project root or admin area
RewriteRule ^/${location}$ %{REQUEST_SCHEME}://%{HTTP_HOST}/${location}/ [redirect=permanent,last]
RewriteRule ^/${location}/admin$ %{REQUEST_SCHEME}://%{HTTP_HOST}/${location}/admin/ [redirect=permanent,last]
# proxy project root
<Location "/${location}/">
ProxyPass http://localhost:${port}/${location}/
ProxyPassReverse http://localhost:${port}/${location}/
</Location>
# proxy project internal Jekyll API
<Location "/${location}/_api/">
ProxyPass http://localhost:${port}/_api/
ProxyPassReverse http://localhost:${port}/_api/
SetOutputFilter INFLATE;substitute;DEFLATE
Substitute "s|http://localhost:${port}|https://jekyll.HVboom.org|ni"
</Location>
# proxy project Jekyll Admin area
<Location "/${location}/admin/">
ProxyPass http://localhost:${port}/admin/
ProxyPassReverse http://localhost:${port}/admin/
AddOutputFilterByType INFLATE;substitute;DEFLATE text/html
AddOutputFilterByType INFLATE;substitute;DEFLATE text/css
AddOutputFilterByType INFLATE;substitute;DEFLATE application/javascript
Substitute "s|/admin|/${location}/admin|ni"
Substitute "s|/_api|/${location}/_api|ni"
</Location>
</Macro>
Use JekyllProxy Homepage 8001
Use JekyllProxy HVKeyGuard 8002
UndefMacro JekyllProxy
SSLEngine on
SSLCertificateFile /usr/local/etc/letsencrypt/live/hvboom.org/fullchain.pem
SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/hvboom.org/privkey.pem
RequestHeader add X-Forwarded-Ssl on
<IfModule headers_module>
Header always edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
</IfModule>
</VirtualHost>
Create following script as /home/jekyll/bin/jekyll-start
#!/usr/local/bin/bash
project=$1
if [[ -z $project ]]; then
echo "Usage: project name needs to be provided!"
exit 1
fi
project_path="$HOME/Projects"
pid_path="$HOME/tmp/pids"
log_path="$HOME/log"
project_dir="$project_path/$project"
pid_file="$pid_path/${project}.pid"
log_file="$log_path/${project}.log"
if [[ ! -d "$project_dir" ]]; then
echo "Error: project directory '$project_dir' does not exist!"
exit 1
fi
if ! mkdir -p "$pid_path"; then
echo "Could not create the path '$pid_path' needed to store the pids."
exit 1
fi
if ! mkdir -p "$log_path"; then
echo "Could not create the path '$log_path' needed to store the log files."
exit 1
fi
# ensure RVM is enabled before entering the project directory
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
cd $project_dir
nohup bundle exec jekyll serve --verbose --watch 2>&1 1>>$log_file &
echo $! > $pid_file
exit
Add following script /usr/local/etc/rc.d/jekyll
to start the project servers automatically as system startup.
#! /bin/sh
# Maintainer: Mario Lotz <[email protected]>
# PROVIDE: jekyll
# REQUIRE: LOGIN
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf to enable Jekyll:
#
# jekyll_enable="YES"
PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/local/share/bin"
. /etc/rc.subr
name=jekyll
rcvar=jekyll_enable
extra_commands=status
status_cmd="print_status"
start_cmd="start_jekyll"
stop_cmd="stop_jekyll"
restart_cmd="restart_jekyll"
: ${jekyll_enable:="NO"}
load_rc_config $name
### Environment variables
# Script variable names should be lower-case not to conflict with
# internal /bin/sh variables such as PATH, EDITOR or SHELL.
app_user="jekyll"
user_home="/home/$app_user"
app_root="$user_home/Projects"
pid_path="$user_home/tmp/pids"
start_server="$user_home/bin/jekyll-start"
# Switch to the app_user if it is not he/she who is running the script.
if [ "$USER" != "$app_user" ]; then
eval su - "$app_user" -c $(echo \")/usr/local/etc/rc.d/jekyll "$@"$(echo \")
exit
fi
# Switch to the jekyll path, exit on failure.
if ! cd "$app_root" ; then
echo "Failed to cd into '$app_root', exiting!"
exit 1
fi
### Init Script functions
## Get the pid for one project
get_pid(){
project=$1
pid_file="$pid_path/${project}.pid"
if [ -f "$pid_file" ]; then
pid=$(cat "$pid_file")
# If the server is running kill -0 $pid returns true, or rather 0.
if ! kill -0 "$pid" 2>/dev/null; then
# process is not running
pid=0
# Cleaning up unused pids
rm "$pid_file" 2>/dev/null
fi
else
pid=0
fi
return $pid
}
## Start all projects, if they are not already running
start_jekyll(){
echo "Start servers ..."
find * -prune -type d | while IFS= read -r project; do
get_pid $project
pid=$?
if [ "$pid" -ne 0 ]; then
echo " The server for project '$project' is already running with pid $pid."
else
echo " Starting server for project '$project' ..."
$start_server $project
sleep 1
get_pid $project
pid=$?
echo " The server for project '$project' is running with pid $pid."
fi
done
echo "Starting servers finished"
}
## Stop all projects, if they are still running
stop_jekyll(){
echo "Stop servers ..."
find * -prune -type d | while IFS= read -r project; do
get_pid $project
pid=$?
if [ "$pid" -eq 0 ]; then
echo " The server for project '$project' is already stopped."
else
echo " Shutting down project '$project' ..."
kill -- "$pid"
sleep 1
get_pid $project
pid=$?
if [ "$pid" -eq 0 ]; then
echo " The server for project '$project' is stopped."
else
printf " The server for project '$project' is \033[31mstill running\033[0m.\n"
fi
fi
done
echo "Stopping servers finished"
}
## Restart all projects, even if they are already running
restart_jekyll(){
echo "Restart servers ..."
find * -prune -type d | while IFS= read -r project; do
get_pid $project
pid=$?
if [ "$pid" -ne 0 ]; then
echo " Shutting down project '$project' ..."
kill -- "$pid"
sleep 1
get_pid $project
pid=$?
if [ "$pid" -eq 0 ]; then
echo " The server for project '$project' is stopped."
else
printf " The server for project '$project' is \033[31mstill running\033[0m.\n"
break
fi
fi
echo " Starting server for project '$project' ..."
$start_server $project
sleep 1
get_pid $project
pid=$?
echo " The server for project '$project' is running with pid $pid."
done
echo "Restart servers finished"
}
## Print the server status of all projects
print_status(){
echo "Print status ..."
find * -prune -type d | while IFS= read -r project; do
get_pid $project
pid=$?
if [ "$pid" -ne 0 ]; then
echo " The server for project '$project' is running with pid $pid."
else
printf " The server for project '$project' is \033[31mnot running\033[0m.\n"
fi
done
echo "Print status finished"
}
### Finally the input handling.
case $jekyll_enable in
[yY][eE][sS])
case "$1" in
start)
start_jekyll
;;
stop)
stop_jekyll
;;
restart)
restart_jekyll
;;
status)
print_status
;;
*)
echo "Usage: service jekyll {start|stop|restart|onestart|onestop|onerestart|status}"
exit 1
;;
esac
;;
*)
case "$1" in
onestart)
start_jekyll
;;
onestop)
stop_jekyll
;;
onerestart)
restart_jekyll
;;
status)
print_status
;;
*)
echo "Usage: service jekyll {start|stop|restart|onestart|onestop|onerestart|status}"
exit 1
;;
esac
esac
exit
A Jekyll plugin that provides users with a traditional CMS-style graphical interface to author content and administer Jekyll sites. The project is divided into two parts. A Ruby-based HTTP API that handles Jekyll and filesystem operations, and a Javascript-based front end, built on that API.
A great theme with awesome features. 🌟
- Setup is really simple - see Quick start. But do not forget to copy the whole
_data
directory (bundle show jekyll-text-theme
) into your own directory and adjust the files accordingly. - Set default author
Mario: name : Mario Lotz type : # "person" (default), "organization" url : avatar : /assets/images/Mario.jpg bio : email : [email protected] linkedin : mario-lotz # "user_name" the last part of your profile url, e.g. https://www.linkedin.com/in/user_name github : HVboom # "user_name" the last part of your profile url, e.g. https://github.com/user_name
- Adjust the
_config.yml
to your needs... theme: jekyll-text-theme author: name : Mario Lotz type : # "person" (default), "organization" url : avatar : /assets/images/Mario.jpg bio : email : [email protected] linkedin : mario-lotz # "user_name" the last part of your profile url, e.g. https://www.linkedin.com/in/user_name github : HVboom # "user_name" the last part of your profile url, e.g. https://github.com/user_name defaults: - scope: path: '' values: author: Mario layout: 'article' full_width: false show_title: true show_tags: true aside: toc: true - scope: path: '_features' values: author: Mario layout: 'article' full_width: false show_title: true show_tags: true nav_key: 'features' sidebar: nav: 'features' aside: toc: true
- To use a different font size and font family please adjust the file
_sass/custom.scss
:// Use a bigger font - default is 16px $font-size-root: 21px; // use Lato as default font - others are 1:1 from the theme $font-family: (Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif); // original definition: $font: map-get($base, font-weight) #{map-get($base, font-size)}/#{map-get($base, line-height)} map-get($base, font-family); // $font: map-get($base, font-weight) #{map-get($base, font-size)}/#{map-get($base, line-height)} $font-family; // use Anonymous Pro as default monospace font - others are 1:1 from the theme $font-family-code: ('Anonymous Pro', Menlo, Monaco, Consolas, Andale Mono, lucida console, Courier New, monospace); html { // font-size: map-get($base, font-size-root); font-size: $font-size-root; } body { // font: $font; font-family: $font-family; } input, textarea, select, button { // font: $font; font-family: $font-family; } pre, code { // font-family: map-get($base, font-family-code); font-family: $font-family-code; }
- Add the necessary stylesheet for the font to the file
_includes/head/custom.html
as described on the Google Fonts page:<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Lato:400,400i,700,700i&display=swap'> <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Anonymous+Pro:400,400i,700,700i&display=swap'>
Helper plugin to automatically open external links in a new window.
- In addition following custom stylesheet shows an external link icon
_sass/_target-blank.scss
:/* Step 1: Common Properties: All required to make icons render reliably */ @mixin icon { display: inline-block; font-style: normal; font-variant: normal; text-rendering: auto; -webkit-font-smoothing: antialiased; font-family: "Font Awesome 5 Free"; font-weight: 900; } /* Step 2: Reference Individual Icons */ /* external link icon, but not for buttons like GitHub or LinkedIn */ :not(.button).target-blank { &__icon::after { @include icon; font-size: smaller; vertical-align: super; margin-left: .15em; content: " \f35d"; } }
- Import that additional stylesheet into the
_sass/custom.scss
file@import '_target-blank'; ...
- To activate the icon following entry is necessary in
_config.yml
, which adds the external class to the link:... target-blank: add_css_classes: target-blank target-blank__icon ...
❗ Remark: Not necessary anymore, because the the jekyll-text-theme provides the same possibility with the mermaid extension
It's an add-on to integrate UML diagrams into your static pages
- Example: Sequence diagram
- Precondition
- Installation of Java and Graphviz
- Download the necessary
plantuml.jar
file and create a setup script/usr/local/share/bin/plantuml
:#!/usr/local/bin/bash java -jar /usr/local/share/bin/plantuml.jar "$1" "$2"
- Adopt the system startup script
/usr/local/etc/rc.d/jekyll
to include the path/usr/local/share/bin
- Adopt the system startup script
- Usage documentation see PlantUML.com
- Before you do a final build it is necessary to cleanup the generated
uml
subdirectory
- Before you do a final build it is necessary to cleanup the generated