Combining Tags and Categories for Smart Index Navigation

Why Merge Tags and Categories in Jekyll Most Jekyll sites separate tags and categories into distinct navigation paths. Categories are often shown in sidebars or menus, while tags live in post metadata or isolated tag pages. This division creates friction for users who want to browse content naturally based on relevance or context. By combining both systems in one smart index, we allow visitors to explore both hierarchical and associative relationships between content items. This results in better usability, discoverability, and even SEO improvements due to internal link clustering. Use Case: A Developer Knowledge Base Let’s say we’re building a knowledge base for developers using Jekyll collections. Each resource item belongs to a category like “Performance” or “Theming,” and also has tags such as “includes,” “scss,” or “responsive.” Our goal is to create an index that looks like this: Performance (category) includes (tag) Optimizing I...

Designing Custom Layouts and Filters for Jekyll Collections

Why Custom Layouts and Filters Matter in Jekyll Projects

Once you start organizing your Jekyll content with collections, the next natural step is controlling how those collections are presented. Instead of using a one-size-fits-all layout, custom layouts tailored to each content type improve usability, design, and structure.

In tandem with custom layouts, Liquid filters allow you to sort, group, and transform content dynamically in your templates. This article walks you through real-world examples for combining both techniques to build elegant and flexible sites.

Case Study: Creating a Multi-Level Tutorial Platform

Imagine you're building a tutorial platform where each tutorial has:

  • A level (beginner, intermediate, advanced)
  • An estimated reading time
  • A difficulty badge and progress bar

Your goal is to create a custom layout that highlights this metadata and displays it consistently across the entire _tutorials collection.

Step 1: Define Custom Layout for the Collection

Start by creating a new layout file: _layouts/tutorial.html

{% raw %}

  
    
    {{ page.title }}
    
  
  
    

{{ page.title }}

{{ page.difficulty | capitalize }}

Reading Time: {{ page.reading_time }} min

{{ content }}
{% endraw %}

This layout introduces structured display of metadata using front matter like difficulty and reading_time. You can further enhance this by using custom Liquid filters.

Step 2: Apply the Layout in a Collection Item

---
title: Mastering Liquid Filters
difficulty: advanced
reading_time: 7
layout: tutorial
---

With just these three fields, your tutorial file gets a fully branded and styled layout. You can even customize styles with CSS based on .badge-advanced, .badge-beginner, etc.

Step 3: Filter Tutorials on the Listing Page

On your tutorials.html page, you may want to group or highlight tutorials based on difficulty:

{% raw %}

Advanced Tutorials

    {% for tut in site.tutorials %} {% if tut.difficulty == "advanced" %}
  • {{ tut.title }} ({{ tut.reading_time }} min)
  • {% endif %} {% endfor %}
{% endraw %}

This is basic filtering logic using built-in Liquid conditionals. But let’s take this further.

Using Custom Liquid Filters (Advanced Technique)

Jekyll doesn’t support custom Liquid filters on GitHub Pages unless you use plugins locally. But you can emulate filter-like behavior by using assign, where, and sort.

Sorting by Reading Time

{% raw %}{% assign sorted_tuts = site.tutorials | sort: "reading_time" %}
{% for tut in sorted_tuts %}
  
  • {{ tut.title }} - {{ tut.reading_time }} minutes
  • {% endfor %}{% endraw %}

    Grouping by Difficulty

    {% raw %}{% assign levels = "beginner,intermediate,advanced" | split: "," %}
    {% for level in levels %}
      

    {{ level | capitalize }}

      {% for tut in site.tutorials %} {% if tut.difficulty == level %}
    • {{ tut.title }}
    • {% endif %} {% endfor %}
    {% endfor %}{% endraw %}

    This allows for structured group display without requiring hard-coded blocks per difficulty level.

    Combining with Front Matter Defaults

    To reduce repetition, you can predefine default front matter for tutorials in _config.yml:

    defaults:
      - scope:
          path: "_tutorials"
        values:
          layout: tutorial
          difficulty: intermediate
    

    Now you only need to override values when necessary in the individual tutorial files.

    Case Study: Portfolio Projects with Custom Layouts

    If you have a portfolio collection, each project can have a unique layout showing:

    • Tags (e.g., "React", "Node.js")
    • Screenshots in a gallery
    • A GitHub or live demo link

    Example front matter:

    ---
    title: Weather Dashboard
    tags: [React, API]
    screenshots:
      - /img/weather-1.png
      - /img/weather-2.png
    github: https://github.com/user/weather
    layout: project
    ---

    In _layouts/project.html:

    {% raw %}

    {{ page.title }}

      {% for tag in page.tags %}
    • {{ tag }}
    • {% endfor %}
    {% for shot in page.screenshots %} Screenshot {% endfor %}
    {% if page.github %} View on GitHub {% endif %}{% endraw %}

    This dynamic layout makes it easy to standardize how project content is presented while still allowing for variation in fields.

    Client-Side Filtering Using JSON and Liquid

    To add client-side interactivity without a JavaScript framework, you can generate a JSON file from your collection:

    # _plugins/json-generator.rb (for local builds)
    require 'json'
    module Jekyll
      class JSONGenerator < Generator
        safe true
    
        def generate(site)
          tutorials = site.collections['tutorials'].docs.map do |doc|
            {
              title: doc.data['title'],
              url: doc.url,
              difficulty: doc.data['difficulty'],
              reading_time: doc.data['reading_time']
            }
          end
    
          File.open('tutorials.json', 'w') do |f|
            f.write(JSON.pretty_generate(tutorials))
          end
        end
      end
    end

    Now use JavaScript to fetch and filter tutorials dynamically on the frontend.

    Conclusion

    Custom layouts and Liquid filters unlock the full potential of structured content in Jekyll. By tailoring the layout and behavior of each collection type, you not only improve user experience but also gain editorial control and scalability for your site.

    In the next article, we’ll go even deeper and explore how to build an interactive search interface for collections using client-side JavaScript and JSON output, while still maintaining a fully static GitHub Pages deployment.


    Archives / All Content


    © AdTrailScope🕒😀😀😀 . All rights reserved.