Documentation
¶
Overview ¶
Package fragmentsgo is a framework-agnostic Markdown content engine for Go, modeled on fragments4k: it turns a directory of Markdown files with YAML front matter into blog posts, static pages, and searchable content — with reading time, author profiles, lifecycle statuses, and SEO metadata.
The core type is Fragment; content lives behind a Repository (see NewFileSystemRepository); the blog, static, search, seo, rss, sitemap, and httpadapter subpackages build higher-level engines on top.
Index ¶
- Variables
- func FirstParagraph(body string) string
- func PlainText(html string) string
- func ReadingTimeOf(text string) int
- func Slugify(value string) string
- func SortDated(fragments []*Fragment)
- func SortOrdered(fragments []*Fragment)
- type Author
- type AuthorLink
- type AuthorRepository
- type Fragment
- func (f *Fragment) DateValue() *time.Time
- func (f *Fragment) GetBool(key string) bool
- func (f *Fragment) GetInt(key string) int
- func (f *Fragment) GetString(key string) string
- func (f *Fragment) GetStringList(key string) []string
- func (f *Fragment) HasTag(tag string) bool
- func (f *Fragment) Visible() bool
- type MarkdownParser
- type Repository
- type RepositoryOptions
- type SanitizerProfile
- type Status
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("fragmentsgo: fragment not found")
ErrNotFound is returned when no fragment matches a lookup.
Functions ¶
func FirstParagraph ¶
FirstParagraph extracts the first prose paragraph of a Markdown body as preview text: headings, lists, code fences, tables, and quotes are skipped.
func ReadingTimeOf ¶
ReadingTimeOf estimates reading minutes for a plain-text body at 200 words per minute, minimum one for non-empty text.
func SortDated ¶
func SortDated(fragments []*Fragment)
SortDated orders dated fragments newest-first, title as tiebreaker.
func SortOrdered ¶
func SortOrdered(fragments []*Fragment)
SortOrdered orders fragments by Order, then Title (pages, projects).
Types ¶
type Author ¶
type Author struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Slug string `yaml:"slug"`
Bio string `yaml:"bio"`
GitHub string `yaml:"github"`
Twitter string `yaml:"twitter"`
SocialLinks map[string]string `yaml:"socialLinks"`
}
Author is a content author profile loaded from a .author.yml file.
func (*Author) SocialEntries ¶
func (a *Author) SocialEntries() []AuthorLink
SocialEntries returns the author's social links with GitHub/Twitter expanded to full URLs, in a stable order.
type AuthorLink ¶
AuthorLink is one outbound social profile link.
type AuthorRepository ¶
type AuthorRepository struct {
// contains filtered or unexported fields
}
AuthorRepository loads author profiles from a directory of .author.yml files and resolves them by id, slug, or display name.
func NewAuthorRepository ¶
func NewAuthorRepository(root string) (*AuthorRepository, error)
NewAuthorRepository loads every *.author.yml file under root. A missing directory yields an empty repository.
func (*AuthorRepository) All ¶
func (r *AuthorRepository) All() []*Author
All returns every author profile ordered by name.
func (*AuthorRepository) Resolve ¶
func (r *AuthorRepository) Resolve(name string) *Author
Resolve finds an author by id, slug, or display name; nil when the name is empty or unknown.
type Fragment ¶
type Fragment struct {
// Slug is the URL identifier, from front matter or derived from Title.
Slug string
// Title is the document heading.
Title string
// Date is the publication date from front matter (zero when absent).
Date time.Time
// Updated is the optional last-modified date from the "updated"
// front-matter key (zero when absent); it never affects visibility
// or ordering, only feeds/sitemap metadata.
Updated time.Time
// Tags and Categories come from front matter.
Tags []string
Categories []string
// Author names an author profile (see AuthorRepository).
Author string
// Image is a front-matter hero/cover image path.
Image string
// Preview is the summary text: the front-matter preview when present,
// otherwise the first paragraph of the body.
Preview string
// Template names an alternate rendering template.
Template string
// Order positions fragments in ordered listings (projects, pages).
Order int
// Status is the effective lifecycle status after resolution.
Status Status
// URL is the computed public URL (see RepositoryOptions.URLBuilder).
URL string
// HTML is the sanitized rendered Markdown.
HTML template.HTML
// BodyText is the tag-stripped plain text of the body (search input).
BodyText string
// ReadingTime is the estimated reading time in minutes (200 wpm).
ReadingTime int
// Fields holds the raw front matter for typed access to custom keys.
Fields map[string]any
// SourcePath is the file the fragment was loaded from.
SourcePath string
}
Fragment is one parsed Markdown document.
func (*Fragment) DateValue ¶
DateValue returns the date as a pointer, nil when unset — convenient for templates that format optional dates.
func (*Fragment) GetStringList ¶
GetStringList reads a custom front-matter field as a string slice.
type MarkdownParser ¶
type MarkdownParser struct {
// contains filtered or unexported fields
}
MarkdownParser converts Markdown bodies into sanitized HTML.
func NewMarkdownParser ¶
func NewMarkdownParser(profile SanitizerProfile) *MarkdownParser
NewMarkdownParser builds a parser with the given sanitizer profile.
type Repository ¶
type Repository interface {
// Load (re)reads every fragment from disk.
Load() error
// All returns fragments in listing order (newest first for dated
// content; Order then Title for undated content), visible ones only
// unless IncludeInvisible was set.
All() []*Fragment
// Everything returns every fragment — including drafts, scheduled,
// and other invisible states — in the same listing order. It is the
// administrative lifecycle view; public listings should use All.
Everything() []*Fragment
// BySlug finds a fragment by slug.
BySlug(slug string) (*Fragment, error)
// ByURL finds a fragment by its public URL.
ByURL(url string) (*Fragment, error)
// UpdateStatus rewrites a fragment's status front matter and reloads it.
UpdateStatus(slug string, status Status) error
// Schedule sets a future publish date and reloads the fragment.
Schedule(slug string, at time.Time) error
// Archive marks a fragment archived and reloads it.
Archive(slug string) error
}
Repository provides access to a set of fragments.
func NewFileSystemRepository ¶
func NewFileSystemRepository(options RepositoryOptions) Repository
NewFileSystemRepository creates a repository over a directory of Markdown files. Call Load before first use.
type RepositoryOptions ¶
type RepositoryOptions struct {
// Path is the content directory holding .md files.
Path string
// BaseURL prefixes generated URLs (e.g. "/projects"). Mutually
// exclusive with URLBuilder.
BaseURL string
// URLBuilder computes a fragment's public URL; when nil the URL is
// BaseURL + "/" + slug (or "/"+slug without a base).
URLBuilder func(f *Fragment) string
// Parser renders Markdown; nil selects the relaxed trusted-author
// profile.
Parser *MarkdownParser
// Now overrides time for status resolution (tests).
Now func() time.Time
// IncludeInvisible keeps drafts and scheduled fragments in listings so
// preview surfaces can show them; they are excluded by default.
IncludeInvisible bool
// Ordered selects listing order: true sorts by Order then Title
// (pages, projects); false (default) sorts dated content newest first.
Ordered bool
// Exclude drops files whose base name matches (checked case-blind
// against the full path), e.g. to keep self-referential entries out.
Exclude func(path string) bool
}
RepositoryOptions configures a [FileSystemRepository].
type SanitizerProfile ¶
type SanitizerProfile int
SanitizerProfile selects the HTML policy applied to rendered Markdown.
const ( // SanitizerRelaxedTrustedAuthor allows standard rich content (images, // links, headings, code, tables) — the default, matching fragments4k's // RELAXED_TRUSTED_AUTHOR profile for content you author yourself. SanitizerRelaxedTrustedAuthor SanitizerProfile = iota // SanitizerStrict strips everything down to basic formatting — for // content contributed by untrusted parties. SanitizerStrict )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package blog implements the blog engine over a dated fragment repository: paginated overviews, tag listings, archives, and previous/next navigation.
|
Package blog implements the blog engine over a dated fragment repository: paginated overviews, tag listings, archives, and previous/next navigation. |
|
cmd
|
|
|
example
command
Command example is a minimal fragmentsgo site: a blog, an about page, search, RSS, and a sitemap rendered through html/template.
|
Command example is a minimal fragmentsgo site: a blog, an about page, search, RSS, and a sitemap rendered through html/template. |
|
fragmentsgo
command
Command fragmentsgo scaffolds and validates content directories for fragmentsgo-based sites.
|
Command fragmentsgo scaffolds and validates content directories for fragmentsgo-based sites. |
|
Package httpadapter mounts a fragmentsgo content site on any net/http mux: blog routes (paged listing, tags, dated posts, archive), search, static pages, and the rss.xml and sitemap.xml endpoints.
|
Package httpadapter mounts a fragmentsgo content site on any net/http mux: blog routes (paged listing, tags, dated posts, archive), search, static pages, and the rss.xml and sitemap.xml endpoints. |
|
Package imageopt re-encodes content images to web-friendly sizes: JPEGs are downscaled and re-compressed, PNGs are downscaled losslessly, and anything else passes through untouched.
|
Package imageopt re-encodes content images to web-friendly sizes: JPEGs are downscaled and re-compressed, PNGs are downscaled losslessly, and anything else passes through untouched. |
|
Package reload provides a dependency-free content watcher for development servers: it polls the watched directories and invokes a callback once changes settle.
|
Package reload provides a dependency-free content watcher for development servers: it polls the watched directories and invokes a callback once changes settle. |
|
Package rss builds RSS 2.0 feeds from fragments.
|
Package rss builds RSS 2.0 feeds from fragments. |
|
Package search provides an in-memory scored search engine over fragment repositories — the pragmatic Go stand-in for fragments4k's Lucene engine.
|
Package search provides an in-memory scored search engine over fragment repositories — the pragmatic Go stand-in for fragments4k's Lucene engine. |
|
Package seo builds per-page SEO metadata: Open Graph and Twitter tags, canonical URLs, robots directives, and JSON-LD structured data — the Go counterpart of fragments4k's fragments-seo module.
|
Package seo builds per-page SEO metadata: Open Graph and Twitter tags, canonical URLs, robots directives, and JSON-LD structured data — the Go counterpart of fragments4k's fragments-seo module. |
|
Package sitemap builds sitemap.xml documents from page URLs.
|
Package sitemap builds sitemap.xml documents from page URLs. |
|
Package static implements the engine for undated, ordered content: standalone pages and custom sections like projects or articles.
|
Package static implements the engine for undated, ordered content: standalone pages and custom sections like projects or articles. |