Jwan622
Jwan622

Reputation: 11647

How to create a category/tags page in Jekyll without a list of posts for that tag?

I want to create a Jekyll site where the root page/index.html in root folder just has list of tags/categories (let's say both are the same right now). I want each tag/category to link to a tag_page where it has the tag and the posts associated with each tag. Right now, I have this as my root index.html:

{% capture tags %}
  {% for tag in site.tags %}
    {{ tag[0] }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}

{% for tag in sortedtags %}
  <h3 id="{{ tag }}">{{ tag }}</h3>
  <ul>
  {% for post in site.tags[tag] %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% endfor %}
  </ul>
{% endfor %}

which lists the tags and the posts for each tag on the main page.

Instead, I would like this:

{% capture tags %}
  {% for tag in site.tags %}
    {{ tag[0] }}
  {% endfor %}
{% endcapture %}
{% assign sortedtags = tags | split:' ' | sort %}

{% for tag in sortedtags %}
  <a href="{{ tag.url }}">{{ tag }}</a>
{% endfor %}

But tag.url doesn't work right now. I would like each tag.url to take me to this following page where it lists the tag name and the posts per tag. How do I do this?

This is my tag_page layout in my _layouts folder. I want this to load when someone clicks on a tag in the index.html file.

---
layout: default
---

<h1>{{ page.tag }}</h1>

<ul>
{% for post in site.tags[page.tag] %}
  <li>
    {{ post.date | date: "%B %d, %Y" }}: <a href="{{ post.url }}">{{ post.title }}</a>
  </li>
{% endfor %}
</ul>

Upvotes: 0

Views: 1112

Answers (2)

mnishiguchi
mnishiguchi

Reputation: 2241

I would like to share my implementation of simple tag cloud and tags page. It is working perfectly in this blog website.

Demo

Implementation

1. Create a partial for a tag cloud

I created a partial _include/tag_cloud.html for reusability. This partial displays all the site tags and each tag links to its corresponding section of tags.html page. It optionally take an array of tag names as an argument. Using this partial, I can place a list of tags anywhere I wish.

{% comment %}
<!--
- If tag_names array is not passed in as argument,
  - Create an empty array,
  - Obtain a tag name and push it to the array, and
  - Sort the tag names.
- List tags as a tag cloud.
-->
{% endcomment %}

{% if include.tag_names %}
  {% assign tag_names = include.tag_names %}

{% else %}
  {% assign tag_names = "" | split: "|"  %}

  {% for posts_by_tag in site.tags %}
    {% assign tag_names = tag_names | push: posts_by_tag.first %}
  {% endfor %}

  {% assign tag_names = tag_names | sort %}
{% endif %}

<ul class="tag-cloud">
  {% for tag_name in tag_names %}
    <li>
      <a href="{{ baseurl }}/tags#{{ tag_name | slugize }}">
        {{ tag_name }}
      </a>
    </li>
  {% endfor %}
</ul>

2. Create a page for displaying a tag cloud and post titles under each tag

I create a page tags.html that is dedicated to display a tag cloud (created above) and post titles under each tag. At the top of the page, it lists all the tags as a tag cloud, and each tag links to its own section in the page. Below the tag cloud, I place links to blog posts that are grouped by tags.

---
layout: page
title: Posts By Tags
permalink: /tags
---

{% assign tag_names = "" | split: "|"  %}

{% for posts_by_tag in site.tags %}
  {% assign tag_names = tag_names | push: posts_by_tag.first %}
{% endfor %}

{% assign tag_names = tag_names | sort %}

{% include tag_cloud.html tag_names=tag_names %}

<hr>

<section class="posts-by-tags">
  {% for tag_name in tag_names %}
    <div>
      <h3 id="{{ tag_name }}">
        {{ tag_name | capitalize | replace: "_", " " }}
      </h3>

      {% for post in site.tags[tag_name] %}
        <a href="{{ post.url | prepend: baseurl }}">
          {{ post.title }}
        </a>
      {% endfor %}
    </div>
  {% endfor %}
</section>

Related posts

Upvotes: 3

Shadowen
Shadowen

Reputation: 836

Unfortunately, to generate additional tags/<tag>.html pages, you will need to generate pages with a Jekyll plugin.

The easiest way to implement this would probably just to have a tags.html page containing all the posts for all tags, then use JavaScript to show/hide the correct sections. With Jekyll you can still generate urls like /tags.html#<tag>, then retrieve the tag name with window.location.hash. From there, use JQuery selectors to show/hide the matching elements.

Upvotes: 1

Related Questions