- Website: https://qlimber.github.io
A concise reference for how this site works, how to change themes and layout, and the safest ways to customize.
- Engine: Jekyll (static site generator). GitHub Pages builds and hosts it automatically on each push to
main. - Content model: Markdown posts under
_posts/namedYYYY-MM-DD-slug.md. - Templates: Provided by the selected theme. Jekyll merges your Markdown with theme layouts to generate HTML.
- Gem: A Ruby package. Many themes (e.g.,
minima) are shipped as gems. You don’t edit the gem; you override parts of it in your repo when needed.
_config.yml: Global settings (site title/description, selected theme, permalink style, defaults).index.md: The homepage. The layout you choose here determines how the front page renders._posts/: Blog posts. Each file can definelayout,title,date, etc. in its front matter.- Optional override points (only create if you need to customize):
_layouts/*.html: Page skeletons. Create to override a theme’s layout._includes/*.html: Small reusable fragments likeheader.html,footer.html, analytics helpers.assets/main.scssor_sass/*.scss: CSS overrides.
- Additional project files:
_layouts/default.html: Custom wrapper that injects nav links and analytics consent._layouts/page.html: Simple page layout that displays the title._layouts/post.html: Post layout with title header plus tag/category footer._includes/head-custom.html: Inline CSS for the cookie consent banner._includes/analytics-consent.html: Banner + GA initialisation logic (honours consent & IP anonymisation).privacy-policy.md: Published policy linked from the header.
-
Install Ruby (once per machine)
Usingrbenvkeeps versions isolated:rbenv install 3.3.4 rbenv global 3.3.4 gem install bundler
-
Install project gems
cd ~/projects/qlimber.github.io bundle config set path 'vendor/bundle' bundle install
-
Run a live preview
bundle exec jekyll serve --livereloadOpen
http://127.0.0.1:4000/. Test the cookie banner: consenting loads GA (withanonymize_ip), declining keeps analytics disabled. Stop the server withCtrl+C. -
Production build check
bundle exec jekyll buildInspect
_site/if you need to review the generated HTML. -
Optional QA
bundle exec htmlproofer ./_site --check-html(if you installhtmlproofer)- Manual smoketest of GA real-time dashboard after deploying and accepting the banner.
- Built-in themes (auto-available on GitHub Pages): set
theme: theme-namein_config.yml.- Blog-suitable, dark-friendly options you used:
minima(has blog layouts; can enable dark skin)jekyll-theme-midnight(dark; project-oriented)jekyll-theme-hacker(dark/green; project-oriented)
- Blog-suitable, dark-friendly options you used:
- Remote themes (fetched from a GitHub repo): set
remote_theme:and enable the plugin.- Example:
remote_theme: pages-themes/midnight@v0.2.0plus pluginjekyll-remote-theme.
- Example:
-
Minima (dark blog):
# _config.yml title: QLiMBer Blog description: My notes on various topics theme: minima minima: skin: dark
# index.md (front matter only) --- layout: home ---
-
Built-in Midnight (dark):
# _config.yml title: QLiMBer Blog description: My notes on various topics theme: jekyll-theme-midnight
# index.md (use default + posts list) --- layout: default title: Home --- <h1>Posts</h1> <ul class="post-list"> {% for post in site.posts %} <li> <span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span> <h2><a class="post-link" href="{{ post.url | relative_url }}">{{ post.title }}</a></h2> </li> {% endfor %} </ul>
-
Built-in Hacker (dark/green):
# _config.yml title: QLiMBer Blog description: My notes on various topics theme: jekyll-theme-hacker
# index.md same as Midnight (use default + posts list) --- layout: default title: Home --- <h1>Posts</h1> <ul class="post-list"> {% for post in site.posts %} <li> <span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span> <h2><a class="post-link" href="{{ post.url | relative_url }}">{{ post.title }}</a></h2> </li> {% endfor %} </ul>
Notes:
minimaprovides ahomelayout that auto-lists posts, soindex.mdneeds no HTML.midnightandhackerdo not provide a blog home layout, so the simple posts list is added toindex.md.- Alternative to adding HTML in
index.md: create your own_layouts/home.htmlthat lists posts and setindex.mdback tolayout: home.
-
Post defaults: All posts automatically use
layout: postvia_config.ymldefaults.# _config.yml defaults: - scope: { path: "", type: posts } values: { layout: post }
-
Permalinks: Human-friendly URL structure.
# _config.yml permalink: /:year/:month/:day/:title/
-
Tags & categories: Clickable tags/categories on each post plus index pages at
/tags/and/categories/.- Local override layout:
_layouts/post.html(renders linked tags/categories) - Index pages:
tags.md,categories.md
- Local override layout:
-
Post template:
_drafts/post-template.mdto quickly start new posts with consistent front matter.
-
Post layout that links tags and categories (current implementation):
<!-- _layouts/post.html --> --- layout: default --- <article class="post"> <header class="post-header"> <h1>{{ page.title }}</h1> </header> {{ content }} {% assign has_tags = page.tags | default: empty %} {% assign has_categories = page.categories | default: empty %} {% if has_tags != empty or has_categories != empty %} <hr> <footer class="post-meta"> {% if has_tags != empty %} <p><strong>Tags:</strong> {% for tag in page.tags %} {% assign tag_slug = tag | slugify %} <a href="{{ '/tags/#' | append: tag_slug | relative_url }}">{{ tag }}</a>{% unless forloop.last %} · {% endunless %} {% endfor %} </p> {% endif %} {% if has_categories != empty %} <p><strong>Categories:</strong> {% for category in page.categories %} {% assign category_slug = category | slugify %} <a href="{{ '/categories/#' | append: category_slug | relative_url }}">{{ category }}</a>{% unless forloop.last %} · {% endunless %} {% endfor %} </p> {% endif %} </footer> {% endif %} </article>
-
Style tweaks:
--- --- /* assets/main.scss */ @import "minima"; /* or omit for built-in themes that don’t expose a Sass entry */ .site-title { font-weight: 700; }
-
Optional navigation in header: Add quick links (e.g.,
About,Projects,Tags,Categories).jekyll-theme-hackermay not renderheader_pagesby default; add your own_includes/header.htmlor_includes/nav.htmlto display links.-
Potential config if you adopt a theme that supports it:
header_pages: - about.md - projects.md - tags.md - categories.md
-
-
Analytics:
- GA4 is wired through
_includes/head-custom.html(loads the standard gtag snippet, sets consent default to denied, and usessend_page_view: falseso no hit fires before opt-in) and_includes/analytics-consent.html(banner + consent handling). - Consent banner stores state in
localStorageand only enables GA after acceptance; declining keeps analytics disabled and updates consent back to denied. - Privacy Policy lives at
/privacy-policy/; update it whenever tracking scope changes. - GitHub Insights still provides basic repo traffic metrics if you need a double-check.
- GA4 is wired through
- Copy the template:
_drafts/post-template.md→_posts/YYYY-MM-DD-your-title.md. - Update front matter:
title,date(match filename for clarity),categories,tags. - Write content in Markdown below the front matter.
- Push to
main— GitHub Pages will rebuild automatically. Notes:
- Posts must include a front matter block (
---at top) to be processed. layout: postis auto-applied by defaults; you can override per post if needed.
- Follow the steps in Local development workflow. That uses Bundler with the exact GitHub Pages gem set.
- On Windows, WSL2 is recommended. Run the commands from within your WSL shell; LiveReload still serves at
http://127.0.0.1:4000.
- Empty homepage after switching theme:
- Cause: the theme lacks a
homelayout. - Fix: use
layout: defaultwith the posts list HTML inindex.md, or create an override_layouts/home.htmlthat lists posts and setindex.mdtolayout: home.
- Cause: the theme lacks a
- Duplicate site title appearing in multiple places:
- Header/footer are pulling
site.titleandsite.descriptionfrom_config.yml. Override_includes/footer.htmlto change what shows.
- Header/footer are pulling
- Minima:
https://github.com/jekyll/minima - Midnight (built-in and remote):
https://github.com/pages-themes/midnight - Hacker:
https://github.com/pages-themes/hacker