Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
437 views
in Technique[技术] by (71.8m points)

jekyll - List Subcategories in GitHub Pages

Edit: I've created a repository here that tests jibe's answer below. I just end up getting a blank page when I visit /animals, so any help is appreciated!

This is a follow-up to this question: Hierarchical Categories in GitHub Pages

In that question, I found out how to list the posts of a particular hierarchical category. Now I'm trying to figure out how to list the subcategories of a particular hierarchical category.

I'm using Jekyll on GitHub pages, and I want to have hierarchical categories like this:

  • animals -> mammals -> cats -> _posts -> housecat.md, tiger.md
  • animals -> mammals -> dogs -> _posts -> poodle.md, doberman.md
  • animals -> reptiles -> lizards -> _posts -> iguana.md, chameleon.md

I'd like users to be able to visit /animals and see a listing of the subcategories (mammals and reptiles). Then if they go to /animals/mammals, they'd see cats and dogs listed as subcategories.

I'm currently doing this manually by putting an index.html file inside each subcategory. But that makes updating things much more complicated than it probably should be.

I've tried following this answer, but that's meant for single tags, not multiple categories.

The catch is that any particular category might not be unique, so I can have stuff like this:

  • animals -> mammals -> bats -> _posts -> vampire.md, fruit.md
  • sports -> baseball -> bats -> _posts -> wiffle.md, teeball.md

I'd also like to be able to define frontmatter attributes in the subcategories, maybe in the index.html file of each? For example the animals->mammals->bats->index.html file would contain a frontmatter variable thumbnail with a value of "VampireBat.jpg", and sports->baseball->bats->index.html would have a thumbnail of "YellowWiffleBat.png". I'd like to be able to access these variables from the parent level (to show a thumbnail and a link to the subcategory).

My first thought was to access the subcategories directly, like this:

{% for mammalType in site.categories.animals.mammals %}
   <p>{{ mammalType.title }}</p>
   <img src="(( mammalType.thumbnail }}" />
{% endfor %}

Which I'd generalize using the categories from the page itself:

{% for subcategory in page.categories %}
   <p>{{ subcategory.title }}</p>
   <img src="(( subcategory.thumbnail }}" />
{% endfor %}

But that doesn't work at all, since site.categories.whatever is a list of all of the posts in that category, ignoring any hierarchical information.

Is there a better way to approach this other than doing it manually?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As it was suggested in my deleted answer, I post an improved version of my answer of your previous question. I also add information to answer your new questions (also deleted) :

Thanks for the reply. This almost works, but it's got a few problems. Most importantly, it doesn't support subcategories with the same name (like animals->bats and baseball->bats). It also lists every subcategory and every post under a particular category. I only want to list the subcategories, not the posts. Is there a way to modify your approach to meet those requirements? – Kevin Workman yesterday

Modify your _config.yml accordingly

collections:
    animals:
        output: true
        mammals:
            output: true
            cats:
                output: true
            dogs:
                output: true
        reptiles:
            output: true
            lizards:
                output: true

then created the structure:

mkdir -p _animals/reptiles/lizards
mkdir -p _animals/mammals/cats
mkdir _animals/mammals/dogs

add your md files and all index.html you need to make the list you want. which will index items with filter. From the top directory, your animals collection should look like this (with index.html in each folder) :

cleaner

root/
└── _animals/
    ├── index.html
    ├── mammals
    │   ├── cats
    │   │   ├── housecat.md
    │   │   └── tiger.md
    │   ├── dogs
    │   │   ├── doberman.md
    │   │   └── poodle.md
    │   └── index.html
    └── reptiles
        └── lizards
            ├── chameleon.md
            └── iguana.md

new you can list only subcategories with or without going deeply (with an optional parameters) _includes/list_subcategories.html

 {% assign animals = site.animals| sort:'title' %}
 {% assign from = page.url | remove: '/index.html' %}
 {% assign deep = (page.url | split: '/' | size) + 1 %}
 {% for animal in animals %}
 {% assign d = animal.url | remove: '/index.html' | split: '/' | size %}
 {% if animal.url != page.url and animal.url contains from and animal.url contains "index" and (include.dig or deep == d) %}
 <a  href={{ animal.url | prepend: site.baseurl }}>{{animal.title}}</a>
 {% endif %}
 {% endfor %}

improved similarly to list animals _includes/list_animals.html

{% assign animals = site.animals| sort:'title' %}
{% assign from = page.url | remove: '/index.html' %}
{% assign deep = (page.url | split: '/' | size) + 1 %}
{% for animal in animals %}
{% assign d = animal.url | remove: '/index.html' | split: '/' | size %}
{% if animal.url contains "index" or animal.url == page.url %}
{% else %}
    {% if animal.url contains from  and (include.dig or deep == d) %}
    <a  href={{ animal.url | prepend: site.baseurl }}>{{animal.title}}</a>
    {% endif %}
{% endif %}
{% endfor %}

list all subcategories and all animals in animals/index.html :

---
title: animals
---
{% include list_subcategories.html dig=true %}
<hr>
{% include list_animals.html dig=true %}

For example, to list all mammals and subcategoeries in animals/mammals/index.html :

---
title: animals
---
{% include list_subcategories.html %}
<hr>
{% include list_animals.html %}

Finally the generated structure should look like this (with some more index.html):

cleaner

root/
├─ _animals/
│   └─── ...
└── _site
    └── animals
        ├── index.html
        ├── mammals
        │   ├── cats
        │   │   ├── housecat.html
        │   │   └── tiger.html
        │   ├── dogs
        │   │   ├── doberman.html
        │   │   └── poodle.html
        │   └── index.html
        └── reptiles
            └── lizards
                ├── chameleon.html
                └── iguana.html

it solves your question. I changed from taxonomy to dig, but you could also have distinguished between animals->bats and baseball->bats by putting taxonomy="baseball/bats"?or taxonomy="animals/bats".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...