lariv

package module
v0.6.11 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 41 Imported by: 0

README

Lariv Web Framework

Go Reference

Lariv is a modular, plugin-based web application framework for Go. It features dynamic registry-based layouts, hot-reloadable plugin features, transactional views, and database schema migrations managed per plugin.

For a detailed bootstrapping guide, check out the Lariv Quickstart Guide.

Quickstart

Database Setup (PostgreSQL)

To use PostgreSQL with Lariv:

  1. Install PostgreSQL:

    • Linux (Ubuntu/Debian): Run sudo apt update && sudo apt install postgresql postgresql-contrib
    • macOS: Run brew install postgresql
    • Windows: Download and run the installer from the PostgreSQL Official Downloads Page.
  2. Start the PostgreSQL Service:

    • Linux: Run sudo systemctl start postgresql
    • macOS: Run brew services start postgresql
  3. Create a Database User and Database: Access the PostgreSQL prompt:

    • Linux/macOS: Run:
      sudo -u postgres psql
      
    • Windows: Launch SQL Shell (psql) from the Start Menu, or open Command Prompt/PowerShell and run:
      psql -U postgres
      
      (If psql is not in your system PATH, run it from the installation directory, e.g., "C:\Program Files\PostgreSQL\<version>\bin\psql.exe" -U postgres) Run the following SQL commands to create a user and database:
    CREATE USER lariv_user WITH PASSWORD 'secure_password';
    CREATE DATABASE lariv_db OWNER lariv_user;
    \q
    

Create a empty go project named lariv_test

mkdir lariv_test
cd lariv_test
go mod init lariv_test
go get github.com/lariv-in/lariv@latest

Create an empty main.go, and an empty config.toml file

touch main.go
touch config.toml

In config.toml, put the following to connect with the postgres server configured above:

Debug = true
DBType = "Postgres"
Address = ":42069"

[PostgresConfig]
  DSN = "host=localhost user=lariv_user password=secure_password dbname=lariv_db port=5432 sslmode=disable TimeZone=Asia/Kolkata"

[plugins.p_pwa]
  # If set, /serviceworker.js will serve this file. If empty, p_pwa serves a minimal default.
  serviceWorkerPath = ""

  # If set, /offline will render this view key. If empty, p_pwa serves a minimal offline HTML page.
  offlineViewName = ""

  staticDir = "./pwa_static/"

  PWA_APP_NAME = "Lariv Test"
  PWA_APP_DESCRIPTION = "Test app for lariv"
  PWA_APP_THEME_COLOR = "#0A0302"
  PWA_APP_BACKGROUND_COLOR = "#ffffff"
  PWA_APP_DISPLAY = "standalone"
  PWA_APP_SCOPE = "/"
  PWA_APP_ORIENTATION = "any"
  PWA_APP_START_URL = "/"
  PWA_APP_STATUS_BAR_COLOR = "default"
  PWA_APP_DIR = "ltr"
  PWA_APP_LANG = "en-US"

[plugins.p_users]
adminEmail = "superadmin@test.com"
adminPassword = "SuperadminPassword1234"

To initialize a Lariv application by registering active plugins, loading configuration values from a TOML file, and executing the CLI entrypoint, put the following in main.go

package main

import (
	"log"

	"github.com/lariv-in/lariv"
	"github.com/lariv-in/lariv/plugins/p_dashboard"
	"github.com/lariv-in/lariv/plugins/p_users"
	"github.com/lariv-in/lariv/registry"
)

func main() {
	// 1. Register the list of active plugins to load into the application kernel.
	plugins := []registry.Pair[string, lariv.Plugin]{
		p_dashboard.GetPlugin(),
		p_users.GetPlugin(),
	}
	// Load database settings, server addresses, and plugin parameters from config.toml.
	app, err := lariv.NewBuilder().AddPlugins(plugins).LoadConfigFromFile("config.toml")
	if err != nil {
		log.Fatalf("failed loading configuration file: %v", err)
	}

	// 2. Run the Cobra CLI bootstrapper.
	if err := app.Start(); err != nil {
		log.Fatalf("failed executing application entry: %v", err)
	}
}

To run,

go mod tidy
go run main.go generate
go run main.go

You can now login using the following credentials:

Email: superadmin@test.com Password: SuperadminPassword1234

Features

  • Plugin Registries: Package database models, pages, API routes, and configs inside modular plugin boundaries.
  • Transactional View Layers: Compose request pipelines with built-in or custom middleware layers to handle detail loading, form updates, and deletions.
  • Goose Migrations: Keep SQL database migrations decoupled and isolated inside plugin subdirectory systems.

Next Steps & Documentation

For detailed package documentation and guides, check out:

  • Lariv Quickstart Guide: Detailed guide on bootstrapping and building modular plugins.
  • Lariv Documentation Package: Explains the application directory structure, standard plugin files (app.go, config.go, pages.go, migrations.go, routes.go, models.go, views.go, commands.go), and architectural concepts (layers.go, components.go, querypatchers.go).

Documentation

Overview

Package lariv is the application kernel: configuration loading, HTTP server wiring, and aggregated plugin registries (pages, views, routes, models, migrations, etc.).

Core Plugin Registrations

The kernel registers a default "core" plugin during boot via CorePlugin(). Below is a detailed list of features, pages, views, and routes contributed by the core plugin:

Core Global Layers (Global HTTP Middleware)

Registered under the following keys:

  • "core.AttachRequestLayer" -> views.AttachRequestLayer Attaches raw query parameter map ($get), request object ($request), and start timestamp ($timestamp) to the request context.
  • "core.DbLayer" -> DBLayer Attaches the active GORM database connection pool instance ($db) to the request context.
  • "core.LoggingLayer" -> LoggingLayer (Debug mode only) Logs HTTP request methods, paths, durations, and response codes.
  • "core.CacheDisableLayer" -> CacheDisableLayer (Debug mode only) Injects HTTP headers (Cache-Control, Pragma, Expires) to disable browser caching under local development.
  • "core.HtmxBoostLayer" -> HtmxBoostLayer Configures response headers for HTMX requests.
  • "core.EnvironmentLayer" -> EnvironmentLayer Sets up standard environment config context.

Core Views

Registered under:

  • "core.HomeView" -> views.View Resolves and displays the "core.HomePage" page component.

Core Pages

Registered under:

  • "core.HomePage" -> components.ShellBase The default home page visual layout scaffolding.

Core Routes

Registered under:

  • "core.HomeRoute" -> lariv.Route Maps the root path ("/") to render standard text content or the home page view.

Bundled Plugins

The framework includes a collection of bundled plugins supporting standard app capabilities:

Index

Constants

View Source
const (
	// DBTypeSqlite specifies GORM SQLite database configurations.
	DBTypeSqlite = DBType("Sqlite")
	// DBTypePostgres specifies GORM PostgreSQL database configurations.
	DBTypePostgres = DBType("Postgres")
)
View Source
const (
	// PluginTypeApp indicates standalone, self-contained plugins containing primary application business logic and models.
	PluginTypeApp = iota
	// PluginTypeAddon indicates plugins that will not get listed on the dashboard's app grid.
	PluginTypeAddon
	// PluginTypeService indicates plugins booting long-running processes (e.g. background queue workers, SSE connections).
	PluginTypeService
)

Variables

This section is empty.

Functions

func ContextWithApp added in v0.6.11

func ContextWithApp(ctx context.Context, app *App) context.Context

ContextWithApp returns a child context carrying the compiled App and its components.Catalog.

func CorePlugin

func CorePlugin(db *gorm.DB, config LarivConfig) registry.Pair[string, Plugin]

CorePlugin creates the framework core plugin configuration. It registers standard global middleware layers (e.g. database attachments, logging, caching controls, environment mappings) and hooks up default routing and landing page views.

func GetDbConn

func GetDbConn(config LarivConfig) (*gorm.DB, error)

GetDbConn opens and configures a GORM connection using the provided database configurations. It overrides default delete callbacks to enforce hard deletes (disabling soft deletes).

func GetPageView

func GetPageView(pageName string) *views.View

GetPageView initializes and returns a standard view controller wrapper views.View that resolves page layouts by name. PageLookup is rebound to the owning App during AppBuilder.Build.

func GooseVersionTableName

func GooseVersionTableName(registryKey string) string

GooseVersionTableName derives a database-safe schema version tracker table name for a plugin migration registry key. It maps plugin keys deterministically to clean snake_case table names (prefixed with "goose_migrations__") ensuring separate tables per plugin so that numeric migration versions can overlap across plugins.

Database Migrations Structure

In Lariv, database schema migrations are managed per plugin. To add migrations to a plugin:

1. Create a `migrations` folder inside your plugin directory structure. 2. Add SQL migration files inside the `migrations` directory following Goose's syntax structure:

-- 00001_create_users_table.sql
-- +goose Up
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) NOT NULL UNIQUE
);

-- +goose Down
DROP TABLE users;

3. Embed the migration files and register the filesystem on your Plugin configuration under the Migrations field:

//go:embed migrations/*.sql
var migrationFS embed.FS

// In your lariv.Plugin setup:
lariv.Plugin{
    Migrations: lariv.PluginStages(func() lariv.PluginFeatures[lariv.UsefulFilesystem] {
        return lariv.PluginFeatures[lariv.UsefulFilesystem]{
            Entries: []registry.Pair[string, lariv.UsefulFilesystem]{
                registry.NewPair("my_plugin", migrationFS),
            },
        }
    }),
}

func GrapesJSBlockCategoryString added in v0.6.11

func GrapesJSBlockCategoryString(label string) json.RawMessage

GrapesJSBlockCategoryString marshals a category label string.

func GrapesJSBlockContentJSON added in v0.6.11

func GrapesJSBlockContentJSON(v any) (json.RawMessage, error)

GrapesJSBlockContentJSON marshals a component-definition object for Content.

func GrapesJSBlockContentString added in v0.6.11

func GrapesJSBlockContentString(html string) json.RawMessage

GrapesJSBlockContentString marshals an HTML (or HTML+style) string for Content.

func GrapesJSBlockOnClickBool added in v0.6.11

func GrapesJSBlockOnClickBool(v bool) json.RawMessage

GrapesJSBlockOnClickBool marshals a boolean onClick value.

func GrapesJSBlockOnClickJS added in v0.6.11

func GrapesJSBlockOnClickJS(body string) json.RawMessage

GrapesJSBlockOnClickJS marshals a trusted JS function body for onClick. The body receives parameters block and editor when invoked in the builder.

func GrapesJSComponentIsComponentBool added in v0.6.11

func GrapesJSComponentIsComponentBool(v bool) json.RawMessage

GrapesJSComponentIsComponentBool marshals a boolean isComponent value.

func GrapesJSComponentIsComponentJS added in v0.6.11

func GrapesJSComponentIsComponentJS(body string) json.RawMessage

GrapesJSComponentIsComponentJS marshals a trusted JS function body for isComponent. The body receives parameter el when invoked in the builder.

func GrapesJSComponentIsComponentTag added in v0.6.11

func GrapesJSComponentIsComponentTag(tag string) json.RawMessage

GrapesJSComponentIsComponentTag returns an isComponent JS body that matches a tag name.

func GrapesJSComponentModelJSON added in v0.6.11

func GrapesJSComponentModelJSON(v any) (json.RawMessage, error)

GrapesJSComponentModelJSON marshals a model definition object.

func GrapesJSComponentMustModelJSON added in v0.6.11

func GrapesJSComponentMustModelJSON(v any) json.RawMessage

GrapesJSComponentMustModelJSON marshals a model definition or panics.

func GrapesJSComponentMustViewJSON added in v0.6.11

func GrapesJSComponentMustViewJSON(v any) json.RawMessage

GrapesJSComponentMustViewJSON marshals a view definition or panics.

func GrapesJSComponentViewJSON added in v0.6.11

func GrapesJSComponentViewJSON(v any) (json.RawMessage, error)

GrapesJSComponentViewJSON marshals a view definition object.

func GrapesJSTraitCreateInputJS added in v0.6.11

func GrapesJSTraitCreateInputJS(body string) json.RawMessage

GrapesJSTraitCreateInputJS marshals a trusted JS function body for createInput. The body receives a destructured props object ({ trait }) when invoked.

func GrapesJSTraitCreateLabelJS added in v0.6.11

func GrapesJSTraitCreateLabelJS(body string) json.RawMessage

GrapesJSTraitCreateLabelJS marshals a trusted JS function body for createLabel.

func GrapesJSTraitOnEventJS added in v0.6.11

func GrapesJSTraitOnEventJS(body string) json.RawMessage

GrapesJSTraitOnEventJS marshals a trusted JS function body for onEvent. The body receives a destructured props object ({ elInput, component, event }).

func GrapesJSTraitOnUpdateJS added in v0.6.11

func GrapesJSTraitOnUpdateJS(body string) json.RawMessage

GrapesJSTraitOnUpdateJS marshals a trusted JS function body for onUpdate. The body receives a destructured props object ({ elInput, component }).

func GrapesJSTraitTemplateInputJS added in v0.6.11

func GrapesJSTraitTemplateInputJS(body string) json.RawMessage

GrapesJSTraitTemplateInputJS marshals a trusted JS function body for templateInput.

func GrapesJSTraitTemplateInputString added in v0.6.11

func GrapesJSTraitTemplateInputString(html string) json.RawMessage

GrapesJSTraitTemplateInputString marshals a templateInput HTML string.

func MapSlice

func MapSlice[T any, R any](slice []T, mapper func(T) R) []R

MapSlice maps elements in a slice from type T to type R using a converter function.

func PluginStages

func PluginStages[T any](stage func() PluginFeatures[T]) []func() PluginFeatures[T]

PluginStages wraps a single feature callback as a one-element slice for Plugin fields.

func RedirectView

func RedirectView(urlGetter getters.Getter[string]) *views.View

RedirectView returns a specialized *views.View instance configured to perform client redirects to the URL resolved by urlGetter.

Use Cases:

  • Mapping base routes or landing URLs to dashboard landing folders (e.g. mapping "/" to "/dashboard/").

Example:

var HomeRoute = Route{
	Path:    "/",
	Handler: lariv.RedirectView(getters.Static("/dashboard/")),
}

func RoutePath

func RoutePath(name string, args map[string]getters.Getter[any]) getters.Getter[string]

RoutePath yields a Getter that resolves and interpolates path variables in a named route on the request's App.

Example:

pathGetter := RoutePath("user.profile", map[string]getters.Getter[any]{
	"id": getters.Static(42),
})
url, err := pathGetter(ctx) // Resolves to "/users/u/42/profile"

func StartServer

func StartServer(config LarivConfig) error

StartServer is deprecated. Use (*App).StartServer after AppBuilder.LoadConfigFromFile.

Types

type AdminPanel deprecated

type AdminPanel[T any] struct {
	SearchField string
	ListFields  []string
	Preload     []string
}

Deprecated: This struct is a Work in Progress (WIP) and should NOT be used.

func (AdminPanel[T]) Create

func (a AdminPanel[T]) Create(db *gorm.DB, values map[string]*string) error

func (AdminPanel[T]) EditableFields

func (a AdminPanel[T]) EditableFields() []string

func (AdminPanel[T]) ExportCSV

func (a AdminPanel[T]) ExportCSV(db *gorm.DB, path string) (int, error)

func (AdminPanel[T]) GetListFields

func (a AdminPanel[T]) GetListFields() []string

func (AdminPanel[T]) ImportCSV

func (a AdminPanel[T]) ImportCSV(db *gorm.DB, path string) (int, error)

func (AdminPanel[T]) IsAdminPanel

func (a AdminPanel[T]) IsAdminPanel() bool

func (AdminPanel[T]) List

func (a AdminPanel[T]) List(db *gorm.DB, page, pageSize int) ([]map[string]any, error)

func (AdminPanel[T]) ModelName

func (a AdminPanel[T]) ModelName() string

func (AdminPanel[T]) Save

func (a AdminPanel[T]) Save(db *gorm.DB, id string, values map[string]*string) error

type AdminPanelInterface deprecated

type AdminPanelInterface interface {
	IsAdminPanel() bool
	ModelName() string
	GetListFields() []string
	EditableFields() []string
	List(db *gorm.DB, page, pageSize int) ([]map[string]any, error)
	Save(db *gorm.DB, id string, values map[string]*string) error
	Create(db *gorm.DB, values map[string]*string) error
	ImportCSV(db *gorm.DB, path string) (int, error)
	ExportCSV(db *gorm.DB, path string) (int, error)
}

Deprecated: This interface is a Work in Progress (WIP) and should NOT be used.

type App added in v0.6.11

App is a sealed, immutable application catalog produced by AppBuilder.Build. It owns registries, config, DB, and the HTTP handler for one independent app instance.

func AppFromContext added in v0.6.11

func AppFromContext(ctx context.Context) (*App, bool)

AppFromContext returns the App stored by ContextWithApp, if any.

func MustAppFromContext added in v0.6.11

func MustAppFromContext(ctx context.Context) *App

MustAppFromContext returns the App from ctx or panics.

func (*App) Handler added in v0.6.11

func (a *App) Handler() http.Handler

Handler returns the fully wrapped HTTP handler (App context, global layers, CORS, router).

func (*App) HeadNodes added in v0.6.11

func (a *App) HeadNodes() []components.PageInterface

HeadNodes implements components.Catalog.

func (*App) InitDB added in v0.6.11

func (a *App) InitDB() error

InitDB runs migrations and DB init hooks for this App.

func (*App) Page added in v0.6.11

func (a *App) Page(name string) (components.PageInterface, bool)

Page implements components.Catalog.

func (*App) PageView added in v0.6.11

func (a *App) PageView(pageName string) *views.View

PageView returns a views.View that resolves pages from this App's page catalog.

func (*App) RightSidebarItems added in v0.6.11

func (a *App) RightSidebarItems() []components.NamedSidebarItem

RightSidebarItems implements components.Catalog.

func (*App) Route added in v0.6.11

func (a *App) Route(name string) (Route, bool)

Route looks up a named route.

func (*App) Router added in v0.6.11

func (a *App) Router() *http.ServeMux

Router builds the ServeMux from this App's routes (and optional pprof endpoints).

func (*App) RunGenerators added in v0.6.11

func (a *App) RunGenerators()

RunGenerators runs seed generators registered on this App.

func (*App) Start added in v0.6.11

func (a *App) Start() error

Start runs the Cobra CLI (HTTP server root, generate, plugin commands).

func (*App) StartServer added in v0.6.11

func (a *App) StartServer() error

StartServer listens for HTTP requests using this App's handler.

func (*App) TopbarItems added in v0.6.11

func (a *App) TopbarItems() []components.PageInterface

TopbarItems implements components.Catalog.

func (*App) View added in v0.6.11

func (a *App) View(name string) (*views.View, bool)

View looks up a named view.

type AppBuilder added in v0.6.11

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

AppBuilder accumulates plugin contributions and seals them into an App.

func NewBuilder added in v0.6.11

func NewBuilder() *AppBuilder

NewBuilder returns an empty AppBuilder.

func (*AppBuilder) AddPlugin added in v0.6.11

func (b *AppBuilder) AddPlugin(name string, p Plugin) *AppBuilder

AddPlugin appends a named plugin contribution.

func (*AppBuilder) AddPlugins added in v0.6.11

func (b *AppBuilder) AddPlugins(plugins []registry.Pair[string, Plugin]) *AppBuilder

AddPlugins appends multiple named plugin contributions.

func (*AppBuilder) Build added in v0.6.11

func (b *AppBuilder) Build() (*App, error)

Build seals plugin contributions into an immutable App. If db/config are zero, catalogs are still built (useful for tests); call AppBuilder.LoadConfigFromFile for full boot.

func (*AppBuilder) BuildWith added in v0.6.11

func (b *AppBuilder) BuildWith(config LarivConfig, db *gorm.DB) (*App, error)

BuildWith seals plugins including CorePlugin, using the provided config and DB (for tests).

func (*AppBuilder) LoadConfigFromFile added in v0.6.11

func (b *AppBuilder) LoadConfigFromFile(path string) (*App, error)

LoadConfigFromFile decodes TOML config, opens the DB, seals catalogs (with CorePlugin), runs PostConfig hooks, and initializes the database.

func (*AppBuilder) PatchHead added in v0.6.11

func (b *AppBuilder) PatchHead(name string, patch func(components.PageInterface) components.PageInterface) *AppBuilder

PatchHead registers a patch for a shell head node.

func (*AppBuilder) RegisterAdmin added in v0.6.11

func (b *AppBuilder) RegisterAdmin(name string, panel AdminPanelInterface) *AppBuilder

RegisterAdmin registers an admin panel on the builder.

func (*AppBuilder) RegisterHead added in v0.6.11

func (b *AppBuilder) RegisterHead(name string, node components.PageInterface) *AppBuilder

RegisterHead registers a shell head node on the builder.

func (*AppBuilder) RegisterRightSidebar added in v0.6.11

func (b *AppBuilder) RegisterRightSidebar(name string, item components.SidebarItem) *AppBuilder

RegisterRightSidebar registers a right-sidebar item on the builder.

func (*AppBuilder) RegisterTopbar added in v0.6.11

func (b *AppBuilder) RegisterTopbar(name string, node components.PageInterface) *AppBuilder

RegisterTopbar registers a topbar item on the builder.

type CacheDisableLayer

type CacheDisableLayer struct{}

func (CacheDisableLayer) Next

type CommandFactory

type CommandFactory func(LarivConfig) *cobra.Command

CommandFactory represents a generator function that builds Cobra CLI commands mapped to a specific LarivConfig.

Use Cases:

  • Defining custom CLI sub-commands inside application plugins (e.g., system diagnostics, database cleaner tasks).

Example:

var BackupCmdFactory CommandFactory = func(config LarivConfig) *cobra.Command {
	return &cobra.Command{
		Use:   "backup",
		Short: "Executes a database schema backup",
		Run: func(cmd *cobra.Command, args []string) {
			executeBackup(config)
		},
	}
}

// Register the command factory inside your lariv.Plugin configuration:
lariv.Plugin{
	CommandFactories: lariv.PluginStages(func() PluginFeatures[CommandFactory] {
		return PluginFeatures[CommandFactory]{
			Entries: []registry.Pair[string, CommandFactory]{
				registry.NewPair("backup_db", BackupCmdFactory),
			},
		}
	}),
}

type Config

type Config interface {
	// PostConfig executes sanity checks and assigns default values after TOML values are loaded.
	PostConfig()
}

Config defines the interface implemented by plugin config structs to receive and validate parsed settings from TOML files. PostConfig is executed automatically after settings are mapped, enabling validation or setting default values.

Use Cases:

  • Defining configuration tables for plugins (e.g. storage paths, API client secrets).

Example Definition:

type DashboardConfig struct {
	AppName string
}

func (c *DashboardConfig) PostConfig() {
	if c.AppName == "" {
		c.AppName = "My Dashboard App"
	}
}

Example Registration:

var DashboardConfigPtr = &DashboardConfig{}

// Register the config instance inside your lariv.Plugin configuration:
lariv.Plugin{
	Configs: lariv.PluginStages(func() PluginFeatures[Config] {
		return PluginFeatures[Config]{
			Entries: []registry.Pair[string, Config]{
				registry.NewPair("dashboard", DashboardConfigPtr),
			},
		}
	}),
}

type DBInitHook

type DBInitHook func(*gorm.DB) *gorm.DB

DBInitHook represents a hook function executed after core database setup is complete (migrations, default callbacks). Hooks are executed in registration order and receive the active *gorm.DB instance, returning a decorated/modified *gorm.DB client.

Use Cases:

  • Configuring connection pool properties (e.g., setting maximum connections).
  • Triggering initial auto-migrations for non-plugin core tables.
  • Running database logging configurations or starting background cron workers with database handles.

Example Definition:

var ConnPoolHook DBInitHook = func(db *gorm.DB) *gorm.DB {
	sqlDB, err := db.DB()
	if err == nil {
		sqlDB.SetMaxOpenConns(20)
	}
	return db
}

Example Registration:

// In your lariv.Plugin setup:
lariv.Plugin{
	DBInitHooks: lariv.PluginStages(func() PluginFeatures[DBInitHook] {
		return PluginFeatures[DBInitHook]{
			Entries: []registry.Pair[string, DBInitHook]{
				registry.NewPair("conn_pool", ConnPoolHook),
			},
		}
	}),
}

Example Patch:

// Register a patch to chain or decorate existing DBInitHooks from another plugin:
lariv.Plugin{
	DBInitHooks: lariv.PluginStages(func() PluginFeatures[DBInitHook] {
		return PluginFeatures[DBInitHook]{
			Patches: []registry.Pair[string, func(DBInitHook) DBInitHook]{
				registry.NewPair("conn_pool", func(existing DBInitHook) DBInitHook {
					return func(db *gorm.DB) *gorm.DB {
						db = existing(db)
						// Chain extra configurations:
						return db.Debug()
					}
				}),
			},
		}
	}),
}

type DBLayer

type DBLayer struct {
	DB *gorm.DB
}

func (DBLayer) Next

func (m DBLayer) Next(next http.Handler) http.Handler

type DBType

type DBType string

DBType represents the configuration database engine driver selector.

type DynamicPage

type DynamicPage struct {
	components.Page
	// Name represents the registered string identifier of the target page component to fetch (e.g. "admin.Dashboard").
	Name string
}

DynamicPage lazily resolves page elements by string identifiers from the compiled App catalog at build/render time. This decouples component registrations, avoiding import-time dependency loops between modular plugins.

func (DynamicPage) Build

func (d DynamicPage) Build(cat components.Catalog, ctx context.Context, w io.Writer) error

Build compiles the dynamic component by rendering the lazy resolved page from cat.

func (DynamicPage) GetChildren

func (d DynamicPage) GetChildren() []components.PageInterface

GetChildren resolves the lazy target page from the catalog and returns it in a slice. Without a catalog argument this returns nil; prefer Build for rendering.

func (DynamicPage) GetKey

func (d DynamicPage) GetKey() string

GetKey returns the unique key identifier for this DynamicPage component.

func (DynamicPage) GetRoles

func (d DynamicPage) GetRoles() []string

GetRoles returns the authorized roles required to view this DynamicPage.

type DynamicView

type DynamicView struct {
	// Key represents the registered identifier of the view controller (e.g., "core.HomeView").
	Key string
}

DynamicView represents an HTTP handler that lazily resolves and executes a target view from the request's App. This resolves import-cycle constraints between routing endpoints and view logic blocks.

Use Cases:

  • Delegating routing mappings to plugins without statically importing the views controllers.

Example Definition:

var HomeHandler = lariv.NewDynamicView("core.HomeView")

func NewDynamicView

func NewDynamicView(key string) DynamicView

NewDynamicView constructs a new DynamicView handler targeting the specified view key.

func (DynamicView) ServeHTTP

func (v DynamicView) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP satisfies the standard http.Handler interface, executing the resolved view handler.

type EnvironmentLayer

type EnvironmentLayer struct{}

func (EnvironmentLayer) Next

type Generator

type Generator struct {
	// Create populates database tables with mock data records.
	Create func(*gorm.DB) error
	// Remove cleans up database tables to undo mock population.
	Remove func(*gorm.DB) error
}

Generator defines creation and deletion functions executed during database seeding/data generating commands.

Use Cases:

  • Seeding development or test databases with mock tables data (e.g. creating dummy administrator accounts, catalog samples).

Example Definition:

var ProductGen = Generator{
	Create: func(db *gorm.DB) error {
		return db.Create(&Product{Name: "Mock Item"}).Error
	},
	Remove: func(db *gorm.DB) error {
		return db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&Product{}).Error
	},
}

Example Registration:

// In your lariv.Plugin setup:
lariv.Plugin{
	Generators: lariv.PluginStages(func() PluginFeatures[Generator] {
		return PluginFeatures[Generator]{
			Entries: []registry.Pair[string, Generator]{
				registry.NewPair("products_seeder", ProductGen),
			},
		}
	}),
}

Example Patch:

// Register a patch to chain or modify database seeders from another plugin:
lariv.Plugin{
	Generators: lariv.PluginStages(func() PluginFeatures[Generator] {
		return PluginFeatures[Generator]{
			Patches: []registry.Pair[string, func(Generator) Generator]{
				registry.NewPair("products_seeder", func(existing Generator) Generator {
					return Generator{
						Create: func(db *gorm.DB) error {
							if err := existing.Create(db); err != nil {
								return err
							}
							// Add extra seeder child data:
							return db.Create(&Tag{Name: "Hot"}).Error
						},
						Remove: existing.Remove,
					}
				}),
			},
		}
	}),
}

type GrapesJSBlock added in v0.6.11

type GrapesJSBlock struct {
	Label      string          `json:"label"`
	Content    json.RawMessage `json:"content"`
	Media      string          `json:"media,omitempty"`
	Category   json.RawMessage `json:"category,omitempty"`
	Attributes map[string]any  `json:"attributes,omitempty"`
	Activate   bool            `json:"activate,omitempty"`
	Select     bool            `json:"select,omitempty"`
	Disable    bool            `json:"disable,omitempty"`
	OnClick    json.RawMessage `json:"onClick,omitempty"`
}

GrapesJSBlock is the props object passed as the second argument to GrapesJS BlockManager.add(id, props). The registry entry Key is the block id.

Content, Category, and OnClick use json.RawMessage so plugins can supply either a JSON string or an object (or, for OnClick, a boolean or JS function-body string).

type GrapesJSComponent added in v0.6.11

type GrapesJSComponent struct {
	Extend      string          `json:"extend,omitempty"`
	IsComponent json.RawMessage `json:"isComponent,omitempty"`
	Model       json.RawMessage `json:"model,omitempty"`
	View        json.RawMessage `json:"view,omitempty"`
}

GrapesJSComponent is the props object passed as the second argument to GrapesJS DomComponents.addType(id, props). The registry entry Key is the type id.

IsComponent, Model, and View use json.RawMessage so plugins can supply JSON objects/bools or trusted JS function-body strings (revived in the builder).

type GrapesJSTheme added in v0.6.11

type GrapesJSTheme struct {
	// Label is the human-readable name shown in theme selectors.
	Label string `json:"label"`
	// CSS is the theme stylesheet body injected into the builder canvas and published HTML.
	CSS string `json:"css"`
	// Stylesheets are optional external stylesheet URLs (fonts, etc.) loaded with the theme.
	Stylesheets []string `json:"stylesheets,omitempty"`
}

GrapesJSTheme is a named CSS theme for the website page builder and published pages. The registry entry Key is the theme id stored on routes (e.g. "p_website.default").

type GrapesJSTrait added in v0.6.11

type GrapesJSTrait struct {
	NoLabel       bool            `json:"noLabel,omitempty"`
	EventCapture  []string        `json:"eventCapture,omitempty"`
	TemplateInput json.RawMessage `json:"templateInput,omitempty"`
	CreateInput   json.RawMessage `json:"createInput,omitempty"`
	CreateLabel   json.RawMessage `json:"createLabel,omitempty"`
	OnEvent       json.RawMessage `json:"onEvent,omitempty"`
	OnUpdate      json.RawMessage `json:"onUpdate,omitempty"`
}

GrapesJSTrait is the props object passed as the second argument to GrapesJS Traits.addType(id, props). The registry entry Key is the trait type id.

TemplateInput, CreateInput, CreateLabel, OnEvent, and OnUpdate use json.RawMessage so plugins can supply JSON strings/objects or trusted JS function-body strings (revived in the builder).

type HtmxBoostLayer

type HtmxBoostLayer struct{}

func (HtmxBoostLayer) Next

func (HtmxBoostLayer) Next(next http.Handler) http.Handler

type LarivConfig

type LarivConfig struct {
	// Debug enables verbose debug level outputs and diagnostics.
	Debug bool
	// DBType specifies the database driver engine type (e.g. Postgres, Sqlite).
	DBType DBType
	// SqliteConfig represents driver parameters for SQLite DB files.
	SqliteConfig *sqlite.Config
	// PostgresConfig represents connection parameters for PostgreSQL connections.
	PostgresConfig *postgres.Config
	// Address represents the TCP bind address (e.g. ":8080").
	Address string
	// UDS represents the Unix Domain Socket path to bind to (overrides Address if specified).
	UDS string
	// GeneratorOrder specifies the sequence of db seeder names to run during seed execution.
	GeneratorOrder []string
	// TrustedOrigins lists the allowed CORS request origin hosts.
	TrustedOrigins []string
	// Plugins maps raw TOML configuration sections to specific plugin config structures.
	Plugins map[string]toml.Primitive
}

LarivConfig represents the top-level configuration structure mapped from TOML files. It carries connection details, database setups, UDS paths, CORS trusted origins, and plugin parameters.

func LoadConfigFromFile

func LoadConfigFromFile(path string, plugins []registry.Pair[string, Plugin]) (LarivConfig, error)

LoadConfigFromFile decodes a TOML configuration file via AppBuilder and returns the config. Prefer NewBuilder().AddPlugins(plugins).LoadConfigFromFile(path) to retain the *App.

type LoggingLayer

type LoggingLayer struct{}

func (LoggingLayer) Next

func (LoggingLayer) Next(next http.Handler) http.Handler

type PageURL

type PageURL struct {
	// URL embeds standard url.URL structures.
	url.URL
}

PageURL represents a GORM-compatible database-persisted URL wrapper. It embeds standard Go url.URL allowing callers to directly access standard URL fields and methods (e.g. url.URL.String).

Use Cases:

  • Storing web resources urls (e.g. avatar images, callback webhooks, external client logins) in database models.

Example:

type ClientApp struct {
	gorm.Model
	Homepage lariv.PageURL
}

func (PageURL) MarshalText

func (p PageURL) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler to serialize URL objects to byte strings.

func (*PageURL) Scan

func (p *PageURL) Scan(value any) error

Scan implements the SQL Scanner interface to populate URL properties from database columns.

func (*PageURL) SetFromURL

func (p *PageURL) SetFromURL(u *url.URL)

SetFromURL overrides the embedded URL properties using fields from the provided *url.URL object. Providing nil clears the url properties to zero.

func (*PageURL) URLPtr

func (p *PageURL) URLPtr() *url.URL

URLPtr returns a pointer to a copy of the embedded URL (or nil if empty / invalid for use as *url.URL). URLPtr yields a standard url.URL pointer to a copy of the embedded URL structure. Returns nil if the URL Host string is empty or invalid.

func (*PageURL) UnmarshalText

func (p *PageURL) UnmarshalText(text []byte) error

UnmarshalText implements encoding.TextUnmarshaler to parse TOML configurations and form bindings.

func (PageURL) Value

func (p PageURL) Value() (driver.Value, error)

Value implements the database driver Valuer interface to save URL properties as database text strings.

type Plugin

type Plugin struct {
	// Type specifies the plugin classification.
	Type PluginType
	// Icon represents a CSS class or emoji string for UI representation.
	Icon string
	// URL represents the primary entry URL path pointing to the plugin landing page.
	URL *url.URL
	// VerboseName represents the user-friendly human readable label for the plugin.
	VerboseName string
	// Roles lists the authorized security roles allowed to interact with the plugin.
	Roles []string
	// Migrations defines embedded database schema update folders.
	Migrations []func() PluginFeatures[UsefulFilesystem]
	// Views defines views controllers to map request pipelines.
	Views []func() PluginFeatures[*views.View]
	// Routes maps endpoint strings to standard HTTP handlers.
	Routes []func() PluginFeatures[Route]
	// Pages registers HTML component page layout trees.
	Pages []func() PluginFeatures[components.PageInterface]
	// Models registers GORM schema models.
	Models []func() PluginFeatures[any]
	// Layers registers global request/response multiplexer middlewares.
	Layers []func() PluginFeatures[views.GlobalLayer]
	// Generators registers database mock seed handlers.
	Generators []func() PluginFeatures[Generator]
	// DBInitHooks registers GORM initialization hook decorators.
	DBInitHooks []func() PluginFeatures[DBInitHook]
	// Configs registers custom setting configurations structs.
	Configs []func() PluginFeatures[Config]
	// CommandFactories registers custom CLI commands generators.
	CommandFactories []func() PluginFeatures[CommandFactory]
	// HeadNodes registers tags contributed to the HTML document <head>.
	HeadNodes []func() PluginFeatures[components.PageInterface]
	// Topbar registers widgets contributed to the top navigation bar.
	Topbar []func() PluginFeatures[components.PageInterface]
	// RightSidebar registers items for the collapsible right drawer.
	RightSidebar []func() PluginFeatures[components.SidebarItem]
	// Admin registers TUI admin panels (WIP).
	Admin []func() PluginFeatures[AdminPanelInterface]
	// GrapesJSBlocks registers GrapesJS BlockManager blocks for the website page builder.
	GrapesJSBlocks []func() PluginFeatures[GrapesJSBlock]
	// GrapesJSComponents registers GrapesJS DomComponents types for the website page builder.
	GrapesJSComponents []func() PluginFeatures[GrapesJSComponent]
	// GrapesJSTraits registers GrapesJS Traits.addType definitions for the website page builder.
	GrapesJSTraits []func() PluginFeatures[GrapesJSTrait]
	// GrapesJSThemes registers CSS themes selectable per website route / builder session.
	GrapesJSThemes []func() PluginFeatures[GrapesJSTheme]
}

Plugin defines a collection of application features, CLI commands, database initializers, routing endpoints, configurations, and metadata components.

Use Cases:

  • Defining modular code boundaries to group related database tables, templates, middlewares, and views.

Example Definition:

var DashboardPlugin = lariv.Plugin{
	Type:        lariv.PluginTypeApp,
	VerboseName: "Dashboard",
	Pages: lariv.PluginStages(func() lariv.PluginFeatures[components.PageInterface] {
		return lariv.PluginFeatures[components.PageInterface]{
			Entries: []registry.Pair[string, components.PageInterface]{
				registry.NewPair("dashboard.home", DashboardHome{}),
			},
		}
	}),
}

type PluginFeatures

type PluginFeatures[T any] struct {
	// Entries represents the slice of new registry contributions to register.
	Entries []registry.Pair[string, T]
	// Patches represents the slice of modification rules targeting previously registered components with matching keys.
	Patches []registry.Pair[string, func(T) T]
}

PluginFeatures collects registry Entries and optional Patches for a specific feature type T. Patches are applied to registered entries with matching keys during registry builds.

func (*PluginFeatures[T]) Build

func (f *PluginFeatures[T]) Build() []registry.Pair[string, T]

Build returns registry pairs with patches applied in registration order. Patches must be pure and idempotent: they must not mutate their argument T in place, and applying the same patch again to its own output must yield an equivalent result. Registry assembly may invoke Build more than once while merging plugins.

func (PluginFeatures[T]) Merge

func (f PluginFeatures[T]) Merge(others ...PluginFeatures[T]) PluginFeatures[T]

Merge concatenates Entries and Patches. Order is preserved so patch application order stays deterministic.

type PluginType

type PluginType int

PluginType represents the classification of a Lariv plugin.

type RedirectLayer

type RedirectLayer struct {
	// URLGetter represents the dynamic URL target getter resolving to the redirection link.
	URLGetter getters.Getter[string]
}

RedirectLayer represents a view middleware layer that intercepts requests and performs a client redirect.

func (RedirectLayer) Next

func (m RedirectLayer) Next(_ *views.View, next http.Handler) http.Handler

Next wraps the down-chain HTTP handler with redirection interceptors.

type ResponseLoggerLayer

type ResponseLoggerLayer struct{}

func (ResponseLoggerLayer) Next

type ResponseWriterWrapper

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

ResponseWriterWrapper struct is used to log the response

func NewResponseWriterWrapper

func NewResponseWriterWrapper(w http.ResponseWriter) ResponseWriterWrapper

NewResponseWriterWrapper static function creates a wrapper for the http.ResponseWriter

func (ResponseWriterWrapper) Header

func (rww ResponseWriterWrapper) Header() http.Header

Header function overwrites the http.ResponseWriter Header() function

func (ResponseWriterWrapper) String

func (rww ResponseWriterWrapper) String() string

func (ResponseWriterWrapper) Write

func (rww ResponseWriterWrapper) Write(buf []byte) (int, error)

func (ResponseWriterWrapper) WriteHeader

func (rww ResponseWriterWrapper) WriteHeader(statusCode int)

WriteHeader function overwrites the http.ResponseWriter WriteHeader() function

type Route

type Route struct {
	// Path represents the ServeMux-compatible URL path pattern (e.g., "/users/u/{id}/").
	Path string
	// Handler represents the HTTP handler mapped to this route path.
	Handler http.Handler
}

Route represents a multiplexer-compatible HTTP routing entry.

Wildcard Path Guidelines

1. Wildcards (like `{id}`) must occupy a full path segment. Use `/users/u/{id}/` instead of `/users{id}/`. 2. Base paths should end with a trailing slash `/` before segment appends. 3. Sibling paths with fixed literals and wildcards under the same prefix should be disambiguated by adding an explicit sub-segment (e.g. `/users/roles/...` vs `/users/u/{id}/...`).

type UsefulFilesystem

type UsefulFilesystem interface {
	fs.FS
	fs.ReadDirFS
	fs.ReadFileFS
}

UsefulFilesystem represents a comprehensive filesystem interface combining basic reads, directory lists, and file retrieval capabilities. It embeds standard Go fs.FS, fs.ReadDirFS, and fs.ReadFileFS interfaces.

Use Cases:

  • Bundling embedded resource directories (e.g. database migration files, template directory pools) in plugin packages.

Example:

func LoadSqlMigrations(filesystem lariv.UsefulFilesystem) {
	entries, err := filesystem.ReadDir("migrations")
	// ... parse and run migrations ...
}

Directories

Path Synopsis
Package components provides reusable and interactive UI layout components, fields, inputs, and page scaffolds for the Lariv application framework, rendered with html/template.
Package components provides reusable and interactive UI layout components, fields, inputs, and page scaffolds for the Lariv application framework, rendered with html/template.
Package docs contains explanations and code examples for plugin-specific files in Lariv.
Package docs contains explanations and code examples for plugin-specific files in Lariv.
app
Package app contains explanations and code examples for the plugin app.go file in Lariv.
Package app contains explanations and code examples for the plugin app.go file in Lariv.
commands
Package commands contains explanations and code examples for plugin-specific CLI commands in Lariv.
Package commands contains explanations and code examples for plugin-specific CLI commands in Lariv.
components
Package components contains explanations and code examples for UI page components in Lariv.
Package components contains explanations and code examples for UI page components in Lariv.
config
Package config contains explanations and code examples for plugin configurations in Lariv.
Package config contains explanations and code examples for plugin configurations in Lariv.
layers
Package layers contains explanations and code examples for middleware request-handling layers in Lariv.
Package layers contains explanations and code examples for middleware request-handling layers in Lariv.
migrations
Package migrations contains explanations and code examples for database migrations in Lariv.
Package migrations contains explanations and code examples for database migrations in Lariv.
models
Package models contains explanations and code examples for database models in Lariv.
Package models contains explanations and code examples for database models in Lariv.
pages
Package pages contains explanations and code examples for pages in Lariv.
Package pages contains explanations and code examples for pages in Lariv.
querypatchers
Package querypatchers contains explanations and code examples for database query patchers in Lariv.
Package querypatchers contains explanations and code examples for database query patchers in Lariv.
quickstart
Package quickstart guides you through building a minimal Lariv plugin that renders "Hello, World!".
Package quickstart guides you through building a minimal Lariv plugin that renders "Hello, World!".
routes
Package routes contains explanations and code examples for HTTP routing in Lariv.
Package routes contains explanations and code examples for HTTP routing in Lariv.
views
Package views contains explanations and code examples for view controllers in Lariv.
Package views contains explanations and code examples for view controllers in Lariv.
Package fields provides custom datatype fields and structures for GORM database models persisting.
Package fields provides custom datatype fields and structures for GORM database models persisting.
Package getters defines the core Getter type and a suite of utility functions for fetching, transforming, and composing dynamic values.
Package getters defines the core Getter type and a suite of utility functions for fetching, transforming, and composing dynamic values.
plugins
p_blog
Package p_blog provides blog post management and hierarchical tagging capabilities for Lariv.
Package p_blog provides blog post management and hierarchical tagging capabilities for Lariv.
p_dashboard
Package p_dashboard implements the central launchpad, top bar navigation buttons, and theme toggling for the Lariv application portal.
Package p_dashboard implements the central launchpad, top bar navigation buttons, and theme toggling for the Lariv application portal.
p_export
Package p_export implements Excel spreadsheet (XLSX) creation and table export features for GORM models.
Package p_export implements Excel spreadsheet (XLSX) creation and table export features for GORM models.
p_filesystem
Package p_filesystem implements a virtual node (VNode) database filesystem for the Lariv framework.
Package p_filesystem implements a virtual node (VNode) database filesystem for the Lariv framework.
p_google_genai
Package p_google_genai implements Google Gemini GenAI client wrappers and dynamic schema generators.
Package p_google_genai implements Google Gemini GenAI client wrappers and dynamic schema generators.
p_livereloading
Package p_livereloading implements automated browser refresh / live reloading capabilities during local development.
Package p_livereloading implements automated browser refresh / live reloading capabilities during local development.
p_llm_assistant
Package p_llm_assistant implements an interactive LLM chat assistant powered by Gemini.
Package p_llm_assistant implements an interactive LLM chat assistant powered by Gemini.
p_no_signup
Package p_no_signup provides a module for disabling signup functionality and removing the signup button from the login page.
Package p_no_signup provides a module for disabling signup functionality and removing the signup button from the login page.
p_otp
Package p_otp implements one-time password (OTP) delivery and verification features for password recovery and multi-factor auth.
Package p_otp implements one-time password (OTP) delivery and verification features for password recovery and multi-factor auth.
p_pwa
Package p_pwa implements Progressive Web App (PWA) manifest compilation, service worker mapping, offline fallback pages, and Android asset links hosting.
Package p_pwa implements Progressive Web App (PWA) manifest compilation, service worker mapping, offline fallback pages, and Android asset links hosting.
p_users
Package p_users implements the user administration and authentication system for the Lariv framework.
Package p_users implements the user administration and authentication system for the Lariv framework.
p_website
Package p_website provides website routing configurations loaded from the database.
Package p_website provides website routing configurations loaded from the database.
Package registry provides a mechanism to store and modify objects.
Package registry provides a mechanism to store and modify objects.
Package syncmap provides a generic, thread-safe map implementation.
Package syncmap provides a generic, thread-safe map implementation.

Jump to

Keyboard shortcuts

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