feat: derive sidebar from content

This commit is contained in:
2026-06-21 18:01:31 +00:00
parent b9b78db633
commit f8af9035e8
6 changed files with 36 additions and 61 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ weight = 12
The fast path is to change four things in `hugo.toml`: `baseURL`, `title`, `params.sidebarFooter`, and `params.homeFooter`. The fast path is to change four things in `hugo.toml`: `baseURL`, `title`, `params.sidebarFooter`, and `params.homeFooter`.
Then adjust `menus.main`. The sidebar shape comes from the menu, so you do not need a special data file or extra config layer. Then adjust `title` and `weight` in your content files. The sidebar shape comes from the section tree, so you do not need a special data file or a menu block for each page.
If you want a different voice on the homepage, edit `content/_index.md`. If you want layout changes, start in `themes/starless/layouts/_default/baseof.html`. If you want a different voice on the homepage, edit `content/_index.md`. If you want layout changes, start in `themes/starless/layouts/_default/baseof.html`.
+3 -3
View File
@@ -6,11 +6,11 @@ weight = 13
The files that matter are not hard to find. The files that matter are not hard to find.
- `hugo.toml` sets the theme, site title, footer text, and sidebar menu. - `hugo.toml` sets the theme, site title, and footer text.
- `content/` holds the homepage and this short guide. - `content/` holds the homepage and this short guide. Its section tree also drives the sidebar.
- `themes/starless/layouts/_default/baseof.html` builds the page shell and the shared styling. - `themes/starless/layouts/_default/baseof.html` builds the page shell and the shared styling.
- `themes/starless/layouts/partials/sidebar.html` renders the left rail. - `themes/starless/layouts/partials/sidebar.html` renders the left rail.
- `themes/starless/layouts/partials/menu-tree.html` renders the nested menu links. - `themes/starless/layouts/partials/menu-tree.html` renders the nested section and page links.
- `themes/starless/layouts/_default/home.html`, `list.html`, and `single.html` handle the main content area. - `themes/starless/layouts/_default/home.html`, `list.html`, and `single.html` handle the main content area.
If you are trying to understand the theme, read those files in that order. There is not much else hiding off to the side. If you are trying to understand the theme, read those files in that order. There is not much else hiding off to the side.
+1 -1
View File
@@ -8,6 +8,6 @@ If you fork this repo, you already have the theme and the demo site in one place
If you want to drop Starless into another Hugo site, copy the `themes/starless/` folder into that project and set `theme = "starless"` in `hugo.toml`. If you want to drop Starless into another Hugo site, copy the `themes/starless/` folder into that project and set `theme = "starless"` in `hugo.toml`.
After that, add a small `menus.main` block so the sidebar has something to render. The current config in this repo is enough to copy and trim. After that, add an `_index.md` for each section you want listed and set `weight` in front matter to control order. The sidebar follows the `content/` tree automatically.
Run `hugo server` and edit from there. The theme is simple enough that most changes show up where you expect. Run `hugo server` and edit from there. The theme is simple enough that most changes show up where you expect.
-29
View File
@@ -22,32 +22,3 @@ inline = [["\\(", "\\)"]]
description = "Starless is a small Hugo theme for dark, text first sites." description = "Starless is a small Hugo theme for dark, text first sites."
sidebarFooter = "Built with Hugo." sidebarFooter = "Built with Hugo."
homeFooter = "Small on purpose." homeFooter = "Small on purpose."
[[menus.main]]
name = "Guide"
pageRef = "/docs"
weight = 10
[[menus.main]]
name = "Install"
pageRef = "/docs/install"
parent = "Guide"
weight = 11
[[menus.main]]
name = "Customize"
pageRef = "/docs/customize"
parent = "Guide"
weight = 12
[[menus.main]]
name = "Files"
pageRef = "/docs/files"
parent = "Guide"
weight = 13
[[menus.main]]
name = "How it looks?"
pageRef = "/docs/how-it-looks"
parent = "Guide"
weight = 14
+23 -19
View File
@@ -1,29 +1,33 @@
{{- range .ByWeight -}} {{- range .nodes.ByWeight -}}
{{- if eq $.level 0 -}}
<div class="flex flex-col"> <div class="flex flex-col">
<a class="flex items-center {{ if .HasChildren }}text-on-surface{{ else }}text-on-surface-variant{{ end }} hover:text-primary transition-colors py-1 text-left w-full group" href="{{ .URL }}"> <a class="flex items-center {{ if .IsSection }}text-on-surface{{ else }}text-on-surface-variant{{ end }} hover:text-primary transition-colors py-1 text-left w-full group" href="{{ .RelPermalink }}">
<span class="material-symbols-outlined text-[16px] mr-1 text-on-surface-variant group-hover:text-primary">{{ if .HasChildren }}expand_more{{ else }}chevron_right{{ end }}</span> <span class="material-symbols-outlined text-[16px] mr-1 text-on-surface-variant group-hover:text-primary">{{ if .IsSection }}expand_more{{ else }}chevron_right{{ end }}</span>
{{ .Name }} {{ .LinkTitle }}
</a> </a>
{{- with .Children -}} {{- if .IsSection -}}
{{- with .Pages.ByWeight -}}
<div class="ml-6 flex flex-col gap-1 text-on-surface-variant text-label-sm tree-item mt-1 mb-2"> <div class="ml-6 flex flex-col gap-1 text-on-surface-variant text-label-sm tree-item mt-1 mb-2">
{{- range .ByWeight -}} {{ partial "menu-tree.html" (dict "nodes" . "level" (add $.level 1)) }}
{{- if .HasChildren -}}
<div class="flex flex-col">
<a class="flex items-center hover:text-on-surface transition-colors py-0.5" href="{{ .URL }}">
<span class="material-symbols-outlined text-[14px] mr-1 text-on-surface-variant">expand_more</span>
{{ .Name }}
</a>
<div class="ml-5 flex flex-col gap-1 text-on-surface-variant text-label-sm tree-item mt-1 italic">
{{ range .Children.ByWeight }}
<a class="hover:text-on-surface transition-colors py-0.5" href="{{ .URL }}">{{ .Name }}</a>
{{ end }}
</div> </div>
{{- end -}}
{{- end -}}
</div> </div>
{{- else -}} {{- else -}}
<a class="hover:text-on-surface transition-colors py-0.5 italic" href="{{ .URL }}">{{ .Name }}</a> {{- if .IsSection -}}
{{- end -}} <div class="flex flex-col">
{{- end -}} <a class="flex items-center hover:text-on-surface transition-colors py-0.5" href="{{ .RelPermalink }}">
<span class="material-symbols-outlined text-[14px] mr-1 text-on-surface-variant">expand_more</span>
{{ .LinkTitle }}
</a>
{{- with .Pages.ByWeight -}}
<div class="ml-5 flex flex-col gap-1 text-on-surface-variant text-label-sm tree-item mt-1 italic">
{{ partial "menu-tree.html" (dict "nodes" . "level" (add $.level 1)) }}
</div> </div>
{{- end -}} {{- end -}}
</div> </div>
{{- else -}}
<a class="hover:text-on-surface transition-colors py-0.5 italic" href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
{{- end -}}
{{- end -}}
{{- end -}} {{- end -}}
@@ -9,8 +9,8 @@
</button> </button>
<nav class="flex flex-col gap-1 text-sm" aria-label="Primary"> <nav class="flex flex-col gap-1 text-sm" aria-label="Primary">
{{ with site.Menus.main }} {{ with site.Sections }}
{{ partial "menu-tree.html" . }} {{ partial "menu-tree.html" (dict "nodes" . "level" 0) }}
{{ end }} {{ end }}
</nav> </nav>