FileTree
filetree fence draws an annotated directory structure — aligned comment column, per-entry icons, collapsible directories, a draggable split.A file tree is a filetree fence whose body is the listing itself: indentation
is depth, a trailing / marks a directory, and everything after # is a
comment. Use it to explain the part of a directory structure that concerns the
reader, one annotation at a time. When the reader has to copy the listing
verbatim, use an ordinary code block.
Shortest form
content/
- _index.md
- docs/
- blog/
- hugo.yml
- go.mod
Bullets (-, *, +) may be omitted; the result is the same. An entry with
children is a directory. Without children, a trailing / tells the theme it is
one.
Adding comments
Everything after the first whitespace-preceded # on a line is a comment,
rendered as an aligned right-hand column. Comments are plain text, so Markdown
inside them shows literally; for a literal hash write \#.
content/every page, both languages in one directory
- docs/the documentation tree you are reading
- blog/release notes and articles
- assets/scss/the site's own SCSS, overriding theme variables
- layouts/site-level template overrides, the fewer the better
- static/images/images that need no build-time processing
- hugo.ymlsite configuration: languages, menus, params.ui
Where the comment column starts is computed at build time from the widest row,
so every # begins at the same column whether or not the source lines up. The
comment column takes at most the right half of the panel and at least three
tenths. The dashed rule between them is a splitter you can drag, or focus with
Tab and move with the arrow keys (Home / End go
to the extremes).
Overlong names and comments are truncated with an ellipsis inside their own
column, and hovering shows the full text through title. The splitter is the
file tree’s only JavaScript, and only a tree with comments loads it.
truncation in both columns
runbooks/
- a-deliberately-long-runbook-filename-for-a-failover-drill.mdan equally overlong comment, kept on one line so it has to be clipped inside the comment column
- restart.mdshort
Title bars
The fence attribute {title="…"} renders a title bar above the tree; without it
there is none.
the oink.pgsty.com repository root
- content/pages
- assets/resources that take part in the build
- data/data for the home page, landings and downloads
- layouts/template overrides
- static/files copied verbatim
- tests/Playwright and node --test
- hugo.yml
- go.modthe theme, imported as a Hugo Module
- Makefilemake d / make b / make c
Indentation and depth
Depth comes from indentation. Two spaces, four spaces, or tabs (counted as four
columns) all work and need not be consistent within one tree, as long as every
level you return to has been opened before. Output from the tree command can
be pasted whole, root line and summary line included — the summary is dropped.
content/docs
about
- _index.md
- features.md
components
- filetree.md
image
- index.md
- _index.md
Returning to an indentation level that was never opened warns and skips that line; the message carries the line number inside the fence, and strict publishing rejects it.
Folding and explicit types
A directory with children is open by default; {open=false} starts it closed.
Directories render as native <details>, so they are keyboard-operable without
JavaScript. open is valid on directories only. An entry with no children whose
name does not end in / is treated as a file; {type=dir} overrides that, and
{type=file} the other way.
the content directory
content/
docs/the documentation tree
components/22 component pages
- callout.md
- filetree.md
- image/page bundle: body + images
customize/site-level configuration
- config.md
blog/
- release.md
Icons and tones
Icons are inferred from the name: directories get a folder icon that follows the
open state; files are matched first by full filename (LICENSE, Makefile,
go.mod, package.json, .gitignore …), then by extension (md yml toml json sh py go js sql css png svg pdf zip …), and otherwise get a generic file icon.
{icon=…} overrides it and takes exactly one Font Awesome class pair.
{tone=…} colours the icon, using the same vocabulary as
badges: neutral info success warning
danger.
deployment layout: permissions and what matters
/etc/pigsty/0755 root:root · configuration root
- pigsty.yml0644 root:root · cluster inventory
ca/0700 root:root · self-signed CA, never commit
- ca.key0600 root:root
/var/lib/pgsql/18/data/0700 postgres:postgres · data directory
- postgresql.conf0600 postgres:postgres
- /usr/bin/pig0755 root:root · command-line tool
tone colours the icon only, never the text. Colour is a supplement; the
meaning belongs in the name or the comment.
Linked entries
Write an entry name as [name](link) to make it a link. Site paths, relative
paths and http(s): all work, under the same URL validation as every other
component.
this site's component pages
content/docs/
- callout.mdcallouts
- filetree.mdthis page
- gallery.mdgalleries
image/page bundle
- index.mdimages
- hugo.ymlfixture configuration on GitHub
One tree per platform
A fence carrying tab= (and group= / value=) becomes one panel of a
tab set and can sit alongside code fences.
- /etc/pigsty/configuration
- /var/lib/pgsql/data
- /usr/bin/pigexecutable
- ~/Library/Application Support/pigsty/configuration
- /opt/homebrew/bin/pigexecutable
Output
| Output | Shape |
|---|---|
| HTML | <div class="td-filetree">, an optional title bar, directories as native <details>; a tree with comments also gets the draggable splitter, its only runtime |
| The same tree, fully expanded, no splitter, comments wrapped instead of truncated | |
| Markdown | The filetree fence, emitted as written |
| RSS | The fence source inside a <pre> |
Below the sm breakpoint the layout collapses to a single column: comments move
under the name, stop being truncated, and the splitter is hidden. A tree without
comments is single-column and loads no script at all.
Parameter reference
Fence attributes, after ```filetree:
Entry attributes, in the {…} at the end of a line:
The line syntax itself:
Unknown attributes and values, open on a file, malformed {…}, and a dedent
to an unopened level all warn and take a safe fallback or skip the bad line.
The message names the line; strict publishing rejects the warning.
Limits
- The
filetreefence is the only form: there is no{.filetree}list marker and no shortcode. - Names and comments are plain text:
**bold**shows literally, so the fence source reads correctly anywhere. - Nothing is read from disk: the tree is static content you write or paste, and it does not follow the repository.
- No search, no multi-select, no copy-the-whole-tree: when the reader has to copy it verbatim, use a code block.
- The split position is not persisted: after a reload it returns to the width computed at build time.
Related
- Code blocks — listings meant to be copied verbatim
- Tabs — one tree per platform, side by side
- Badges —
toneuses the same vocabulary - Organizing content — how a real content directory is laid out