Customizing a Jekyll Site

Customizing a Jekyll site is not for faint hearted.
Aside from the technical grunt work, there’s a lot of thought work – finding taxonomies that work for your domain – part library science! You’ll need to override parts of the default ‘Minima’ theme as you’ll be hard-pressed to find a perfect theme for your needs anyway.


🛠️ Change Log

Making your site production and UX ready involves many refinements. Here’s what this one entailed:

1. Global Navigation & Theme Overhaul

  • Established new baseline visual framework, stripping out Minima’s legacy typography and layout, and replacing it with Bootswatch Cerulean, a responsive, open-source Bootstrap theme variant.

  • Data-Driven Responsive Navbar: Replaced Minima’s rigid, flat page-header loop with a dynamic header (_includes/header.html) powered by a centralized data file (_data/navbar.yml).
    • adding sticky-top wrapper to the master <header> class so it won’t scroll off screen.
  • Standardized a unified domain -> area -> topic deep-classification taxonomy system for all markdown content documents.

2. Layout Width & Component Refactoring

  • Middle-Ground Viewport Width: Replacing Minima’s narrow .wrapper column layout across global viewports with Bootstrap’s responsive .container class grid boundaries (~1140px to 1320px).

  • Constrained Typography Viewports: Applied a focused 8-column reading layout (col-lg-8 mx-auto) onto human-centric timelines (blog.md and dms-memorial.html) to maximize text readability and prevent layout line stretching on desktop monitors.

  • Native Browser Offset Corrections: Configured scroll-padding-top: 110px and scroll-behavior: smooth rules inside the master stylesheet layer to prevent sticky navbar overlaps when jumping via anchor links.

  • Modern Dashboard Tiles: Refactored all list-rendering includes (collection-*.html) into modern, shadow-elevated Bootstrap card components.

3. Advanced Document Classification Taxonomy

  • Multi-Tiered Object Front-Matter: a deep-classification taxonomy for documents:
      taxonomy:
        domain: "Static Site Generators"
        area: "Jekyll Customization"
        topic: "Menu Systems"
    
  • Slicing Component Library: Built a set of modular layout includes (collection-list.html, collection-domain.html, collection-area.html, collection-topic.html) to slice single collection buckets into localized, reusable lists sorted by their exact taxonomy levels – (list documents by domain or area or topic)

  • Abstract Page-Folders: Nested layout viewports inside logical physical subdirectories (/technology/, /personal/) to serve as entry windows into concrete data collections.

4. Hybrid Documentation Sidebar System (_layouts/collection-doc.html):**

  • Multi-Domain Nested Directory: Upgraded the left sidebar to execute a dynamic double loop. It groups files by taxonomy.domain to create bold section banners, and then groups items by taxonomy.area inside each section.

  • Contextual Directory Accordion: Scans the active collection, filters items automatically, and renders files inside collapsible Bootstrap accordion folder blocks.

  • Adaptive Flat-Link Isolation: Uses conditional checks to isolate loose overview pages (documents without an area) and floats them to the absolute top of the sidebar as direct, standalone links. That is, documents without an area as top level (overview) links directly under the collection name, while two-tiered (domain-area) documents are placed under an accordion.

  • Dynamic State Autocompute: Scans page.url to automatically apply active highlight styling (fw-bold text-primary active) and uses unique slug identifiers (slugify) to open the correct active accordion panel container on page load

  • Multi-Tier In-Page TOC Script: Replaced brittle Kramdown string-splitting filters with a lightweight, client-side JavaScript parser. Wrote a client-side vanilla JavaScript parser that queries article <h2>, <h3>, and <h4> headers to inject a nested Table of Contents, using spatial padding markers (ps-3 and ps-4) to reflect heading depth.
    The entire panel auto-hides if zero headers exist.

5. Automated Global Scoping & Parent Controls

  • Dynamic Breadcrumb Navigation Trail: Built a dynamic trail component for document pages that maps an active file’s parent path settings back to its high-level index directory page flawlessly.

  • Polymorphic Portal Layout (_layouts/portal-hub.html): Created a unified, reusable layout for portal hub files.
    • If a specific domain parameter is given, it slices out that isolated card block.
    • If the domain is omitted, it triggers an automated loop to discover and display every domain inside the collection automatically.
  • Dynamic Concept Hub Module (_includes/concept-hub.html): Extracted the core loop of the abstract category index pages into an include that automatically displays collection metrics and presents a live text preview of the top 3 files ordered by ordinal_position.

  • Folder Routing Permalink Fix: Switched _config.yml collection parameters to use a path-preserving variable structure (permalink: /:collection/:path:output_ext), allowing Jekyll to natively compile subfolder files safely without throwing layout conflicts.

Tips & Recommendations

Use collections_dir to prevent folder drift

Don’t clutter your project root with multiple _<name> collection folders.
Instead, set a common home for your collections:

# in `_config.yml`
collections_dir: my_collections # or whatever folder name you choose
.
├── my_collections
│   ├── _dms-memorial
│   │   ├── books-authored.md
│   │   └── in-memoriam.md
│   └── _web-development
│       ├── ssg-jamstack.md
│       └── ssg-workflow-mobile.md
└── _config.yml

NOTE: You’ll need to move _posts and drafts to this location as well.
_pages is not an in-built Jekyll collection.

Use root level page folders to provide a window into your collections

Think of these folders as representing the most abstract concepts (personal, or, technology).
While collections can be thought of in terms of more concrete concepts (blog posts, microservices, etc.).
The top level (abstract concept) page folders, can contain pages that represent groupings of collections. For example, my web-development.html page includes a _web-development collection, but could as easily add a _ui-frameworks collection.

Therefore, rather than clutter the project root with a number of pages, create a tree like this:

.
├── personal/
│   ├── blog.html
│   └── dms-memorial.md
├── technology/
│   ├── architecture.html
│   └── web-development.html
└── index.md

Don’t make your collections too abstract

With content heavy sites, that will result in a glut of document files in a folder.

Instead of Narrow the scope to
_development _java
_architecture _microservices

But if you find yourself needing an abstract themed collection that could grow to many documents, here’re a couple of strategies for handling that.

1. Adopt a Document Classification Taxonomy and enforce a file-naming convention to go with it

Frontmatter & Liquid Templates: The Driver behind Jekyll
A document classification taxonomy lets you organize your documents in different views, by domain, area, or topic, going arbitrarily deep as you need.
However, to keep your sanity, stick with two- or three-level classifications at most.

---
taxonomy:
  domain: "Static Site Generators"
  area: "Jekyll"
  topic: "Customizing"
  #subtopic: Retry
  #level: "L2"
---

I designed taxonomy as an object, which is unfortunately unsupported by Obsidian, restricting frontmatter edits to VS Code. I considered shifting to flat, top-level keys to avoid this and to potentially simplify manipulation loops by using group_by and where, but the impact will be pretty widespread so I shelved that idea.

Why Bother?
Imagine cycling through all documents in a large collection, and no way of grouping them.
A _web-development collection might hold any subject from HTML5, CSS, JavaScript, Angular, React, Static Site Generation, etc.

You will inevitably need a window into your collection: a page(s) that display(s) a specific viewport or subset of collecion documents.
A taxonomy lets you slice and dice – display different subsets of your collection on different pages – with reuse enabled through include files.

.
├── _includes
│   ├── collection-area.html
│   ├── collection-domain.html
│   ├── collection-list.html
│   └── collection-topic.html

HOT-TIP
Apart from the Liquid enabled slicing and dicing, hooman site maintainers can struggle with a large volume of files in a folder – needle in a haystack problem.
To make it easier, adopt a naming convention for your collection documents.
Something along the lines of <domain>-<area>-<topic>.
I usually choose to abbreviate where possible, for example ‘ssg’ for ‘static site generation’.

│   └── _web-development
│       ├── ssg-jamstack.md
│       ├── ssg-jekyll-customizations.md
│       ├── ssg-jekyll-menu-system.md
│       ├── ssg-jekyll-setup.md
│       ├── ssg-jekyll-site-creation.md
│       ├── ssg-ruby-setup.md
│       └── ssg-workflow-mobile.md

Another option is to have subfolders under a collection. Again, stick with one- or two-level nesting, lest you trade file clutter for navigation fatigue from an arbitrarily deep folder structure.
On the plus side though, it makes it easier to move folders between collections if your domain holds such fluid possibilities.