Skip to content
internal/blog/listing
On this page

The home project's curated project listing: one authored document, rendered twice -- as the front page's project cards and as the generated projects page.

#internal/blog/listing

#internal/blog/listing

Package listing carries the home project's curated project listing: one declared source, two renderings.

The assembled site shows the projects it serves in two places -- the front page's cards and the generated /projects/ page -- and both read this one document, [SourceFile] in the home project. The listing is content, and content is the home project's territory, so it is authored there rather than in the assembly repository.

Curation means selection: a roster project the listing leaves out simply does not appear, which is legal and deliberate. The reverse is not: a listed slug with no manifest at assembly time is a hard error naming it, because the listing would otherwise print a card for a project the site cannot serve.

#SourceFile

Go go
const SourceFile = "docs/projects.toml"

SourceFile is the file, relative to the home project's root, that declares the listing.

#SidecarSuffix

Go go
const SidecarSuffix = "-listing.json"

SidecarSuffix is where the assembly keeps the copy the deploy grafted, as a manifest sidecar belonging to the home slug.

#FormatVersion

Go go
const FormatVersion = 1

FormatVersion is the sidecar format this package writes and reads.

#CategoryKeys

Go go
var CategoryKeys = []string{"name", "project"}

CategoryKeys is every key a [[category]] block may carry.

#ProjectKeys

Go go
var ProjectKeys = []string{"slug", "blurb", "url", "name", "repo"}

ProjectKeys is every key a [[category.project]] block may carry.

slug and blurb are required; url marks an entry the assembly does not serve (a project with no docs section), and name is required for exactly those -- an entry the assembly does serve takes its name from its manifest, so declaring one here would be a second source for the same fact. repo is the project's repository, rendered as a second link on the card beside the one the title carries.

#Error

Go go
type Error struct

Error is the failure every listing operation reports: an unparsable or invalid declaration, a sidecar in another format, and a listing that names a project the assembly cannot serve.

It is the Go counterpart of the RuntimeError the Python surface raised, and the one error type a caller needs to recognize with errors.As to render a listing refusal distinctly from an unexpected internal failure.

#Project

Go go
type Project struct

Project is one curated entry.

URL empty means the entry names a project the assembly serves: its display name and version come from its manifest and its address is its section on this site. URL set means an external project with no docs section here, which therefore carries its own Name. Repo is the project's repository, which a card links to beside its documentation.

#Category

Go go
type Category struct

Category is one named group of curated entries, in declared order.

#Listing

Go go
type Listing struct

Listing is the whole curated listing, in declared order.

#Entry

Go go
type Entry struct

Entry is one listed project together with the category that holds it -- the pair [Listing.Entries] walks.

#Parse

Go go
func Parse(text string, source string) (Listing, error)

Parse returns the [Listing] the document text declares, naming source in every diagnostic.

Validation is strict in every direction: an unknown top-level key, an unknown key on any block, a missing or empty required key, a category with no entries, a duplicate category name and a duplicate slug are each a hard error naming the offending declaration.

#CheckAgainst

Go go
func CheckAgainst(listing Listing, manifests []map[string]any, homeSlug string, source string) error

CheckAgainst returns an error unless every listed slug can actually be rendered, naming source in the diagnostic.

Two failures, both naming the slug: an entry the assembly is supposed to serve but has no manifest for, and the home project listing itself -- the front page is not one of the projects the front page lists.

#RenderHTML

Go go
func RenderHTML(listing Listing, manifests []map[string]any, siteHop string, homeSlug string, heading string) (string, error)

RenderHTML returns the curated listing as one HTML fragment.

This is the single renderer behind both surfaces: the generated /projects/ page passes a heading, the front page's cards directive does not. Version badges come from the manifests, so a card is as current as the last deploy of the project it names.

siteHop is the hop from the page holding the fragment back to the site root, and every card for a project the site serves is addressed through it. A card for an external project keeps the absolute URL the listing declares: that one really does name somebody else's server.

The cards are stated in the framework's own card vocabulary -- .card-grid for the responsive grid, .card for the box, .card-title-row/.card-title for the head, .card-badges and .badge for the version chip -- with .project-* hooks riding alongside for the rules only a project card needs. A private class surface no theme knew about is what made these render as full-width unstyled boxes.

#Load

Go go
func Load(path string) (Listing, error)

Load returns the listing declared in the TOML document at path.

#RenderSidecar

Go go
func RenderSidecar(listing Listing, slug string) string

RenderSidecar returns the JSON the assembly keeps beside the manifests.

The document is written in declaration order rather than sorted, and every character outside printable ASCII is escaped, so the bytes are the ones Python's json.dumps(document, indent=2) produced.

#ParseSidecar

Go go
func ParseSidecar(text string, source string) (Listing, error)

ParseSidecar returns the listing a sidecar document holds.

The sidecar is written by the deploy, never by hand, so the only thing checked here is that it is the format this build understands -- a wrong or absent format_version is a hard error, never a guess.

#LoadSidecar

Go go
func LoadSidecar(path string) (Listing, error)

LoadSidecar returns the listing the sidecar document at path holds.

#Error.Error

Go go
func (e *Error) Error() string { return e.Message }

Error returns the diagnostic.

#Project.External

Go go
func (p Project) External() bool { return p.URL != "" }

External reports whether the entry names a project this site does not serve.

#Listing.Slugs

Go go
func (l Listing) Slugs() []string

Slugs is every listed slug, in declared order.

#Listing.Entries

Go go
func (l Listing) Entries() []Entry

Entries walks every listed project in declared order, each paired with its category.

Search