I want to publish chapters of multiple books, looking for guidance

  • I want all books to share the same Huge site, I realize this would probably be easier to setup right with a Hugo setup for each book
  • I want to be able to publish chapters of a specific book in this kind of link structure

www.example.site/books/title-of-book/chapter-1/

www.example.site/books/title-of-book/ ← chapter 0 page, listing information, book cover, tags related to that book

www.example.site/books/ ← root of the Hugo public folder, I want to be able to list recent chapters from all books on the site here

  • I want an easy way for readers to be able to go to the next and previous chapters of a specific book title without these links needing to be able to set up manually
  • I want to be able to set a chapter 0 of a specific book title and have it link all chapters along with publish dates, preferably able to be setup in an automated way

Has anyone used Hugo to do something like this before? Any suggestions on how to do the various parts the right way would be helpful.

I’m using this theme for this project. I don’t know of one more suitable for what I’m trying to do.

One of the problems I’m facing is that if I have multiple branch bundle (what I’m trying to use to organize books) only the posts of a single one shows up on the main page.

Using multiple branches other than posts also seems to break part of tags. The tag page populates, but when you click a tag for something in another branch bundle no posts/chapters which have that tag show up.

I’ll use this thread to document my struggles with trying to get this all to work.

Get yourself a blog to document your struggles :wink:

First of all, have a look at sections:

Use one subfolder in your content directory per book. This is called a section. Add _index.md for the main page of the book and add chapter-1.md, chapter2-md, etc. or whatever name you wish as subchapters in the same folder.

Then either use one design for all (layouts/_default/single.html, layouts/_default/list.html for the _index.md) or add one design per section (with _default as fallback) in layouts/sectionname/(index|list).html

Add two booka content wise, then see if it works. THEN start thinking about the design. IN such a project I would always start with a clear content structure so you won’t have to restart when you find out your content is unusable structured.

1 Like

You won’t be able to have layouts per book, they will all look the same. If you are ok with that then keep this structure.

I think I did this with the Branch Bundle? Or maybe I don’t understand the difference yet. The pages show as expected but two things break in the theme I am using which I do want that being tags not fully working and the main page only listing one branch/section?

I’ll make a public repo of what I’m trying to do so it can be shared and be easier to see what’s wrong.

I have published an example repo here. I figure eventually someone else will want to do something similar so I’ll leave this up once it’s all working as desired.

The main issue right now from making this fresh is that only chapters from a single book show up in the front page. There are 2 books with 2 chapters in the sample.

/books/dracula/

/books/wuthering-heights/

But for me only Dracula shows up.

Would it be something to do with the theme or something else?

The theme uses the internal mainSections method.

If you define that array in config.yml like so:

    mainSections:
     - dracula
     - wuthering-heights

Then you will see the chapters from both books on the homepage.


There are other themes meant for books that seem better suited for your use case, like for example:

I would prefer a simpler setup, like serving an entire book on a single page and using the TOC feature to create anchor links for the each chapter.

Anyway it’s up to you to decide how you want to structure your project.

1 Like

A bit of advertising. Wowchemy has a book feature that may come in handy here.

(I’m one of the moderators of the Wowchemy Discord Server)

1 Like

Thank you, putting that under params did help to make all chapters show up on the main page.

I did see this before and though it has the book title in its name it seems more suitable for documentation or perhaps a book published all at once.

A reason for the structure of what I’m working on is that single chapters are published over time following the webnovel pattern.

There are a few more issues related to this project so I won’t mark any solutions as I’d like this thread to not be locked until everything is working. :prayer_beads:

The next thing I wanted to be able to do is to selectively disable breadcrumbs on a page.

Turns out it is as simple as setting the front matter param on the page, I was overthinking it.

---
title: "About Book Project"
searchHidden: true
draft: false
ShowBreadCrumbs: false
---

This site is a book project.

Next is adjusting this which I feel like will be easy and hard for me.

Maybe swap the left/right of the “next page / previous page” widget so it’s more logical to reading a book, might be other moving parts related to that which are going to require special changes to work cleanly

A problem is I want to exclude sections not within the current section. Now that mainSections is defined, all of those sections show up in the next/previous buttons.

This is the template currently

    {{- if .Site.Params.ShowPostNavLinks }}
    {{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}
    {{- if and (gt (len $pages) 1) (in $pages . ) }}
    <nav class="paginav">
      {{- with $pages.Next . }}
      <a class="prev" href="{{.Permalink}}">
        <span class="title">« Previous Chapter</span>
        <br>
        <span>{{- .Name -}}</span>
      </a>
      {{- end}}	 	
      {{- with $pages.Prev . }}
      <a class="next" href="{{.Permalink}}">
        <span class="title">Next Chapter »</span>
        <br>
        <span>{{- .Name -}}</span>
      </a>
      {{- end}}
 
    </nav>
    {{- end }}
    {{- end }}

I need to do a few things

  • Only include sections of the current page, not other sections
  • Reverse the chronological order of presenting sections, it currently presents a chapter 2 as being previous to a chapter 1

I’m not yet familiar enough with how to modify the shortcodes yet to do this.

{{- with $pages.Prev . }}
{{- with $pages.Next . }}

Swapping these seems to work. Then only including the pages of the section related to this page is left for this part.

I think I need to use either .CurrentSection or .Section here but I don’t know how to properly yet.

{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}

Got it I think

{{- $pages := where site.RegularPages "Section" "==" .Section }}

Reading this helped where | Hugo


Next I want to try to automatically generate a list of posts within the section of a page excluding the current page.

So what I want would be like

...
Chapter 2 - 3/1/2021
Chapter 1 - 3/1/2021

With each line being a link to that chapter.

The way I will try to do this is with shortcodes. I will use shortcodes for the list of books and featured list as well.

{{< listchapters >}}
{{< listbooks >}}
{{< listfeatured >}}

For the chapters I believe I can use similar code as listed above for the previous/next buttons except include all of them.

For the books I’ll also use similar code but pull from the main sections config.

For featured I’ll do similar but make a new config for featured book listing within the config.

I think this page should help for this so I’m studying it next.

Progress on this.

For
{{< listchapters >}}

I referenced the _default/list.html and modified it.

This shortcode now seems to work:

{{- $pages := where site.RegularPages "Section" "==" $.Page.Section }}

{{- range $pages }}

<article>
  <header>
    <p>
	<a aria-label="post link to {{ .Title | plainify }}" href="{{ .Permalink }}">
		{{ .Title }}
		{{- if .Draft }}<div class="entry-isdraft"><sup>&nbsp;&nbsp;[draft]</sup></div>{{- end }}
		{{- if not .Date.IsZero -}}
		&nbsp;-&nbsp;
		{{- (.Date.Format (default "January 2, 2006" .Site.Params.DateFormat)) }}
		{{- end -}}
	</a>		
    </p>
  </header>

</article>
{{- end }}

Now I need to style it as desired.

I want the posts to show up in reverse of what they are am I’m not sure how to do it.

I can see that there is a way sort so it would be something like this?

{{- range sort $pages }}

But I’m not sure what else is needed so the posts are listed by dates in order from top to bottom

Got it

{{- range sort $pages.ByDate }}

For another similar shortcode for listing the latest chapters but limiting to only the first 5 I changed the range to the below.

{{- range first 5 $pages}}

Related to this post

When I do this I can’t include links by themselves I have to have some text first. I also can’t use : in the description, how do I use this / escape it?

---
title: "Wuthering Heights"
description: Links -- [Description & Chapters](/books/wuthering-heights/front/) • [Chapter I](/books/wuthering-heights/chapter-1/)
author: Emily Brontë
searchHidden: true
draft: false
date: 1614546475
---

The above works but I can’t do

description: [Description & Chapters](/books/wuthering-heights/front/) • [Chapter I](/books/wuthering-heights/chapter-1/)

I get: failed to unmarshal YAML: yaml: line 1: did not find expected key

When I do

description: Links: [Description & Chapters](/books/wuthering-heights/front/) • [Chapter I](/books/wuthering-heights/chapter-1/)

I get: failed to unmarshal YAML: yaml: line 2: mapping values are not allowed in this context

You need to encapsulate the value with quotation marks.

title: "Wuthering Heights"
description: "[Description & Chapters](/books/wuthering-heights/front/) • [Chapter I](/books/wuthering-heights/chapter-1/)"
author: Emily Brontë
searchHidden: true
draft: false
date: 1614546475
---
1 Like

Thank you, that works, I should have realized that.


For the listbooks shortcode I have this so far

{{ range sort .Site.Sections}}
  <li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
{{ end }}

I’d like to sort the sections alphabetically of the title (this does not) and to only include sections within site.Params.mainSections

You are more likely to receive a prompt and accurate response if you post a link to the public repository for your project. Please make sure you have pushed your local changes.