content

package
v0.11.0 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package content is keryx's SSG-agnostic content source (spec 0033 §4). It reads the owning project's posts and their frontmatter so the studio can drive a post-first reel workflow — the picker, the posts-with-reels rail, and taxonomy filter/sort. keryx bakes in no Hugo assumptions: a content-layout config (`match` glob · `format` · field `map`, with optional `profile` presets) describes any generator — Hugo bundles, Jekyll `_posts`, Astro `src/content`, or a custom tree. The reel model is untouched; this only reads content (keryx already reads `reels/`), keeping the tool reusable per project.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.NewSentinel("keyrx.not_found", "post not found")

ErrNotFound is returned when no post matches a lookup (e.g. Article by bundle).

Functions

This section is empty.

Types

type Article

type Article struct {
	Post
	Body string `json:"body"` // the markdown after the frontmatter
	Dir  string `json:"dir"`  // the entry's directory — relative image srcs resolve here
}

Article is a post's markdown body alongside its normalised metadata, and the entry dir its relative asset paths (images) resolve against.

type Config

type Config struct {
	Profile string   `yaml:"profile" json:"profile" mapstructure:"profile"`
	Sources []Source `yaml:"sources" json:"sources" mapstructure:"sources"`
}

Config is the `content` block: optional profile preset + one or more sources.

type Post

type Post struct {
	Slug     string              `json:"slug"`
	Title    string              `json:"title"`
	Date     string              `json:"date"`
	Bundle   string              `json:"bundle"`  // the entry's dir — the reel link
	Section  string              `json:"section"` // the source name — a filter facet
	Draft    bool                `json:"draft"`
	Image    string              `json:"image"`
	Summary  string              `json:"summary"`
	Taxonomy map[string][]string `json:"taxonomy"` // every non-consumed frontmatter key
}

Post is a normalised content entry, generator-independent.

type Reader

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

Reader enumerates posts from an fs per a resolved config.

func New

func New(fs afero.Fs, cfg Config) (*Reader, error)

New resolves the config (applying any profile + field-map defaults) and returns a Reader. It errors on an unknown profile so a typo fails loudly, not silently empty.

func (*Reader) Article

func (r *Reader) Article(ctx context.Context, bundle string) (Article, error)

Article finds the post whose bundle matches and returns it with its markdown body. Bundle is the post entry's directory (the reel's link — see Post.Bundle). If several entries share a dir (e.g. a Jekyll `_posts` flat layout) the first match wins.

func (*Reader) Posts

func (r *Reader) Posts(ctx context.Context) ([]Post, error)

Posts scans every source and returns the normalised entries. Order follows the sources then the glob's sorted matches (stable for the UI).

type Source

type Source struct {
	Name   string            `yaml:"name" json:"name" mapstructure:"name"`
	Match  string            `yaml:"match" json:"match" mapstructure:"match"`    // glob (supports ** via doublestar)
	Format string            `yaml:"format" json:"format" mapstructure:"format"` // yaml|toml|json|auto
	Map    map[string]string `yaml:"map" json:"map" mapstructure:"map"`          // field → @dir|@file|<frontmatter-key>
}

Source describes where a set of entries live and how to read them. Tagged for yaml/json and mapstructure (the studio decodes it from the project config via viper).

Jump to

Keyboard shortcuts

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