phx

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Nov 21, 2023 License: MIT Imports: 24 Imported by: 0

README ΒΆ

🐦 Phx

A little, highly opinated framework to create complete web apps.

Demo:

package main

import (
	"littlecash/locale"
	"littlecash/static"
	"littlecash/views"
	"log"
	"net/http"
	"time"

	"github.com/deltegui/phx"
	"github.com/deltegui/phx/core"
	"github.com/deltegui/phx/cypher"
	"github.com/deltegui/phx/session"
)

func ParseAll(r *phx.Router) {
	r.Parse(views.DemoIndex, "index.html", "demo/index.html")
	r.Parse(views.Login, "layout.html", "account/layout.html", "account/login.html")
	r.Parse(views.Arr, "arr.html", "demo/arr.html")
	r.ShowAvailableTemplates()
}

func main() {
	r := phx.NewRouter()
	r.Bootstrap()
	r.Add(func() core.Cypher {
		csrfpass := "you can generate a password with the framework or let it be random"
		return cypher.NewWithPasswordAsString(csrfpass)
	})
	r.ShowAvailableBuilders()

	r.Use(phx.HttpLogMiddleware)

	r.UseStaticEmbedded(static.Files)
	r.UseTemplate(views.Files)
	r.AddDefaultTemplateFunctions()
	r.UseCsrf(15 * time.Minute)
	r.UseLocalization(locale.Files, locale.Shared, locale.Errors)
	r.UseSessionInMemory(1 * time.Hour)
	r.UseSessionAuthWithRedirection("/login")

	views.ParseAll(r)

	r.Get("/", func() phx.Handler {
		return func(ctx *phx.Context) {
			ctx.StringOK("Hola mundo desde aqui")
		}
	})
	r.Get("/demo", func() phx.Handler {
		return func(ctx *phx.Context) {
			ctx.Render(http.StatusOK, views.DemoIndex, struct{}{})
		}
	}, r.Authorize())
	r.Get("/change/:lang", func() phx.Handler {
		return func(ctx *phx.Context) {
			from := ctx.GetCurrentLanguage()
			to := ctx.GetUrlParam("lang")
			if len(to) == 0 {
				ctx.String(http.StatusBadRequest, "Nothing to change!")
				return
			}
			ctx.ChangeLanguage(to)
			ctx.StringOK("Changed from '%s' to '%s'", from, to)
		}
	})
	r.Post("/demo", func(hasher core.Hasher) phx.Handler {
		type f struct {
			Name     string `validate:"required,min=3,max=255"`
			Password string `validate:"required,min=3,max=255"`
		}
		return func(ctx *phx.Context) {
			var form f
			ctx.ParseForm(&form)
			errs := ctx.Validate(form)
			if errs != nil {
				ctx.RenderWithErrors(http.StatusBadRequest, views.DemoIndex, struct{}{}, errs)
				return
			}
			form.Password = hasher.Hash(form.Password)
			ctx.JsonOK(form)
		}
	}, r.Authorize())
	r.Get("/login", func() phx.Handler {
		return func(ctx *phx.Context) {
			ctx.RenderOK(views.Login, AccountViewModel{})
		}
	})
	r.Post("/login", func() phx.Handler {
		return func(ctx *phx.Context) {
			var vm AccountViewModel
			ctx.ParseForm(&vm)
			if errs := ctx.Validate(vm); errs != nil {
				log.Println("MAL")
				ctx.RenderWithErrors(http.StatusBadRequest, views.Login, vm, errs)
				return
			}
			ctx.CreateSessionCookie(session.User{
				Id:   0,
				Name: vm.Name,
				Role: core.RoleAdmin,
			})
			ctx.Redirect("/demo")
		}
	})
	r.Get("/logout", func() phx.Handler {
		return func(ctx *phx.Context) {
			ctx.DestroySession()
			ctx.Redirect("/login")
		}
	})

	r.Get("/arr", func() phx.Handler {
		return func(ctx *phx.Context) {
			ctx.RenderOK(views.Arr, nil)
		}
	})

	r.Post("/arr", func() phx.Handler {
		return func(ctx *phx.Context) {
			var names []string
			if err := ctx.ParseJson(&names); err != nil {
				ctx.String(http.StatusBadRequest, "Invalid JSON")
				return
			}
			log.Println("OK")
			ctx.JsonOK(names)
		}
	})

	phx.PrintLogoEmbedded(views.Files, "banner.txt")
	r.Run(":3000")
}

type AccountViewModel struct {
	Name           string `validate:"required,min=3,max=255"`
	ErrorMessage   string
	HaveBeenLogout bool
}

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func PrintLogo(logoFile string)

PrintLogo takes a file path and prints your fancy ascii logo. It will fail if your file is not found.

func PrintLogoEmbedded ΒΆ added in v0.0.42

func PrintLogoEmbedded(fs embed.FS, path string)

PrintLogo takes a embedded filesystem and file path and prints your fancy ascii logo. It will fail if your file is not found.

func Redirect ΒΆ

func Redirect(to string) func() Handler

Types ΒΆ

type Builder ΒΆ

type Builder interface{}

Builder is a function that expects anything and retuns the type that builds. The type cant be func() interface{} cause some errors appears in runtime. So it's represented as an interface.

type Context ΒΆ added in v0.0.15

type Context struct {
	Req *http.Request
	Res http.ResponseWriter
	// contains filtered or unexported fields
}

func (*Context) ChangeLanguage ΒΆ added in v0.0.25

func (ctx *Context) ChangeLanguage(to string)

func (*Context) CreateSessionCookie ΒΆ added in v0.0.28

func (r *Context) CreateSessionCookie(user session.User)

func (*Context) DestroySession ΒΆ added in v0.0.28

func (r *Context) DestroySession() error

func (*Context) GetCurrentLanguage ΒΆ added in v0.0.18

func (ctx *Context) GetCurrentLanguage() string

func (*Context) GetLocalizer ΒΆ added in v0.1.2

func (ctx *Context) GetLocalizer(file string) localizer.Localizer

func (*Context) GetQueryParam ΒΆ added in v0.0.45

func (ctx *Context) GetQueryParam(name string) string

func (*Context) GetUrlParam ΒΆ added in v0.0.45

func (ctx *Context) GetUrlParam(name string) string

func (*Context) GetUser ΒΆ added in v0.0.15

func (ctx *Context) GetUser() session.User

func (*Context) HaveSession ΒΆ added in v0.1.1

func (ctx *Context) HaveSession() bool

func (*Context) Json ΒΆ added in v0.0.15

func (ctx *Context) Json(status int, data interface{})

func (*Context) JsonOK ΒΆ added in v0.0.38

func (ctx *Context) JsonOK(data interface{})

func (*Context) Localize ΒΆ added in v0.1.1

func (ctx *Context) Localize(file, key string) string

func (*Context) LocalizeError ΒΆ added in v0.1.1

func (ctx *Context) LocalizeError(err core.UseCaseError) string

func (*Context) LocalizeWithoutShared ΒΆ added in v0.1.1

func (ctx *Context) LocalizeWithoutShared(file, key string) string

func (*Context) PaginationToVM ΒΆ added in v0.1.2

func (ctx *Context) PaginationToVM(pag pagination.Pagination) pagination.ViewModel

func (*Context) ParseForm ΒΆ added in v0.0.18

func (ctx *Context) ParseForm(dst interface{})

ParseForm parses req.Form and then serializes the form data to the dst struct using reflection. The form names should match to the 'html' tag or, if its not setted, to the field name. ParseForm only supports serializing data to one-depth structs. Example, using this struct as target:

type MyStruct struct {
		A bool,
		B int `html:"pagination.currentPage"`
}

And having this serialized form:

"A=false&pagination.currentPage=2"

Calling ParseForm like this (NOTE THAT A POINTER TO THE STRUCT IS BEING PASSED):

var s MyStruct phx.ParseForm(req, &s)

It will result to this fullfilled struct:

{ A = false, B: 2 }

The supported field types are: int, int8, int16, int32, int64, float32, float64, bool and string

func (*Context) ParseJson ΒΆ added in v0.0.26

func (ctx *Context) ParseJson(dst any) error

func (*Context) ReadSessionCookie ΒΆ added in v0.0.28

func (r *Context) ReadSessionCookie() (session.User, error)

func (*Context) Redirect ΒΆ added in v0.0.15

func (ctx *Context) Redirect(to string)

func (*Context) RedirectCode ΒΆ added in v0.0.18

func (ctx *Context) RedirectCode(to string, code int)

func (*Context) Render ΒΆ added in v0.0.15

func (ctx *Context) Render(status int, parsed string, vm interface{})

func (*Context) RenderOK ΒΆ added in v0.0.38

func (ctx *Context) RenderOK(parsed string, vm interface{})

func (*Context) RenderWithErrors ΒΆ added in v0.0.15

func (ctx *Context) RenderWithErrors(status int, parsed string, vm interface{}, formErrors map[string]string)

func (*Context) String ΒΆ added in v0.0.18

func (ctx *Context) String(status int, data string, a ...any)

func (*Context) StringOK ΒΆ added in v0.0.38

func (ctx *Context) StringOK(data string, a ...any)

func (*Context) Validate ΒΆ added in v0.0.25

func (ctx *Context) Validate(s any) map[string]string

type CorsConfig ΒΆ added in v0.0.15

type CorsConfig struct {
	AllowMethods string
	AllowOrigin  string
}

type Handler ΒΆ added in v0.0.15

type Handler func(c *Context)

func HttpLogMiddleware ΒΆ added in v0.0.35

func HttpLogMiddleware(next Handler) Handler

type Injector ΒΆ

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

Injector is an automated dependency injector inspired in Sping's DI. It will detect which builder to call using its return type. If the builder haver params, it will fullfill that params calling other builders that provides its types.

func NewInjector ΒΆ

func NewInjector() *Injector

NewInjector with default values

func (Injector) Add ΒΆ

func (injector Injector) Add(builder Builder)

Add a builder to the dependency injector.

func (Injector) CallBuilder ΒΆ

func (injector Injector) CallBuilder(builder Builder) interface{}

CallBuilder injecting all parameters with provided builders. If some parameter type cannot be found, it will panic

func (Injector) Get ΒΆ

func (injector Injector) Get(name interface{}) interface{}

Get returns a builded dependency

func (Injector) GetByType ΒΆ

func (injector Injector) GetByType(name reflect.Type) interface{}

GetByType returns a builded dependency identified by type

func (Injector) PopulateStruct ΒΆ

func (injector Injector) PopulateStruct(userStruct interface{})

PopulateStruct fills a struct with the implementations that the injector can create. Make sure you pass a reference and not a value

func (Injector) ResolveHandler ΒΆ

func (injector Injector) ResolveHandler(builder Builder) Handler

ResolveHandler created by a builder

func (Injector) ShowAvailableBuilders ΒΆ

func (injector Injector) ShowAvailableBuilders()

ShowAvailableBuilders prints all registered builders.

type Middleware ΒΆ

type Middleware func(Handler) Handler

type Router ΒΆ added in v0.0.15

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

func NewRouter ΒΆ added in v0.0.15

func NewRouter() *Router

func NewRouterFromOther ΒΆ added in v0.0.15

func NewRouterFromOther(r *Router) *Router

func (*Router) Add ΒΆ added in v0.0.15

func (r *Router) Add(builder Builder)

func (*Router) AddDefaultTemplateFunctions ΒΆ added in v0.0.15

func (r *Router) AddDefaultTemplateFunctions()

func (*Router) Admin ΒΆ added in v0.0.28

func (r *Router) Admin() Middleware

func (*Router) Authorize ΒΆ added in v0.0.28

func (r *Router) Authorize() Middleware

func (*Router) AuthorizeRoles ΒΆ added in v0.0.28

func (r *Router) AuthorizeRoles(roles []core.Role) Middleware

func (*Router) Bootstrap ΒΆ added in v0.0.15

func (r *Router) Bootstrap()

func (*Router) Delete ΒΆ added in v0.0.15

func (r *Router) Delete(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Get ΒΆ added in v0.0.15

func (r *Router) Get(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Handle ΒΆ added in v0.0.15

func (r *Router) Handle(method, pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Head ΒΆ added in v0.0.15

func (r *Router) Head(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Options ΒΆ added in v0.0.15

func (r *Router) Options(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Parse ΒΆ added in v0.0.15

func (r *Router) Parse(name, main string, patterns ...string)

func (*Router) ParsePartial ΒΆ added in v0.0.15

func (r *Router) ParsePartial(name string, patterns ...string)

func (*Router) Patch ΒΆ added in v0.0.15

func (r *Router) Patch(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) PopulateStruct ΒΆ added in v0.0.15

func (r *Router) PopulateStruct(s interface{})

func (*Router) Post ΒΆ added in v0.0.15

func (r *Router) Post(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Put ΒΆ added in v0.0.15

func (r *Router) Put(pattern string, builder Builder, middlewares ...Middleware)

func (Router) Run ΒΆ added in v0.0.15

func (r Router) Run(address string)

func (*Router) ShowAvailableBuilders ΒΆ added in v0.0.15

func (r *Router) ShowAvailableBuilders()

func (*Router) ShowAvailableTemplates ΒΆ added in v0.0.22

func (r *Router) ShowAvailableTemplates()

func (*Router) Trace ΒΆ added in v0.0.15

func (r *Router) Trace(pattern string, builder Builder, middlewares ...Middleware)

func (*Router) Use ΒΆ added in v0.0.15

func (r *Router) Use(middleware Middleware)

func (*Router) UseCors ΒΆ added in v0.0.19

func (r *Router) UseCors(methods, origin string)

func (*Router) UseCsrf ΒΆ added in v0.0.19

func (r *Router) UseCsrf(expires time.Duration)

func (*Router) UseLocalization ΒΆ added in v0.0.19

func (r *Router) UseLocalization(files embed.FS, sharedKey, errorsKey string)

func (*Router) UseSession ΒΆ added in v0.0.27

func (r *Router) UseSession(provider session.SessionStore, duration time.Duration)

func (*Router) UseSessionAuth ΒΆ added in v0.0.28

func (r *Router) UseSessionAuth()

func (*Router) UseSessionAuthWithRedirection ΒΆ added in v0.0.28

func (r *Router) UseSessionAuthWithRedirection(redirectUrl string)

func (*Router) UseSessionInMemory ΒΆ added in v0.0.27

func (r *Router) UseSessionInMemory(duration time.Duration)

func (*Router) UseSessionPostgres ΒΆ added in v0.0.27

func (r *Router) UseSessionPostgres(db *sqlx.DB, duration time.Duration)

func (*Router) UseStatic ΒΆ added in v0.0.19

func (r *Router) UseStatic(path string)

func (*Router) UseStaticEmbedded ΒΆ added in v0.0.42

func (r *Router) UseStaticEmbedded(fs embed.FS)

func (*Router) UseTemplate ΒΆ added in v0.0.19

func (r *Router) UseTemplate(fs embed.FS)

type ViewModel ΒΆ

type ViewModel struct {
	Model      interface{}
	Localizer  localizer.Localizer
	FormErrors map[string]string
	CsrfToken  string
}

func (ViewModel) GetFormError ΒΆ

func (vm ViewModel) GetFormError(key string) string

func (ViewModel) HaveFormError ΒΆ

func (vm ViewModel) HaveFormError(key string) bool

func (ViewModel) Localize ΒΆ

func (vm ViewModel) Localize(key string) string

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

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