render

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package render is the Githome web front's html/template engine. It parses the template set, exposes Page and Fragment with the htmx fragment contract, owns the asset manifest and the icon-backed FuncMap, and renders the error pages. It holds no domain logic and imports no domain package: it renders a view model handed to it. Its only non-stdlib imports are fe/assets (the icon registry and the built asset tree) and, from later milestones, the module-root markup renderer. See implementation/03 and the import boundary in implementation/01.

Index

Constants

View Source
const AssetURLPrefix = "/assets/"

AssetURLPrefix is the public path the hashed asset tree is served under. "assets" is a reserved top-level name (2005/02 section 2.3), so the static prefix wins over the dynamic "/{owner}" namespace by ServeMux specificity and no owner login can shadow it. The route builder and the mount both read this one constant so the served path and the generated URLs cannot drift.

Variables

This section is empty.

Functions

func IsFragment

func IsFragment(c *mizu.Ctx) bool

IsFragment reports whether to skip the layout, in the precedence htmx header, then an explicit ?_fragment=1. A request lacking both renders the full page, so every fragment endpoint also serves a sensible full page on direct navigation (the no-JS fallback). See implementation/03 section 3.

Types

type Set

type Set struct {
	// contains filtered or unexported fields
}

Set is the parsed template registry plus the asset manifest. One Set is built at boot and shared across requests. In the fedev build it re-parses the templates and re-reads the manifest per render so an edit shows on reload.

func New

func New(assetFS fs.FS, dev bool) (*Set, error)

New builds the Set. assetFS is the asset tree (assets.FS()); dev toggles the re-parse-per-request path. It returns an error rather than panicking so the caller decides how a malformed template at boot is surfaced; cmd/githome treats it as fatal.

func (*Set) AssetHandler

func (s *Set) AssetHandler() mizu.Handler

AssetHandler serves files from the asset tree under AssetURLPrefix. Hashed files are immutable, so the production build sends a far-future cache header; the dev build sends no-cache so an edit is always picked up. The handler never serves the manifest itself or escapes the asset root.

The body streams through http.ServeContent off the embedded file's io.ReadSeeker rather than copying the whole file into a per-request slice, so a large bundle is no longer fully buffered to be written. ServeContent also gives Range requests and the conditional-GET dance (If-None-Match → 304) for free; in production it carries a strong ETag derived from the content-hashed file name, so a revalidation that does slip past the immutable cache returns an empty 304 instead of the bytes.

func (*Set) Forbidden

func (s *Set) Forbidden(c *mizu.Ctx, chrome any) error

Forbidden renders the 403 page, used only where existence is already public so hiding the resource behind a 404 would be misleading (for example an action the signed-in viewer is not allowed to take on a repository they can see).

func (*Set) Fragment

func (s *Set) Fragment(c *mizu.Ctx, name string, vm any) error

Fragment renders one page's content template standalone (no layout) for an htmx swap. The same content template backs both Page and Fragment, so a fragment is never a second template.

func (*Set) MethodNotAllowed added in v0.1.3

func (s *Set) MethodNotAllowed(c *mizu.Ctx) error

MethodNotAllowed renders the 405 page. The mux computed the method mismatch and set the Allow header before this runs; the page replaces only the plain-text body, so the header contract (spec §7.4) stays intact. It renders with the fallback chrome because the route's middleware never ran.

func (*Set) NotFound

func (s *Set) NotFound(c *mizu.Ctx) error

NotFound renders the 404 page. Githome returns 404 for a missing resource and for a private one the viewer may not see, so the same page covers both and never reveals that a private resource exists. See implementation/06.

func (*Set) NotFoundWithChrome

func (s *Set) NotFoundWithChrome(c *mizu.Ctx, chrome any) error

NotFoundWithChrome is NotFound with the shell pre-filled, used once the view layer has built chrome for the request.

func (*Set) Page

func (s *Set) Page(c *mizu.Ctx, name string, vm any) error

Page renders a full page, or a fragment if the request is an htmx swap. name is the logical page name ("home/index"). It buffers before writing the status so a template error becomes a clean 500 rather than a half-written 200.

Every full page carries a strong ETag over the rendered bytes (spec 03 section 6: the page is rendered for one viewer and color mode, both of which land in the bytes, so the hash subsumes them) and Cache-Control: private, no-cache, the revalidate-every-time policy. A back-button or repeat visit whose If-None-Match still matches gets a 304 and ships no body. The render happens either way; what the ETag saves is the transfer, not the template.

func (*Set) RepoNotFound

func (s *Set) RepoNotFound(c *mizu.Ctx, chrome any) error

RepoNotFound is the 404 used for a repository that is missing or private to the viewer. It is a distinct entry point so the message can speak to repositories while staying identical for the missing and the forbidden case.

func (*Set) ServerError

func (s *Set) ServerError(c *mizu.Ctx, _ error) error

ServerError renders the 500 page. The underlying error is logged by the recover/middleware layer, not shown to the user. It returns nil because the response is fully written here; returning the original error would let an outer handler write a second time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL