centralized related posts system in jekyll using yaml data

Why Use Centralized YAML for Related Posts?

Previously, we used series or pillar fields in post front matter. While effective, managing related content through front matter can get messy as your site grows. A centralized YAML file provides:

  • Cleaner control over relationships
  • Faster content updates without editing individual posts
  • Support for non-linear or manual groupings

Step 1: Create a Data File for Related Posts

Create a file _data/related.yml with structure like:

template-performance:
  title: "Template Optimization Series"
  posts:
    - /jekyll/template-basics/
    - /jekyll/layout-optimizations/
    - /jekyll/template-performance/
    - /jekyll/minification/

jekyll-site-structure:
  title: "Jekyll Site Structure Guide"
  posts:
    - /jekyll/navigation-overview/
    - /jekyll/building-sidebar/
    - /jekyll/smart-related-posts/
    - /jekyll/yaml-based-relationships/

Each group contains a title and a list of post URLs. This gives you full editorial control.

Step 2: Connect the Current Page to Its Group

In your post front matter, add a key to associate with a group in the YAML file:

---
title: "Jekyll Template Performance Tips"
category: jekyll
related_group: template-performance
---

Step 3: Render Related Posts from Data File

In your layout or include file, add the following logic:

{% assign group_key = page.related_group %}
{% assign group_data = site.data.related[group_key] %}
{% if group_data %}
  <div class="related-posts">
    <h3>More in: {{ group_data.title }}</h3>
    <ul>
    {% for url in group_data.posts %}
      {% assign post = site.posts | where: "url", url | first %}
      {% if post and post.url != page.url %}
        <li><a href="{{ post.url }}">{{ post.title }}</a></li>
      {% endif %}
    {% endfor %}
    </ul>
  </div>
{% endif %}

This system checks the group for the current post, loads its title, and loops through all posts in that group, excluding the current one.

Step 4: Add a Fallback if No Group Found

To avoid empty output, consider adding a fallback using category or tag match:

{% unless group_data %}
  <h3>Related Articles in {{ page.category | capitalize }}</h3>
  <ul>
  {% assign related = site.posts | where: "category", page.category | where_exp: "p", "p.url != page.url" | limit: 3 %}
  {% for post in related %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% endfor %}
  </ul>
{% endunless %}

Advantages of the YAML-Based Approach

  • Manual curation without editing post files
  • Custom titles for related sections
  • Cross-category linking is easy
  • Better visibility for thematic or campaign content

Example Use Case: Campaign-Specific Guides

Imagine you're running a content campaign called “Launch Your Jekyll Site in a Week”. Instead of tagging or creating a category, just add a group like:

jekyll-launch-week:
  title: "Launch Your Jekyll Site in a Week"
  posts:
    - /jekyll/setup-github-pages/
    - /jekyll/choose-a-theme/
    - /jekyll/write-first-post/
    - /jekyll/push-live/

Now every article in that series gets meaningful related content, even if they span different categories or tags.

Tips for Maintaining Your Related YAML File

  • Use descriptive keys (e.g. launch-week, performance-tips)
  • Keep URLs updated — use relative URLs for consistency
  • Use a validator or syntax checker for your YAML if working at scale

Bonus: Display Group Navigation

You can also display the current group’s full list as a navigation menu for multi-part articles:

<nav class="related-nav">
  <h4>{{ group_data.title }}</h4>
  <ol>
  {% for url in group_data.posts %}
    {% assign post = site.posts | where: "url", url | first %}
    <li{% if post.url == page.url %} class="active"{% endif %}>
      <a href="{{ post.url }}">{{ post.title }}</a>
    </li>
  {% endfor %}
  </ol>
</nav>

Conclusion

By storing related post relationships in a YAML file, you unlock a structured, scalable, and highly flexible system. You can control related posts globally without modifying dozens of Markdown files, and the result is a much more coherent reading experience for your users.

In the next article, we’ll explore how to make this system multilingual by combining _data/related.yml with _data/i18n and language-aware layouts in Jekyll.


Archives / All Content


© BoostScopeNest . All rights reserved.