From c5895e15ca8fc09e80a1c71944438bb5a40381b9 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 10 Sep 2026 13:43:05 +1000 Subject: [PATCH] media/loader: article slug from folder; _index.md loads as article; _ dirs ignored; slugs lowercased --- app/src/content.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/src/content.go b/app/src/content.go index def0ca8..df2d860 100644 --- a/app/src/content.go +++ b/app/src/content.go @@ -186,17 +186,20 @@ func (c *Content) loadFilesUnder(dir string, out *[]*Article) error { } for _, e := range entries { name := e.Name() - if strings.HasPrefix(name, "_") { - continue - } if e.IsDir() { - // recurse one level (article folder) — skip hidden - c.loadFilesUnder(path.Join(dir, name), out) + // recurse one level (article folder) — skip hidden/_ folders (e.g. _attachments) + if !strings.HasPrefix(name, "_") { + c.loadFilesUnder(path.Join(dir, name), out) + } continue } if !strings.HasSuffix(name, ".md") { continue } + // skip _ files (config, templates) BUT _index.md is the real article in a folder + if strings.HasPrefix(name, "_") && name != "_index.md" { + continue + } if a, err := c.loadFile(path.Join(dir, name)); err == nil { // unpublished articles are drafts — load, then hide from all listings *out = append(*out, a) @@ -338,7 +341,13 @@ func parseFrontMatter(text string) (FrontMatter, string, bool) { func slugOf(full string) string { base := path.Base(full) base = strings.TrimSuffix(base, ".md") - return base + // article files are now /_index.md — the slug is the folder name. + if base == "_index" { + dir := path.Dir(full) + base = path.Base(dir) + } + // lowercase for URL-friendly slugs + return strings.ToLower(base) } // resolveShortcodes replaces {{media:name}} with base/name and