Documentation
¶
Index ¶
- Constants
- func CORS(next http.Handler) http.Handler
- func DefaultFuncMap() template.FuncMap
- func DefaultRateLimitKeyFunc(r *http.Request) string
- func GetLocalIP() (string, error)
- func GzipFileServer(root http.FileSystem) http.Handler
- func HtmxCurrentURL(r *http.Request) string
- func HtmxPrompt(r *http.Request) string
- func HtmxTarget(r *http.Request) string
- func HtmxTrigger(r *http.Request) string
- func IsBoostedRequest(r *http.Request) bool
- func IsHtmxRequest(r *http.Request) bool
- func LoadAll(r *http.Request, w http.ResponseWriter, app any, loaders ...Loader) (error, bool)
- func ParseTemplateSpec(spec string) (fileName, blockName string)
- func PrintStartupMessage(address string)
- func Register[V View[AC], AC any](app *App[AC], mux *http.ServeMux, pattern string, opts ...Option) *http.ServeMux
- func RegisterFunc(mux *http.ServeMux, pattern string, handler http.HandlerFunc) *http.ServeMux
- func RegisterGroup[G PageGroup[AC], AC any](app *App[AC], mux *http.ServeMux, prefix string, opts ...Option) *http.ServeMux
- func RegisterHandler(mux *http.ServeMux, pattern string, handler http.Handler) *http.ServeMux
- func SetupTemplates(paths ...string) *tmplr.TemplateGroup
- func SmartRegister[V interface{ ... }, AC any](app *App[AC], mux *http.ServeMux, pattern string, fullTemplateSpec string, ...) *http.ServeMux
- type App
- type AuthProvider
- type AuthUser
- type BasePage
- type EntityListingData
- func (d *EntityListingData[ItemType]) DeleteUrl(id string) string
- func (d *EntityListingData[ItemType]) EditUrl(id string) string
- func (d *EntityListingData[ItemType]) ViewUrl(id string) string
- func (d *EntityListingData[ItemType]) WithCreate(url, label string) *EntityListingData[ItemType]
- func (d *EntityListingData[ItemType]) WithDelete(url string) *EntityListingData[ItemType]
- func (d *EntityListingData[ItemType]) WithEdit(url string) *EntityListingData[ItemType]
- func (d *EntityListingData[ItemType]) WithHtmx(searchUrl string) *EntityListingData[ItemType]
- func (d *EntityListingData[ItemType]) WithView(url string) *EntityListingData[ItemType]
- type HtmxAware
- type HtmxResponse
- func (h *HtmxResponse) Location(url string) *HtmxResponse
- func (h *HtmxResponse) LocationWithContext(spec map[string]any) *HtmxResponse
- func (h *HtmxResponse) PushURL(url string) *HtmxResponse
- func (h *HtmxResponse) Redirect(url string) *HtmxResponse
- func (h *HtmxResponse) Refresh() *HtmxResponse
- func (h *HtmxResponse) ReplaceURL(url string) *HtmxResponse
- func (h *HtmxResponse) Reselect(selector string) *HtmxResponse
- func (h *HtmxResponse) Reswap(style string) *HtmxResponse
- func (h *HtmxResponse) Retarget(selector string) *HtmxResponse
- func (h *HtmxResponse) StopPolling() *HtmxResponse
- func (h *HtmxResponse) Trigger(event string) *HtmxResponse
- func (h *HtmxResponse) TriggerAfterSettle(event string) *HtmxResponse
- func (h *HtmxResponse) TriggerAfterSwap(event string) *HtmxResponse
- func (h *HtmxResponse) TriggerWithData(event string, data any) *HtmxResponse
- type Loader
- type LoaderFunc
- type LoginConfig
- type MuxBuilder
- func (b *MuxBuilder[AC]) Build() *http.ServeMux
- func (b *MuxBuilder[AC]) Group(prefix string, setup func(*MuxBuilder[AC])) *MuxBuilder[AC]
- func (b *MuxBuilder[AC]) HandleFunc(pattern string, h http.HandlerFunc) *MuxBuilder[AC]
- func (b *MuxBuilder[AC]) Handler(pattern string, h http.Handler) *MuxBuilder[AC]
- func (b *MuxBuilder[AC]) Mux() *http.ServeMux
- func (b *MuxBuilder[AC]) Page(pattern string, maker func() View[AC], opts ...Option) *MuxBuilder[AC]
- func (b *MuxBuilder[AC]) Static(pattern string, dir string) *MuxBuilder[AC]
- func (b *MuxBuilder[AC]) Use(mw func(http.Handler) http.Handler) *MuxBuilder[AC]
- type Option
- type PageGroup
- type RateLimitConfig
- type RateLimitMiddleware
- type RateLimiter
- type SampleLoginPage
- type SampleProfilePage
- type SampleRegisterPage
- type SortOption
- type View
- type WebAppServer
- type WithAuth
- type WithFiltering
- type WithHtmx
- type WithPagination
- func (p *WithPagination) EvalPages()
- func (p *WithPagination) Load(r *http.Request, w http.ResponseWriter, vc any) (error, bool)
- func (p *WithPagination) NextPage() int
- func (p *WithPagination) Offset() int
- func (p *WithPagination) Paginator() *WithPagination
- func (p *WithPagination) PrevPage() int
- func (p *WithPagination) SetTotal(total int, hasMore bool)
- func (p *WithPagination) TotalPages() int
Constants ¶
const ( ColorReset = "\033[0m" ColorCyan = "\033[36m" ColorGreen = "\033[32m" ColorYellow = "\033[33m" ColorBold = "\033[1m" )
ANSI color codes
Variables ¶
This section is empty.
Functions ¶
func DefaultFuncMap ¶
DefaultFuncMap returns the default template functions.
func DefaultRateLimitKeyFunc ¶
DefaultRateLimitKeyFunc extracts the client identifier from the request. Uses X-Forwarded-For for proxied requests, otherwise RemoteAddr.
func GetLocalIP ¶
GetLocalIP returns the local network IP address (preferring ethernet/wifi over localhost)
func GzipFileServer ¶
func GzipFileServer(root http.FileSystem) http.Handler
GzipFileServer wraps an http.Handler to serve pre-compressed .gz files when available and the client accepts gzip encoding.
For WASM files, this serves .wasm.gz (4.7MB) instead of .wasm (25MB), reducing transfer size by ~81%.
func HtmxCurrentURL ¶
HtmxCurrentURL returns the HX-Current-URL header value.
func HtmxPrompt ¶
HtmxPrompt returns the HX-Prompt header value.
func HtmxTarget ¶
HtmxTarget returns the HX-Target header value.
func HtmxTrigger ¶
HtmxTrigger returns the HX-Trigger header value.
func IsBoostedRequest ¶
IsBoostedRequest checks if the request is a boosted link.
func IsHtmxRequest ¶
IsHtmxRequest checks if the request is an HTMX request.
func LoadAll ¶
LoadAll runs loaders in order with the page's app, and stops at the first one that returns an error or finished = true, returning what it returned. A nil loader is skipped. A page typically calls it from its own Load:
func (p *GamesPage) Load(r *http.Request, w http.ResponseWriter, app *goapplib.App[*Site]) (error, bool) {
return goapplib.LoadAll(r, w, app, &p.BasePage, &p.WithPagination, goapplib.LoaderFunc[*Site](p.loadGames))
}
func ParseTemplateSpec ¶
ParseTemplateSpec parses a template spec into file name and block name. Format: "path/to/template" or "path/to/template:BlockName"
If no ":" is present, block name is auto-derived from the base filename. If ":" is present, the part after ":" is used as the explicit block name. An empty block name after ":" means render the entire template file.
func PrintStartupMessage ¶
func PrintStartupMessage(address string)
PrintStartupMessage prints a colorized startup message with clickable links
func Register ¶
func Register[V View[AC], AC any]( app *App[AC], mux *http.ServeMux, pattern string, opts ...Option, ) *http.ServeMux
Register registers a View at the given pattern. If mux is nil, a new ServeMux is created. Returns the mux for chaining.
Usage:
mux := http.NewServeMux() goapplib.Register[*HomePage](app, mux, "/") goapplib.Register[*GameListingPage](app, mux, "/games/")
func RegisterFunc ¶
RegisterFunc registers a handler function at the given pattern. Convenience wrapper for mux.HandleFunc.
func RegisterGroup ¶
func RegisterGroup[G PageGroup[AC], AC any]( app *App[AC], mux *http.ServeMux, prefix string, opts ...Option, ) *http.ServeMux
RegisterGroup registers a PageGroup under the given prefix. The group's routes are mounted with the prefix stripped.
Usage:
goal.RegisterGroup[*GamesGroup](app, rootMux, "/games")
func RegisterHandler ¶
RegisterHandler registers an http.Handler at the given pattern. Convenience wrapper for mux.Handle.
func SetupTemplates ¶
func SetupTemplates(paths ...string) *tmplr.TemplateGroup
SetupTemplates creates a TemplateGroup with the given paths. Paths are checked in order, so put your app's templates first for overrides.
func SmartRegister ¶
func SmartRegister[V interface {
View[AC]
HtmxAware
}, AC any](
app *App[AC],
mux *http.ServeMux,
pattern string,
fullTemplateSpec string,
fragmentTemplateSpec string,
opts ...Option,
) *http.ServeMux
SmartRegister registers a View that renders fullTemplateSpec as a page and fragmentTemplateSpec for an htmx request that wants a fragment. It's Register with WithTemplate(fullTemplateSpec) and WithFragmentTemplate(fragmentTemplateSpec), kept for the code that calls it; new code can pass WithFragmentTemplate to Register or MuxBuilder.Page directly.
Types ¶
type App ¶
type App[AppContext any] struct { Context AppContext Templates *tmplr.TemplateGroup RenderTemplateFunc func(w http.ResponseWriter, templateFileName string, templateBlockName string, view any) error }
App holds app-level shared state and template system. AppContext is the application context type defined by your application (e.g., *WeewarApp).
func NewApp ¶
func NewApp[AppContext any](ctx AppContext, templates *tmplr.TemplateGroup) *App[AppContext]
NewApp creates a new App with the given application context and templates.
func (*App[AppContext]) NewMux ¶
func (app *App[AppContext]) NewMux() *MuxBuilder[AppContext]
NewMux creates a MuxBuilder for fluent route building.
func (*App[AppContext]) RenderTemplate ¶
func (app *App[AppContext]) RenderTemplate( w http.ResponseWriter, templateFileName string, templateBlockName string, view any) error
RenderTemplate renders the named template with the given view data. The page is rendered in full before any of it is written, so on an error nothing has reached w and the caller can still answer with an error status (#108). If RenderTemplateFunc is set, it delegates to that function, which is responsible for its own writes.
type AuthProvider ¶
type AuthProvider interface {
GetLoggedInUserId(r *http.Request) string
GetUserById(id string) (AuthUser, error)
}
AuthProvider is the interface for auth services.
type BasePage ¶
type BasePage struct {
Title string // Page title (internal use, fallback for MetaTitle)
BodyClass string // CSS classes for <body>
ActiveTab string // Highlight active navigation tab
CustomHeader bool // If true, skip default header rendering
DisableSplashScreen bool // If true, hide loading splash
SplashTitle string // Custom splash title
SplashMessage string // Custom splash message
BodyDataAttributes string // HTML data attributes for body
// SEO fields
MetaTitle string // Title for <title> tag and search results (falls back to Title if empty)
MetaDescription string // Meta description for search engines
CanonicalUrl string // Canonical URL for SEO (e.g., https://example.com/page/)
}
BasePage provides common page metadata. Embed this in your page structs.
type EntityListingData ¶
type EntityListingData[ItemType any] struct { // Page header Title string Subtitle string CreateUrl string CreateLabel string // View configuration ViewMode string // "grid" or "list" ViewModeStorageKey string // localStorage key for saving preference EnableViewToggle bool GridContainerId string SearchInputId string SortSelectId string SearchPlaceholder string // URL "formats". To get the Url we would do something like fmt.Sprintf(fmt, Id) ViewUrlFormat string EditUrlFormat string DeleteUrlFormat string SearchUrl string RefreshUrl string // Sort options SortOptions []SortOption // Items to display - templates access fields directly (e.g., .Id, .Name, .Description) Items []ItemType // Actions ShowActions bool ShowEditButton bool // Show edit button (typically only when logged in) HtmxEnabled bool RefreshTrigger string // Empty state EmptyTitle string EmptyMessage string }
EntityListingData provides data for the EntityListing template component. This struct is designed to work with the EntityListing.html template. ItemType is the type of items in the listing - templates access item fields directly (e.g., .Id, .Name).
func NewEntityListingData ¶
func NewEntityListingData[ItemType any](title string, viewUrlFormat string) *EntityListingData[ItemType]
NewEntityListingData creates a new EntityListingData with sensible defaults.
func (*EntityListingData[ItemType]) DeleteUrl ¶
func (d *EntityListingData[ItemType]) DeleteUrl(id string) string
Returns the formatted DeleteUrl
func (*EntityListingData[ItemType]) EditUrl ¶
func (d *EntityListingData[ItemType]) EditUrl(id string) string
Returns the formatted EditUrl
func (*EntityListingData[ItemType]) ViewUrl ¶
func (d *EntityListingData[ItemType]) ViewUrl(id string) string
Returns the formatted ViewUrl
func (*EntityListingData[ItemType]) WithCreate ¶
func (d *EntityListingData[ItemType]) WithCreate(url, label string) *EntityListingData[ItemType]
WithCreate sets the create URL and label
func (*EntityListingData[ItemType]) WithDelete ¶
func (d *EntityListingData[ItemType]) WithDelete(url string) *EntityListingData[ItemType]
WithDelete sets the delete URL
func (*EntityListingData[ItemType]) WithEdit ¶
func (d *EntityListingData[ItemType]) WithEdit(url string) *EntityListingData[ItemType]
WithEdit sets the edit URL
func (*EntityListingData[ItemType]) WithHtmx ¶
func (d *EntityListingData[ItemType]) WithHtmx(searchUrl string) *EntityListingData[ItemType]
WithHtmx enables HTMX for the listing
func (*EntityListingData[ItemType]) WithView ¶
func (d *EntityListingData[ItemType]) WithView(url string) *EntityListingData[ItemType]
WithView sets the viewer URL
type HtmxAware ¶
type HtmxAware interface {
ShouldRenderFragment() bool
}
HtmxAware is implemented by views that can detect HTMX requests.
type HtmxResponse ¶
type HtmxResponse struct {
// contains filtered or unexported fields
}
HtmxResponse provides helpers for setting HTMX response headers.
func NewHtmxResponse ¶
func NewHtmxResponse(w http.ResponseWriter) *HtmxResponse
NewHtmxResponse creates a new HtmxResponse wrapper.
func (*HtmxResponse) Location ¶
func (h *HtmxResponse) Location(url string) *HtmxResponse
Location does a client-side redirect without full page reload.
func (*HtmxResponse) LocationWithContext ¶
func (h *HtmxResponse) LocationWithContext(spec map[string]any) *HtmxResponse
LocationWithContext does a redirect with additional context.
func (*HtmxResponse) PushURL ¶
func (h *HtmxResponse) PushURL(url string) *HtmxResponse
PushURL pushes a new URL onto the browser's history stack.
func (*HtmxResponse) Redirect ¶
func (h *HtmxResponse) Redirect(url string) *HtmxResponse
Redirect tells HTMX to perform a client-side redirect.
func (*HtmxResponse) Refresh ¶
func (h *HtmxResponse) Refresh() *HtmxResponse
Refresh tells HTMX to do a full page refresh.
func (*HtmxResponse) ReplaceURL ¶
func (h *HtmxResponse) ReplaceURL(url string) *HtmxResponse
ReplaceURL replaces the current URL in the browser's history.
func (*HtmxResponse) Reselect ¶
func (h *HtmxResponse) Reselect(selector string) *HtmxResponse
Reselect changes the selection from the response.
func (*HtmxResponse) Reswap ¶
func (h *HtmxResponse) Reswap(style string) *HtmxResponse
Reswap changes the swap method.
func (*HtmxResponse) Retarget ¶
func (h *HtmxResponse) Retarget(selector string) *HtmxResponse
Retarget changes the target element for the swap.
func (*HtmxResponse) StopPolling ¶
func (h *HtmxResponse) StopPolling() *HtmxResponse
StopPolling tells HTMX to stop polling.
func (*HtmxResponse) Trigger ¶
func (h *HtmxResponse) Trigger(event string) *HtmxResponse
Trigger sets the HX-Trigger header to trigger a client-side event.
func (*HtmxResponse) TriggerAfterSettle ¶
func (h *HtmxResponse) TriggerAfterSettle(event string) *HtmxResponse
TriggerAfterSettle sets HX-Trigger-After-Settle header.
func (*HtmxResponse) TriggerAfterSwap ¶
func (h *HtmxResponse) TriggerAfterSwap(event string) *HtmxResponse
TriggerAfterSwap sets HX-Trigger-After-Swap header.
func (*HtmxResponse) TriggerWithData ¶
func (h *HtmxResponse) TriggerWithData(event string, data any) *HtmxResponse
TriggerWithData sets HX-Trigger with JSON data.
type Loader ¶
type Loader interface {
Load(r *http.Request, w http.ResponseWriter, app any) (err error, finished bool)
}
Loader is one step of a page's Load, run in order by LoadAll. goapplib's mixins (BasePage, WithPagination, WithFiltering, WithAuth, WithHtmx) are Loaders as they are, so a page chains them with LoadAll. app is the page's *App[AC], passed through as is; a loader that needs it typed is a LoaderFunc[AC].
Before 0.7.0 this was Loader[AC], with app typed as *App[AC], which no built-in mixin satisfied (issue 107).
type LoaderFunc ¶
LoaderFunc is a typed Loader: an app's own loading step, which gets app as its *App[AC]. Given an app of any other type, it doesn't run, and returns an error naming both types, which LoadAll returns, so a page renders a 500 rather than panicking.
func AuthLoader ¶
func AuthLoader[AC any](auth *WithAuth, provider AuthProvider) LoaderFunc[AC]
AuthLoader returns a LoaderFunc that loads auth info, for LoadAll when you have an AuthProvider. Its app type can't be inferred, so name it: AuthLoader[*Site](&p.WithAuth, provider).
func (LoaderFunc[AC]) Load ¶
func (f LoaderFunc[AC]) Load(r *http.Request, w http.ResponseWriter, app any) (error, bool)
Load implements Loader.
type LoginConfig ¶
type LoginConfig struct {
EnableEmailLogin bool
EnableGoogleLogin bool
EnableGitHubLogin bool
EnableMicrosoftLogin bool
EnableAppleLogin bool
}
LoginConfig controls which login methods are available.
type MuxBuilder ¶
type MuxBuilder[AC any] struct { // contains filtered or unexported fields }
MuxBuilder builds a ServeMux fluently, as an alternative to calling Register and RegisterGroup:
mux := app.NewMux().
Page("/{$}", func() goapplib.View[*Site] { return &HomePage{} }).
Group("/games", func(m *goapplib.MuxBuilder[*Site]) {
m.Page("/{id}", func() goapplib.View[*Site] { return &GamePage{} })
}).
Build()
A Page renders exactly as Register would render the same view type.
func (*MuxBuilder[AC]) Build ¶
func (b *MuxBuilder[AC]) Build() *http.ServeMux
Build returns the constructed ServeMux.
func (*MuxBuilder[AC]) Group ¶
func (b *MuxBuilder[AC]) Group(prefix string, setup func(*MuxBuilder[AC])) *MuxBuilder[AC]
Group mounts the routes setup adds under prefix, which is stripped before they match, so a route "/{id}" in a Group("/games", ...) answers /games/7. Middleware added by Use before the Group wraps the whole group.
func (*MuxBuilder[AC]) HandleFunc ¶
func (b *MuxBuilder[AC]) HandleFunc(pattern string, h http.HandlerFunc) *MuxBuilder[AC]
HandleFunc registers an http.HandlerFunc.
func (*MuxBuilder[AC]) Handler ¶
func (b *MuxBuilder[AC]) Handler(pattern string, h http.Handler) *MuxBuilder[AC]
Handler registers an http.Handler.
func (*MuxBuilder[AC]) Mux ¶
func (b *MuxBuilder[AC]) Mux() *http.ServeMux
Mux returns the underlying ServeMux for direct access.
func (*MuxBuilder[AC]) Page ¶
func (b *MuxBuilder[AC]) Page(pattern string, maker func() View[AC], opts ...Option) *MuxBuilder[AC]
Page registers a view at pattern. maker returns a fresh view for each request, and the view's type picks its template the way Register's does (HomePage renders HomePage.html's HomePage block), unless WithTemplate says otherwise.
func (*MuxBuilder[AC]) Static ¶
func (b *MuxBuilder[AC]) Static(pattern string, dir string) *MuxBuilder[AC]
Static serves the files in dir at pattern, with pattern stripped from the path.
func (*MuxBuilder[AC]) Use ¶
func (b *MuxBuilder[AC]) Use(mw func(http.Handler) http.Handler) *MuxBuilder[AC]
Use adds middleware to every route registered after it on this builder, groups included. Routes registered before it aren't wrapped. Middleware added by several Uses runs in the order added.
type Option ¶
type Option func(*options)
Option configures registration behavior.
func WithFragmentTemplate ¶ added in v0.7.2
WithFragmentTemplate sets the template a page renders for an htmx request that wants a fragment rather than the whole page: when the view is HtmxAware (embedding WithHtmx makes it so, once WithHtmx has loaded) and its ShouldRenderFragment is true, which it is for an htmx request that isn't a boosted link. Any other request, or a view that isn't HtmxAware, gets the page's usual template. spec has WithTemplate's form, "path/File" or "path/File:Block".
func WithMiddleware ¶
WithMiddleware adds middleware to the handler.
func WithTemplate ¶
WithTemplate sets the template file and optional block name. Format: "path/to/template" or "path/to/template:BlockName"
If no ":" is present, block name is auto-derived from the base filename. If ":" is present, the part after ":" is used as the explicit block name. An empty block name after ":" means render the entire template file.
Examples:
- "CanvasListingPage" -> file: CanvasListingPage.html, block: CanvasListingPage (auto-derived)
- "canvases/CanvasListingPage" -> file: canvases/CanvasListingPage.html, block: CanvasListingPage (auto-derived)
- "canvases/CanvasListingPage:MyBlock" -> file: canvases/CanvasListingPage.html, block: MyBlock
- "canvases/CanvasListingPage:" -> file: canvases/CanvasListingPage.html, block: "" (entire file)
type PageGroup ¶
type PageGroup[AC any] interface { // RegisterRoutes returns a ServeMux with all routes for this group. // Patterns should be relative (prefix is stripped by RegisterGroup). RegisterRoutes(app *App[AC]) *http.ServeMux }
PageGroup is the interface for a group of related pages. Implement this to define a set of routes under a common prefix.
type RateLimitConfig ¶
type RateLimitConfig struct {
// Auth endpoints (login, signup, forgot-password) - stricter limits
AuthLimit int
AuthWindow time.Duration
// API endpoints - more permissive
APILimit int
APIWindow time.Duration
}
RateLimitConfig holds configuration for different rate limit tiers.
func DefaultRateLimitConfig ¶
func DefaultRateLimitConfig() *RateLimitConfig
DefaultRateLimitConfig returns sensible defaults for rate limiting.
type RateLimitMiddleware ¶
type RateLimitMiddleware struct {
// contains filtered or unexported fields
}
RateLimitMiddleware creates HTTP middleware that applies rate limiting.
func NewRateLimitMiddleware ¶
func NewRateLimitMiddleware(config *RateLimitConfig) *RateLimitMiddleware
NewRateLimitMiddleware creates rate limiting middleware with the given config.
func NewRateLimitMiddlewareWithKeyFunc ¶
func NewRateLimitMiddlewareWithKeyFunc(config *RateLimitConfig, keyFunc func(*http.Request) string) *RateLimitMiddleware
NewRateLimitMiddlewareWithKeyFunc creates middleware with a custom key function.
func (*RateLimitMiddleware) Wrap ¶
func (m *RateLimitMiddleware) Wrap(next http.Handler) http.Handler
Wrap wraps any handler with the API rate limiter. This is a convenience method for handlers that aren't auth-specific.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter provides a simple in-memory rate limiting using sliding window. For production with multiple instances, consider using Redis-based rate limiting.
func NewRateLimiter ¶
func NewRateLimiter(limit int, window time.Duration) *RateLimiter
NewRateLimiter creates a new rate limiter with the specified limit per window.
func (*RateLimiter) Allow ¶
func (rl *RateLimiter) Allow(key string) bool
Allow checks if a request from the given key should be allowed.
type SampleLoginPage ¶
type SampleLoginPage[AC any] struct { BasePage CallbackURL string CsrfToken string Config LoginConfig }
SampleLoginPage provides sample login page functionality. Embed this in your app-specific login page struct.
func (*SampleLoginPage[AC]) Load ¶
func (p *SampleLoginPage[AC]) Load(r *http.Request, w http.ResponseWriter, app *App[AC]) (err error, finished bool)
Load implements View[AC] for SampleLoginPage.
type SampleProfilePage ¶
type SampleProfilePage[AC any] struct { BasePage // User information UserID string Nickname string Email string EmailVerified bool Username string Profile map[string]any VerificationSent bool VerificationError string }
SampleProfilePage provides sample profile page functionality. Embed this in your app-specific profile page struct.
func (*SampleProfilePage[AC]) Load ¶
func (p *SampleProfilePage[AC]) Load(r *http.Request, w http.ResponseWriter, app *App[AC]) (err error, finished bool)
Load implements View[AC] for SampleProfilePage.
type SampleRegisterPage ¶
type SampleRegisterPage[AC any] struct { BasePage CallbackURL string CsrfToken string Name string Email string Password string VerifyPassword string Errors map[string]string }
SampleRegisterPage provides sample registration page functionality. Embed this in your app-specific register page struct.
func (*SampleRegisterPage[AC]) Load ¶
func (p *SampleRegisterPage[AC]) Load(r *http.Request, w http.ResponseWriter, app *App[AC]) (err error, finished bool)
Load implements View[AC] for SampleRegisterPage.
type SortOption ¶
SortOption represents a sort dropdown option
type View ¶
type View[AC any] interface { // Load prepares the view data from the request. // app provides access to the application context and templates. // Returns (error, finished): // - error: non-nil if an error occurred (will be displayed) // - finished: true if response was already written (redirect, etc.) Load(r *http.Request, w http.ResponseWriter, app *App[AC]) (err error, finished bool) }
View is the interface that all pages/views must implement. AC is the application context type (e.g., *WeewarApp).
type WebAppServer ¶
WebAppServer provides a generic HTTP server with optional CORS and logging.
func (*WebAppServer) StartWithHandler ¶
func (s *WebAppServer) StartWithHandler(ctx context.Context, handler http.Handler, srvErr chan error, stopChan chan bool) error
StartWithHandler starts the HTTP server with the given handler.
type WithAuth ¶
type WithAuth struct {
LoggedInUserId string // Current user's ID
Username string // Current user's display name
IsLoggedIn bool // True if user is authenticated
IsOwner bool // True if user owns the current entity
}
WithAuth provides authentication info. Embed this in page structs that need user info.
func (*WithAuth) Load ¶
Load is a no-op for WithAuth. Use LoadWithAuth to load auth info with your auth services.
func (*WithAuth) LoadWithAuth ¶
LoadWithAuth loads auth info using the provided auth services.
type WithFiltering ¶
type WithFiltering struct {
Query string // Search query
Sort string // Sort field/direction
ViewMode string // Display mode: "grid", "table", etc.
}
WithFiltering provides search and sort support. Embed this in page structs that support filtering.
func (*WithFiltering) Load ¶
func (p *WithFiltering) Load(r *http.Request, w http.ResponseWriter, vc any) (error, bool)
Load implements Loader for WithFiltering.
type WithHtmx ¶
type WithHtmx struct {
IsHtmx bool // True if this is an HTMX request
IsBoosted bool // True if this is a boosted link
Target string // HX-Target header value
Trigger string // HX-Trigger header value
TriggerName string // HX-Trigger-Name header value
CurrentURL string // HX-Current-URL header value
Prompt string // HX-Prompt header value
}
WithHtmx provides HTMX request detection. Embed this in page structs that need HTMX-aware rendering.
func (*WithHtmx) ShouldRenderFragment ¶
ShouldRenderFragment returns true if only a fragment should be rendered.
type WithPagination ¶
type WithPagination struct {
CurrentPage int // 0-indexed current page
PageSize int // Items per page
TotalCount int // Total number of items
HasPrevPage bool // True if there's a previous page
HasNextPage bool // True if there's a next page
Pages []int // Page numbers to display in pagination UI
}
WithPagination provides pagination support. Embed this in page structs that display paginated lists.
func (*WithPagination) EvalPages ¶
func (p *WithPagination) EvalPages()
EvalPages calculates page numbers to display.
func (*WithPagination) Load ¶
func (p *WithPagination) Load(r *http.Request, w http.ResponseWriter, vc any) (error, bool)
Load implements Loader for WithPagination.
func (*WithPagination) NextPage ¶
func (p *WithPagination) NextPage() int
NextPage returns the next page number.
func (*WithPagination) Offset ¶
func (p *WithPagination) Offset() int
Offset returns the offset for database queries.
func (*WithPagination) Paginator ¶
func (p *WithPagination) Paginator() *WithPagination
Paginator returns self for template access via .Paginator This allows templates to use {{ .Paginator.HasPrevPage }} etc. when the page struct embeds WithPagination.
func (*WithPagination) PrevPage ¶
func (p *WithPagination) PrevPage() int
PrevPage returns the previous page number.
func (*WithPagination) SetTotal ¶
func (p *WithPagination) SetTotal(total int, hasMore bool)
SetTotal updates pagination state based on total count.
func (*WithPagination) TotalPages ¶ added in v0.7.2
func (p *WithPagination) TotalPages() int
TotalPages is how many pages TotalCount fills at PageSize, or 0 before SetTotal. goapplib's Pagination template shows it.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
content
|
|
|
gen/datastore/collections/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/datastore/dal/collections/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/datastore/dal/likes/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/datastore/dal/tags/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/datastore/likes/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/datastore/tags/v1
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
gen/go/collections/v1
Package collectionsv1 is a reverse proxy.
|
Package collectionsv1 is a reverse proxy. |
|
gen/go/likes/v1
Package likesv1 is a reverse proxy.
|
Package likesv1 is a reverse proxy. |
|
gen/go/tags/v1
Package tagsv1 is a reverse proxy.
|
Package tagsv1 is a reverse proxy. |
|
gen/gorm/collections/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gen/gorm/dal/collections/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gen/gorm/dal/likes/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gen/gorm/dal/tags/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gen/gorm/likes/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gen/gorm/tags/v1
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
services/collections
Package collections provides Connect RPC adapters for the CollectionsService.
|
Package collections provides Connect RPC adapters for the CollectionsService. |
|
services/collections/backends
Package backends provides concrete storage implementations for the collections service.
|
Package backends provides concrete storage implementations for the collections service. |
|
services/common
Package common provides shared utilities for content services.
|
Package common provides shared utilities for content services. |
|
services/likes
Package likes provides Connect RPC adapters for the LikesService.
|
Package likes provides Connect RPC adapters for the LikesService. |
|
services/likes/backends
Package backends provides concrete storage implementations for the likes service.
|
Package backends provides concrete storage implementations for the likes service. |
|
services/tags
Package tags provides Connect RPC adapters for the TagsService.
|
Package tags provides Connect RPC adapters for the TagsService. |
|
services/tags/backends
Package backends provides concrete storage implementations for the tags service.
|
Package backends provides concrete storage implementations for the tags service. |
|
Package datastore provides shared utilities for Google Cloud Datastore backends.
|
Package datastore provides shared utilities for Google Cloud Datastore backends. |
|
exercise
|
|
|
islands
command
The exercise for mission #60 (goapplib issue 61): a server-rendered page whose spec names three islands with different load strategies, drawn by goapplib's own PageSpecScript partial.
|
The exercise for mission #60 (goapplib issue 61): a server-rendered page whose spec names three islands with different load strategies, drawn by goapplib's own PageSpecScript partial. |
|
wasmhost/gen/go/files/v1/filesv1connect
A toy service for the wasmhost exercise (goapplib issue 33).
|
A toy service for the wasmhost exercise (goapplib issue 33). |
|
wasmhost/service
Package service is the exercise's toy FilesService.
|
Package service is the exercise's toy FilesService. |
|
wasmhost/wasm
command
The exercise's wasm build: FilesService served from a Web Worker on globalThis.files.
|
The exercise's wasm build: FilesService served from a Web Worker on globalThis.files. |
|
workerstate/service
Package service is the toy stateful service behind mission #74's exercise (goapplib issue 75).
|
Package service is the toy stateful service behind mission #74's exercise (goapplib issue 75). |
|
workerstate/wasm
command
The worker side of the worker-state exercise: the toy service as wasm, behind wasmhost.
|
The worker side of the worker-state exercise: the toy service as wasm, behind wasmhost. |
|
gen
|
|
|
datastore
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
datastore/dal
Code generated by protoc-gen-dal-datastore.
|
Code generated by protoc-gen-dal-datastore. |
|
go/goapplib/v1
Package goapplibv1 is a reverse proxy.
|
Package goapplibv1 is a reverse proxy. |
|
gorm
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
gorm/dal
Code generated by protoc-gen-dal-gorm.
|
Code generated by protoc-gen-dal-gorm. |
|
Package page describes which islands a page mounts and where, as a Spec the server writes into the page for the browser to read (tsappkit's island page mounts each island from a registry by name).
|
Package page describes which islands a page mounts and where, as a Spec the server writes into the page for the browser to read (tsappkit's island page mounts each island from a registry by name). |
|
Package services provides reusable service implementations for user management and authentication.
|
Package services provides reusable service implementations for user management and authentication. |
|
backends/fs
Package fs provides a filesystem-based implementation of the UsersService.
|
Package fs provides a filesystem-based implementation of the UsersService. |
|
backends/gae
Package gae provides a Google Cloud Datastore session store for scs (alexedwards/scs/v2).
|
Package gae provides a Google Cloud Datastore session store for scs (alexedwards/scs/v2). |
|
backends/gorm
Package gorm provides a GORM-based implementation of the UsersService.
|
Package gorm provides a GORM-based implementation of the UsersService. |
|
Package wasmhost runs an app's HTTP services (typically Connect handlers) as WebAssembly inside a browser Web Worker, answering the same generated clients a server answers.
|
Package wasmhost runs an app's HTTP services (typically Connect handlers) as WebAssembly inside a browser Web Worker, answering the same generated clients a server answers. |