gonertia

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2023 License: MIT Imports: 14 Imported by: 0

README

Inertia.js Go Adapter

This is a Inertia.js server-side adapter for Golang. Visit inertiajs.com to learn more.

Introdution

This package based on petaki/inertia-go, but with more striving for similarity inertia-laravel:

  • Middleware (redirect back if empty/303 redirect status for post/put/patch).
  • Lazy and closure props support.
  • Redirect with inertia.Location function works for inertia and non-inertia requests.
  • Template directives inertia and inertiaHead just like in inertia-laravel.
  • Asset versioning by asset url or manifest file.
  • Some other differences like testing coverage or more complex examples.

The purpose of developing this package is to implement all the functions that are available in the official Laravel package, as well as their maximum similar implementation.

Installation

Install using go get command:

go get github.com/romsar/gonertia

Usage

Basic example

main.go

package main

import (
    inertia "github.com/romsar/gonertia"
    "log"
    "http"
    "time"
)

func main() {
    i, err := inertia.New(
        "https://yourwebsite.com",
        "./root.html",
    )
    if err != nil {
        log.Fatal(err)
    }

    mux := http.NewServeMux()

    mux.Handle("/home", i.Middleware(homeHandler(i)))
}

func homeHandler(i *inertia.Inertia) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        props := inertia.Props{
            "some": "data",
        }
		
        if err := i.Render(w, r, "Index", props); err != nil {
           handleServerErr(w, err)
        }
    }

    return http.HandlerFunc(fn)
}

root.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>title</title>
    {{ .inertiaHead }}
</head>

<body>
{{ .inertia }}
<script src="/static/js/app.js"></script>
</body>
</html>
Load root template using embed
import "embed"

//go:embed templates
var templateFS embed.FS

// ...

i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithTemplateFS(templateFS),
)
With asset version
i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithVersion("some-version"),
)

or

i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithAssetURL("/static/js/1f0f8sc6.js"),
)

or

i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithManifestFile("./ui/manifest.json"),
)
With your marshal JSON function
i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithMarshalJSON(jsoniter.Marshal),
)
With your logger
i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithLogger(somelogger.New()),
)

or disable logging at all:

i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithoutLogger(),
)
With custom container id
i, err := inertia.New(
    "https://yourwebsite.com",
    "templates/root.html",
    inertia.WithContainerID("inertia"),
)
Closure and lazy props (learn more)
func homeHandler(i *inertia.Inertia) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        props := inertia.Props{
            "time": func () (any, error) { return time.Now().String(), nil },
            "lazy": inertia.LazyProp(func () (any, error) {
                return "lazy data", nil
            }),
        }
		
        if err := i.Render(w, r, "Index", props); err != nil {
           handleServerErr(w, err)
        }
    }

    return http.HandlerFunc(fn)
}
Redirects
func homeHandler(i *inertia.Inertia) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        i.Location(w, r, "/some-url")
    }

    return http.HandlerFunc(fn)
}

If response is empty - user will be redirected to the previous url.

Share template data
i, err := inertia.New(/* ... */)

i.ShareTemplateData("title", "Home page")
<title>{{ .title }}</title>
Share template func
i, err := inertia.New(/* ... */)

i.ShareTemplateFunc("trim", strings.Trim)
<title>{{ trim " foo bar " }}</title>
Share prop globally
i, err := inertia.New(/* ... */)

i.ShareProp("name", "Roman")
Pass template data via context (in middleware/handler)
ctx := i.WithTemplateData(r.Context(), "title", "Home page")

// pass it to the next middleware or inertia.Render function. 
Pass props via context (in middleware/handler)
ctx := i.WithProp(r.Context(), "name", "Roman")

// pass it to the next middleware or inertia.Render function. 

Roadmap

  • Validation errors
  • SSR

Documentation

Index

Constants

View Source
const (
	// TemplateDataContextKey is the context key for template data.
	TemplateDataContextKey = contextKey(iota + 1)

	// PropsContextKey is the context key for props.
	PropsContextKey
)

Variables

This section is empty.

Functions

func IsInertiaRequest

func IsInertiaRequest(r *http.Request) bool

IsInertiaRequest returns true if this request is Inertia request.

Types

type Inertia

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

Inertia is a structure that contain all logic of Inertia server adapter.

func New

func New(url, rootTemplatePath string, opts ...Option) (*Inertia, error)

New initializes and returns Inertia.

func (*Inertia) FlushSharedProps

func (i *Inertia) FlushSharedProps()

FlushSharedProps flushes shared props.

func (*Inertia) FlushSharedTemplateData

func (i *Inertia) FlushSharedTemplateData()

FlushSharedTemplateData flushes shared template data.

func (*Inertia) FlushSharedTemplateFunc

func (i *Inertia) FlushSharedTemplateFunc()

FlushSharedTemplateFunc flushes the shared template func map.

func (*Inertia) Location

func (i *Inertia) Location(w http.ResponseWriter, r *http.Request, url string, status ...int)

Location creates redirect response.

If request is Inertia request, it will set status to 409 and url will be in "X-Inertia-Location" header. Otherwise, it will do an HTTP redirect with specified status (default is 302).

func (*Inertia) Middleware

func (i *Inertia) Middleware(next http.Handler) http.Handler

Middleware returns http.Handler with Inertia support.

All of your handlers that need to be handled by the Inertia should be under this middleware.

func (*Inertia) Render

func (i *Inertia) Render(w http.ResponseWriter, r *http.Request, component string, props Props) (err error)

Render return response with Inertia data.

If request is Inertia request - it will return JSON. Otherwise, it will return root template.

func (*Inertia) ShareProp

func (i *Inertia) ShareProp(key string, val any)

ShareProp adds passed prop to shared props.

func (*Inertia) ShareTemplateData

func (i *Inertia) ShareTemplateData(key string, val any)

ShareTemplateData adds passed data to shared template data.

func (*Inertia) ShareTemplateFunc

func (i *Inertia) ShareTemplateFunc(key string, val any)

ShareTemplateFunc adds passed value to the shared template func map.

func (*Inertia) SharedProp

func (i *Inertia) SharedProp(key string) (any, bool)

SharedProp return the shared prop.

func (*Inertia) SharedProps

func (i *Inertia) SharedProps() Props

SharedProps returns shared props.

func (*Inertia) WithProp

func (i *Inertia) WithProp(ctx context.Context, key string, val any) context.Context

WithProp appends prop value to passed context.Context.

func (*Inertia) WithProps

func (i *Inertia) WithProps(ctx context.Context, props Props) context.Context

WithProps appends props values to passed context.Context.

func (*Inertia) WithTemplateData

func (i *Inertia) WithTemplateData(ctx context.Context, key string, val any) context.Context

WithTemplateData appends template data value to passed context.Context.

type LazyProp

type LazyProp func() (any, error)

LazyProp is a property value that will only evaluated then needed.

https://inertiajs.com/partial-reloads

type Option

type Option func(i *Inertia) error

Option is an option parameter that modifies Inertia.

func WithAssetURL

func WithAssetURL(url string) Option

WithAssetURL returns Option that will set Inertia's version based on asset url.

func WithContainerID

func WithContainerID(id string) Option

WithContainerID returns Option that will set Inertia's container id.

func WithLogger

func WithLogger(log logger) Option

WithLogger returns Option that will set Inertia's logger.

func WithManifestFile

func WithManifestFile(path string) Option

WithManifestFile returns Option that will set Inertia's version based on manifest file.

func WithMarshalJSON

func WithMarshalJSON(f marshallJSON) Option

WithMarshalJSON returns Option that will set Inertia's marshallJSON func.

func WithTemplateFS

func WithTemplateFS(templateFS fs.FS) Option

WithTemplateFS returns Option that will set Inertia's templateFS.

func WithVersion

func WithVersion(version string) Option

WithVersion returns Option that will set Inertia's version.

func WithoutLogger

func WithoutLogger() Option

WithoutLogger returns Option that will unset Inertia's logger. Actually set a logger with io.Discard output.

type Props

type Props map[string]any

Props are key-value data structure, that will be available in your front-end component.

type TemplateData

type TemplateData map[string]any

TemplateData is a map with values that will be available in the root template.

Jump to

Keyboard shortcuts

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