diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 88 |
1 files changed, 78 insertions, 10 deletions
@@ -6,7 +6,7 @@ outputs in place. ```sh go build -o weft . -./weft ../tjp.lol +./weft -gitignore ../tjp.lol https://tjp.lol ``` Markdown uses CommonMark with GFM tables, strikethrough, task lists, and @@ -26,15 +26,83 @@ walking toward the site root before using the fallback. For example, `notes/recipes`, `notes`, then `page`. Set a different fallback with `-fallback template`; it defaults to `page`. -Template data exposes the current page fields (`.Title`, `.Meta`, `.Sections`, -`.OutputPath`, and so on) plus `.Pages`, a map containing each Markdown page at -every ancestor directory. Helpers are `rel from target`, `sortPages pages key`, -`filterPages pages key value`, `slicePages pages start end`, `joinSections`, -`date value layout`, `rfc3339 value`, and `xml value`. Use `xml` around joined -HTML when embedding it as escaped Atom `type="html"` content. +## Template data -Go templates' built-in `slice` can select rendered sections, for example -`joinSections (slice .Sections 1)` after rendering a weblog lede separately. +Every template receives this root value: + +```go +struct { + *Page + Pages map[string][]*Page +} +``` + +The current `Page` is embedded, so its fields can be accessed as either +`.Title` or `.Page.Title`: + +| Field | Meaning | +| --- | --- | +| `.SourcePath` | Slash-separated source path relative to the site root. | +| `.OutputPath` | Slash-separated generated path relative to the site root. | +| `.URL` | Root-relative URL. Markdown `index.html` outputs use their directory URL. | +| `.CanonicalURL` | `.URL` beneath `canonical-root` | +| `.Title` | First H1, then frontmatter `title`, then a filename-derived fallback. The extracted H1 is removed from the body. | +| `.Meta` | `map[string]any` containing optional YAML frontmatter. | +| `.ModTime` | Source-file modification time as `time.Time`. | +| `.Sections` | `[]template.HTML` containing one rendered fragment per top-level Markdown node. Raw Markdown HTML is disabled before these trusted fragments are created. | +| `.Pages` | All discovered Markdown pages grouped by ancestor directory. This field belongs to the root template value, not `Page`. | + +`.Pages` uses slash-separated directory keys. The root key is `""`. A page at +`notes/recipes/cocktails/old_fashioned.md` appears under `""`, `"notes"`, +`"notes/recipes"`, and `"notes/recipes/cocktails"`; every collection points to +the same `Page`. Underscore-excluded sources and explicit output templates do +not enter the inventory. + +Explicit `*.html.tmpl` and `*.xml.tmpl` outputs receive their source and output +paths, URL fields, an empty `.Meta`, and the complete `.Pages` inventory. They +have no Markdown title, modification time, or sections. + +## Template functions + +| Function | Result | +| --- | --- | +| `rel from target` | Makes a root-relative site target relative to the directory containing `from`. HTTP(S), `mailto:`, and fragment targets pass through. A trailing `/` is preserved, so `rel "about/index.html" "/"` returns `../`. | +| `sortPages pages key` | Returns a copy. `"title"` sorts ascending case-insensitively; `"mod_time"` sorts newest first; every other key sorts newest first using that frontmatter value as a date. | +| `filterPages pages key value` | Keeps pages whose value stringifies equally. `"title"` and `"output"` select `.Title` and `.OutputPath`; other keys select `.Meta[key]`. | +| `slicePages pages start end` | Returns the half-open range `[start:end]`, clamping both bounds instead of failing. | +| `joinSections sections` | Concatenates rendered Markdown sections and returns trusted `template.HTML`. | +| `date value layout` | Parses a `time.Time`, RFC 3339 string, or `YYYY-MM-DD` string and formats it with a Go time layout. An invalid value formats as the zero time. | +| `rfc3339 value` | Parses the same date values and formats them as RFC 3339. An invalid value formats as the zero time. | +| `xml value` | Converts a trusted value back to a plain string so `html/template` escapes it in XML text. Use this around `joinSections` for escaped Atom `content type="html"`. | + +Examples: + +```gotemplate +<a href="{{rel .OutputPath "/notes/"}}">notes</a> +{{range sortPages (index .Pages "weblog") "post_date"}}{{.Title}}{{end}} +{{with index .Sections 0}}{{.}}{{end}} +{{joinSections (slice .Sections 1)}} +<content type="html">{{xml (joinSections .Sections)}}</content> +``` + +All standard `html/template` actions and functions remain available, including +`and`, `or`, `not`, `call`, `html`, `index`, `slice`, `js`, `len`, `print`, +`printf`, `println`, `urlquery`, `eq`, `ne`, `lt`, `le`, `gt`, and `ge`. +`html/template` applies contextual escaping to template output. + +## Git ignore management + +`-gitignore` atomically replaces a marked block in the site-root `.gitignore` +with exact, root-anchored paths for the current generated outputs. Content +outside the block is preserved, and stale output entries are removed. Without +the flag, Weft does not touch `.gitignore`. + +```gitignore +# BEGIN weft generated outputs +/feed.xml +/index.html +# END weft generated outputs +``` Weft validates generated internal links and XML before changing the site. It tracks ownership in `.weft-generated.json`, refuses to replace untracked files, @@ -45,5 +113,5 @@ For cron, schedule the build after Syncthing's settling window and use the host's lock and logging tools, for example: ```cron -17 * * * * sleep 60 && flock -n /run/lock/weft.lock /usr/local/bin/weft /srv/tjp.lol >>/var/log/weft.log 2>&1 || logger -t weft 'build failed or lock unavailable' +17 * * * * sleep 60 && flock -n /run/lock/weft.lock /usr/local/bin/weft -gitignore /srv/tjp.lol https://tjp.lol >>/var/log/weft.log 2>&1 || logger -t weft 'build failed or lock unavailable' ``` |
