Documentation
¶
Overview ¶
Package pubengine is a blog publishing engine built with Go, Echo, and templ. It provides blog CRUD, admin dashboard, analytics, RSS, and sitemap out of the box.
Users provide their own templ templates via the ViewFuncs struct, and pubengine handles all the handler logic, middleware, and database operations.
Index ¶
- Variables
- func BlogPostingJsonLD(post BlogPost, cfg SiteConfig) string
- func BuildURL(base string, pathSegments ...string) string
- func CsrfToken(c echo.Context) string
- func EnvOr(key, fallback string) string
- func FilterEmpty(vals []string) []string
- func IsAdmin(c echo.Context) bool
- func JoinTags(tags []string) string
- func MustEnv(key string) string
- func ParseTags(tagString string) []string
- func PathEscape(s string) string
- func PostPath(slug string) string
- func QueryEscape(s string) string
- func Render(c echo.Context, cmp templ.Component) error
- func RenderStatus(c echo.Context, code int, cmp templ.Component) error
- func Slugify(s string) string
- func ValidateSlug(slug string) string
- func WebsiteJsonLD(cfg SiteConfig) string
- type App
- type BlogPost
- type Image
- type LoginLimiter
- type Option
- type PageMeta
- type Pagination
- type PostCache
- func (c *PostCache) GetPost(slug string) (BlogPost, error)
- func (c *PostCache) GetPostContext(ctx context.Context, slug string) (BlogPost, error)
- func (c *PostCache) Invalidate()
- func (c *PostCache) ListPageContext(ctx context.Context, tag string, offset, limit int) ([]BlogPost, bool, error)
- func (c *PostCache) ListPosts(tag string) ([]BlogPost, error)
- func (c *PostCache) ListPostsContext(ctx context.Context, tag string) ([]BlogPost, error)
- func (c *PostCache) ListTags() ([]string, error)
- func (c *PostCache) ListTagsContext(ctx context.Context) ([]string, error)
- func (c *PostCache) RelatedContext(ctx context.Context, p BlogPost, limit int) ([]BlogPost, error)
- type SiteConfig
- type Store
- func (s *Store) Close() error
- func (s *Store) DeleteImage(filename string) error
- func (s *Store) DeleteImageContext(ctx context.Context, filename string) error
- func (s *Store) DeletePost(slug string) error
- func (s *Store) DeletePostContext(ctx context.Context, slug string) error
- func (s *Store) GetPost(slug string) (BlogPost, error)
- func (s *Store) GetPostAny(slug string) (BlogPost, error)
- func (s *Store) GetPostAnyContext(ctx context.Context, slug string) (BlogPost, error)
- func (s *Store) GetPostContext(ctx context.Context, slug string) (BlogPost, error)
- func (s *Store) ListAdminPageContext(ctx context.Context, offset, limit int) ([]BlogPost, bool, error)
- func (s *Store) ListAllPosts() ([]BlogPost, error)
- func (s *Store) ListAllPostsContext(ctx context.Context) ([]BlogPost, error)
- func (s *Store) ListImages() ([]Image, error)
- func (s *Store) ListImagesContext(ctx context.Context) ([]Image, error)
- func (s *Store) ListImagesPageContext(ctx context.Context, offset, limit int) ([]Image, bool, error)
- func (s *Store) ListPosts(tag string) ([]BlogPost, error)
- func (s *Store) ListPostsContext(ctx context.Context, tag string) ([]BlogPost, error)
- func (s *Store) ListSummariesContext(ctx context.Context) ([]BlogPost, error)
- func (s *Store) ListTags() ([]string, error)
- func (s *Store) ListTagsContext(ctx context.Context) ([]string, error)
- func (s *Store) ResolvePostRedirect(slug string) (string, error)
- func (s *Store) ResolvePostRedirectContext(ctx context.Context, slug string) (string, error)
- func (s *Store) SaveImage(img Image) error
- func (s *Store) SaveImageContext(ctx context.Context, img Image) error
- func (s *Store) SavePost(p BlogPost) error
- func (s *Store) SavePostContext(ctx context.Context, p BlogPost) error
- type ViewFuncs
Constants ¶
This section is empty.
Variables ¶
var EmbeddedAssets embed.FS
EmbeddedAssets contains static assets shipped with the framework: talkdom.js, analytics.js, dashboard.min.js
var ErrInvalidImage = errors.New("invalid image")
ErrInvalidImage identifies malformed or unsupported input, rather than storage errors.
var ErrNotFound = sql.ErrNoRows
var ErrPostConflict = errors.New("post changed or slug is already in use; reload before saving")
ErrPostConflict means a slug is taken or the editor's revision is stale.
Functions ¶
func BlogPostingJsonLD ¶
func BlogPostingJsonLD(post BlogPost, cfg SiteConfig) string
BlogPostingJsonLD returns a JSON-LD string for a BlogPosting schema.
func EnvOr ¶
EnvOr returns the value of the environment variable key, or fallback if empty. This is a convenience function for use in scaffolded main.go files.
func FilterEmpty ¶
FilterEmpty removes empty/whitespace-only strings from a slice.
func MustEnv ¶
MustEnv returns the value of the environment variable key, or fatally exits if empty.
func PathEscape ¶
PathEscape escapes a string for use in a URL path.
func QueryEscape ¶ added in v0.4.0
QueryEscape escapes a value for a URL query parameter.
func ValidateSlug ¶
ValidateSlug checks that a slug is non-empty, not reserved, and within length limits. Returns an error message string, or "" if valid.
func WebsiteJsonLD ¶
func WebsiteJsonLD(cfg SiteConfig) string
WebsiteJsonLD returns a JSON-LD string for a WebSite schema using SiteConfig.
Types ¶
type App ¶
type App struct {
Config SiteConfig
Echo *echo.Echo
Store *Store
Cache *PostCache
Views ViewFuncs
// contains filtered or unexported fields
}
App is the central pubengine application. It wires together the store, cache, handlers, middleware, and user-provided templates.
func New ¶
func New(cfg SiteConfig, views ViewFuncs, opts ...Option) *App
New creates a new pubengine App with the given configuration and view functions.
type BlogPost ¶
type BlogPost struct {
Title string
Date string
Tags []string
Summary string
Link string
Slug string
Content string
Published bool
OriginalSlug string // Identity loaded for an edit; empty for new posts.
Revision int64 // Optimistic concurrency token; zero for new posts.
Error string // Editor validation message; not persisted.
}
BlogPost is the core content type stored in SQLite and rendered by templates.
func FilterRelatedPosts ¶
FilterRelatedPosts finds posts that share at least one tag with current.
type Image ¶
type Image struct {
Filename string // e.g. "my-photo.jpg"
OriginalName string
Width int
Height int
Size int // bytes
UploadedAt string // RFC3339
}
Image represents an uploaded image stored in the uploads directory.
type LoginLimiter ¶
type LoginLimiter struct {
// contains filtered or unexported fields
}
LoginLimiter rate-limits login attempts per IP address.
func NewLoginLimiter ¶
func NewLoginLimiter(max int, window time.Duration) *LoginLimiter
NewLoginLimiter creates a LoginLimiter that allows max attempts per window.
func (*LoginLimiter) Allow ¶
func (l *LoginLimiter) Allow(ip string) bool
Allow atomically checks and records an attempt, including successful logins.
func (*LoginLimiter) Check ¶
func (l *LoginLimiter) Check(ip string) bool
Check returns true if the IP has not exceeded the rate limit. This is informational only. Use Allow for atomic admission.
func (*LoginLimiter) Close ¶ added in v0.4.0
func (l *LoginLimiter) Close()
Close stops the cleanup worker and waits for it to exit. It is safe to repeat.
func (*LoginLimiter) Record ¶
func (l *LoginLimiter) Record(ip string)
Record registers a failed login attempt for the given IP.
type Option ¶
type Option func(*App)
Option configures additional App behavior.
func WithCustomRoutes ¶
WithCustomRoutes registers additional routes on the Echo instance. The callback receives the Echo instance before the server starts.
func WithIPExtractor ¶ added in v0.4.0
func WithIPExtractor(extractor echo.IPExtractor) Option
WithIPExtractor configures which proxies may supply a client's IP address. Use echo.ExtractIPDirect() when the app is reachable without a trusted proxy.
func WithStaticDir ¶
WithStaticDir sets the directory for user-owned static assets (default "public").
type PageMeta ¶
type PageMeta struct {
Title string
Description string
URL string // canonical + og:url
OGType string // "website" or "article"
}
PageMeta carries per-page OpenGraph and SEO metadata into the <head> template.
type Pagination ¶ added in v0.4.0
type Pagination struct{ Previous, Next string }
func PaginationFromContext ¶ added in v0.4.0
func PaginationFromContext(ctx context.Context) Pagination
type PostCache ¶
type PostCache struct {
// contains filtered or unexported fields
}
PostCache stores summaries and a bounded set of article bodies.
func (*PostCache) GetPostContext ¶ added in v0.4.0
func (*PostCache) Invalidate ¶
func (c *PostCache) Invalidate()
func (*PostCache) ListPageContext ¶ added in v0.4.0
func (c *PostCache) ListPageContext(ctx context.Context, tag string, offset, limit int) ([]BlogPost, bool, error)
ListPageContext returns summaries and whether another page exists; zero limit means all.
func (*PostCache) ListPosts ¶
ListPosts preserves the full-content API. Prefer ListPageContext for lists.
func (*PostCache) ListPostsContext ¶ added in v0.4.0
func (*PostCache) ListTagsContext ¶ added in v0.4.0
type SiteConfig ¶
type SiteConfig struct {
Name string // Site name (default "Blog")
URL string // Canonical URL (default "http://localhost:3000")
Description string // Site description for RSS and meta tags
Author string // Author name for JSON-LD
Addr string // Listen address (default ":3000")
DatabasePath string // SQLite path (default "data/blog.db")
AnalyticsEnabled bool // Enable analytics (default false; scaffold sets true)
AnalyticsDatabasePath string // Analytics SQLite path (default "data/analytics.db")
AdminPassword string // Required: admin login password
SessionSecret string // Required: cookie signing key, at least 32 bytes
CookieSecure bool // Set true for HTTPS
GoogleClientID string // Google OAuth client ID (optional)
GoogleClientSecret string // Google OAuth client secret (optional)
GoogleAdminEmail string // Allowed Google email for admin login (optional)
ReadHeaderTimeout time.Duration // Default 5 seconds
ReadTimeout time.Duration // Default 30 seconds
WriteTimeout time.Duration // Default 30 seconds
IdleTimeout time.Duration // Default 60 seconds
ShutdownTimeout time.Duration // Default 10 seconds
MaxConcurrentUploads int // Default 2; bounds upload parsing and decoding.
PageSize int // Zero preserves full-content list views; positive enables paginated summaries.
PostCacheTTL time.Duration // Post cache TTL (default 5min)
}
SiteConfig holds all configuration for a pubengine site.
func (*SiteConfig) GoogleAuthEnabled ¶
func (c *SiteConfig) GoogleAuthEnabled() bool
GoogleAuthEnabled returns true when all three Google OAuth fields are configured.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps a SQLite database and provides CRUD operations for blog posts.
func NewStore ¶
NewStore opens (or creates) the SQLite database at path, ensures the data directory exists, and runs schema migrations.
func (*Store) DeleteImage ¶
DeleteImage removes image metadata from the database.
func (*Store) DeleteImageContext ¶ added in v0.4.0
func (*Store) DeletePost ¶
DeletePost removes a post and its previous URLs atomically.
func (*Store) DeletePostContext ¶ added in v0.4.0
func (*Store) GetPostAny ¶
GetPostAny returns a post by slug regardless of published status (for admin).
func (*Store) GetPostAnyContext ¶ added in v0.4.0
func (*Store) GetPostContext ¶ added in v0.4.0
func (*Store) ListAdminPageContext ¶ added in v0.4.0
func (*Store) ListAllPosts ¶
ListAllPosts returns every post (published and drafts) ordered by date descending.
func (*Store) ListAllPostsContext ¶ added in v0.4.0
func (*Store) ListImages ¶
ListImages returns all images ordered by upload time descending.
func (*Store) ListImagesContext ¶ added in v0.4.0
func (*Store) ListImagesPageContext ¶ added in v0.4.0
func (*Store) ListPosts ¶
ListPosts returns all published posts ordered by date descending. If tag is non-empty, results are filtered to posts containing that tag.
func (*Store) ListPostsContext ¶ added in v0.4.0
func (*Store) ListSummariesContext ¶ added in v0.4.0
ListSummariesContext omits article bodies.
func (*Store) ListTags ¶
ListTags returns a sorted, deduplicated slice of all tags from published posts.
func (*Store) ListTagsContext ¶ added in v0.4.0
func (*Store) ResolvePostRedirect ¶ added in v0.4.0
ResolvePostRedirect returns the current slug only when the destination is published.
func (*Store) ResolvePostRedirectContext ¶ added in v0.4.0
func (*Store) SaveImageContext ¶ added in v0.4.0
type ViewFuncs ¶
type ViewFuncs struct {
Home func(posts []BlogPost, activeTag string, tags []string, siteURL string) templ.Component
HomePartial func(posts []BlogPost, activeTag string, tags []string, siteURL string) templ.Component
BlogSection func(posts []BlogPost, activeTag string, tags []string) templ.Component
Post func(post BlogPost, posts []BlogPost, siteURL string) templ.Component
PostPartial func(post BlogPost, posts []BlogPost, siteURL string) templ.Component
AdminLogin func(errorMsg string, csrfToken string, googleLoginURL string) templ.Component
AdminDashboard func(posts []BlogPost, message string, csrfToken string) templ.Component
AdminFormPartial func(post BlogPost, csrfToken string) templ.Component
AdminEditor func(post BlogPost, csrfToken string) templ.Component
AdminImages func(images []Image, csrfToken string) templ.Component
NotFound func() templ.Component
ServerError func() templ.Component
}
ViewFuncs holds user-provided templ components that the framework calls when rendering pages. This is the inversion-of-control mechanism that lets users own and customize all templates.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package analytics provides privacy-first website analytics.
|
Package analytics provides privacy-first website analytics. |
|
templates
templ: version: v0.3.960
|
templ: version: v0.3.960 |
|
cmd
|
|
|
pubengine
command
|
|
|
internal
|
|
|
sqliteutil
Package sqliteutil configures the database connections used by both stores.
|
Package sqliteutil configures the database connections used by both stores. |
|
Package markdown provides a simple Markdown-to-HTML renderer as a templ component.
|
Package markdown provides a simple Markdown-to-HTML renderer as a templ component. |
|
Package scaffold provides embedded template files for the pubengine CLI project scaffolding tool.
|
Package scaffold provides embedded template files for the pubengine CLI project scaffolding tool. |