问题
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 every post from every category. But if they go to /animals/mammals
, they'd only see mammals. If they go to /animals/mammals/cats
, then they only see cats.
I know I can do this manually by putting an index.html
file in every single directory and then looping through site.categories.mammals
or site.categories.cats
, for example.
But that seems a little bit too brute force, and I'm hoping there's a better way. If I want to change how I'm showing the listings, I'll have to change that in every single subcategory. I'll also have problems when subcategories share a name, like /ABC/XYZ/_posts/one.md
and /DEF/XYZ/_posts/two.md
.
I've tried to follow this article, which uses one main category.html
page that loops through page.category
:
{% for post in site.categories.[page.category] %}
<h2><a href=""></a></h2>
<p></p>
{% endfor %}
Then every index.html
file uses this as its layout. That almost works, but it seems limited to one category, not multiple hierarchical categories.
Is there a less brute-force approach to creating listings for hierarchical categories?
回答1:
page.categories is a list
https://stackoverflow.com/a/23927986
{% for cat in page.categories %}
<h1>{{ cat }}</h1>
<ul>
{% for post in site.categories[cat] %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endfor %}
From jekyll's documentation about page.category http://jekyllrb.com/docs/variables/#page-variables
The list of categories to which this post belongs. Categories are derived from the directory structure above the _posts directory. For example, a post at /work/code/_posts/2008-12-24-closures.md would have this field set to ['work', 'code']. These can also be specified in the YAML Front Matter.
You should be easily able to add a simple dynamic index.html to every folder and the categories should be hierarchical automatically.
Update
The above does NOT work. You need to treat the combination of categories of each hierarchy as a unique item. Concat the index page's categories, and compare that against all the posts in the site.
/foo/bar/_posts/2016-08-01-foo-bar-test.html
---
categories:
- foo
- bar
title: test foo bar
---
<h2>Foo Bar</h2>
/var/bar/_posts/2016-08-01-test-var-bar.html
---
categories:
- var
- bar
title: test var bar
---
<h2>Var Bar</h2>
/foo/bar/index.html
---
categories:
- foo
- bar
---
{% assign pagecat = page.categories | join ' ' | append: ' '%}
{% assign pagecatlen = page.categories.size %}
<h1>{{ cat }}</h1>
<ul>
{% for post in site.posts %}
{% assign postcat = '' %}
{% for thispostcat in post.categories limit: pagecatlen %}
{% assign postcat = postcat | append: thispostcat %}
{% assign postcat = postcat | append: ' ' %}
{% endfor %}
{% if (postcat == pagecat) %}
<li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endif %}
{% endfor %}
</ul>
The categories are optional for the files in _posts, but they are required for the front matter of each index file.
回答2:
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 which will index items with filter. It should look like this (maybe with more indexes) :
_animals/
├── index.html
├── mammals
│ ├── cats
│ │ ├── housecat.md
│ │ └── tiger.md
│ ├── dogs
│ │ ├── doberman.md
│ │ └── poodle.md
│ └── index.html
└── reptiles
└── lizards
├── chameleon.md
└── iguana.md
then you create _includes/list_animals.html
{% assign animals = site.animals| sort:'title' %}
{% for animal in animals %}
{% if page.url != animal.url and include.taxonomy == nil or animal.url contains include.taxonomy %}
<a href={{ animal.url | prepend: site.baseurl }}>{{animal.title}}</a>
{% endif %}
{% endfor %}
to list all animals in animals/index.html
:
---
title: animals
---
{% include list_animals.html %}
For example, to list all mammals in animals/mammals/index.html
:
---
title: animals
---
{% include list_animals.html taxonomy="mammals" %}
Finally the generated structure should look like this (with some more index.html):
_site
└── animals
├── index.html
├── mammals
│ ├── cats
│ │ ├── housecat.html
│ │ └── tiger.html
│ ├── dogs
│ │ ├── doberman.html
│ │ └── poodle.html
│ └── index.html
└── reptiles
└── lizards
├── chameleon.html
└── iguana.html
来源:https://stackoverflow.com/questions/38700154/hierarchical-categories-in-github-pages