How to make a taxonomy page that lists book titles and their chapters underneath?

Say I’m writing a book, and each chapter I’m posting as a blog post. In the front matter of each post I can have something like

books:
  - Title of this Amazing Book
chapter: 1
chaptertitle: Title of this Chapter

What I would like is a page at /books/ that lists all the different books and then under the name of the book, it lists the chapter and chapter titles (like a Table of Contents).

The name of the book itself you could click and it would go to a page that lists the Table of Contents of that book (and maybe some .Content also).

You can also click the Chapter Title to go read that chapter post. (from both the /books/ page and the page specifically for the particular book).

How could I do this with taxonomies?

BONUS Round: How could I do a shortcode that I could put at the end of my chapter blog post that shows a list of the other chapter numbers from within the same book as this post (without the titles) and/or shows a button or two that say previous chapter / next chapter?

Are you open to redefine structure a bit?

sure, if it works well and easy to manage

Here’s how, using what you mentioned: Make books a taxonomy. Either name the files after chapter numbers (01.md or chapter-01.md), or create another parameter called chapter for the number, like you did (except I’d use one or two leading zeroes, 001). Then either paginate or do the previous and next links using chapter publish date or number.

The way I would actually do it, personally: create a section for each book. Name content files chapter-001.md. Set section list template to show chapters in the order by file name.

I like simple things. :slight_smile:

1 Like

Yeah, I’d do sections. I was trying to use 2 taxonomies ( books and chapters ) and trying a couple different things. But that totally messes the url structure.
Sections would be a lot simpler.

I thought about doing it in each book as a section. then I could make a page in the /content/ root like books.md and in the content of that I could have a shortcode that calls the list partial to list the chapters for each book and that’d be an easier way to just edit that content file when adding a new book. i guess it could be done with frontmatter too. i say all this cause mainly I’d like a menu item to point to /books/ and show the multiple books available, instead of having a menu item for each individual book.

but i think structurally it does make more sense to be a section per book, instead of of mixing it in with blog posts.

since the homepage only lists posts from the blog section, I could make a blog post that links to the new chapter

i’m just trying to work within a real crappy theme. rather not change it now but will definitely do so later.

You could set the menu in books.md

menu:
  books:
    weight: 1

That will give you a single menu item for books

yea, adding it to the menu is the easy part, the less easy part is getting that page (a custom template) to populate with the multiple books and their contents. can’t do it automatically since they’d be sections so with each new book, something in the the frontmatter of books.md or in the content by way of a shortcode would have to be added in order to add a book and it’s contents to the page.

It sounds like you want a page that is multiple TOC for each book on the site. Let me point out that is a very weird thing for a visitor to see. Chapters might have spoilers, and as you add more books, the page is going to get unwieldy.

That aside, create each book in its own section, and use a books taxonomy. Then, in /layouts/taxonomy/book.terms.html, list each term, maybe with a description loaded from wherever, and each term will link to /layouts/taxonomy/book.html, where you can go nuts with the chapter listings.

You could even do a nested range on the terms page (which renders at example.com/books, btw), so under each book title (taken from the taxonomy) you can list the chapters as a list (I would make it inline, numbered blocks, and ensure colors change on read links, so they can get back to where they were reading easily).

Does that make sense? It kinda answers your original question.

Note the paths I pointed out in the prior reply. If your theme does the standard header and footer partials in templates, you ought to be able to create custom templates outside of your theme (in layouts) and load those partials, and then if you change themes you just change the partials to point at the new theme, but your templates will remain.

The list with all the books and the chapters underneath is what I was thinking (no chapter titles, just chapter numbers so it’s not out of control and you can quickly jump to whatever chapter you haven’t read). So yea you were thinking along my lines.

As my first foray into these taxonomy structures, i’ll have to ruminate on your suggestion. I think it makes sense but it’s not obvious to me yet. thank you!

@gaetawoo this kept me thinking for a while. I’m still learning hugo, and I haven’t created a site with nested sections. So I played around with it as an exercise to help me learn.

Check this repo and this example site.

I made a structure like this:

| - books
| - - firstbook
| - - - _index.md
| - - - 001.md
| - - - 002.md
| - - secondbook
| - - - _index.md
| - - - 001.md
| - - - 002.md
| - - _index.md

Then in /books/_index.md I placed a shortcode that lists all books and nested chapters. In /books/firstbook/_index.md I placed a shortcode that lists all the chapters.

I’m still missing the shortcode to next and previous. But I think that can be done by putting a “weight” variable on each chapter. Then just get all the pages in the sub section and filter just the one that has a .Params.weight -1 and +1…

One last thing, I had to use shortcodes instead of templates because currently there is no way to have a different template for a nested section and a normal section. So you would need to use the same template for both books and chapters.

– Edit –
Turns out, making the next and prev buttons was a lot easier than I thought. You would just need the “.Next” and “.Prev” variables @maiki mentioned. Lovely.

1 Like