update readme, add form handlers for fluent parsing
This commit is contained in:
parent
0f59ba225a
commit
09f66cfaa4
71
README.md
71
README.md
@ -7,19 +7,16 @@ A fast, raw, tasty framework for simplifying basic web apps!
|
|||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "git.sharkk.net/Sharkk/Sushi"
|
||||||
"git.sharkk.net/Sharkk/Sushi"
|
|
||||||
"git.sharkk.net/Sharkk/Sushi/session"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := sushi.New()
|
app := sushi.New()
|
||||||
|
|
||||||
// Initialize sessions
|
// Initialize sessions
|
||||||
session.InitSessions("sessions.json")
|
sushi.InitSessions("sessions.json")
|
||||||
|
|
||||||
app.Get("/", func(ctx sushi.Ctx, params []any) {
|
app.Get("/", func(ctx sushi.Ctx, params []any) {
|
||||||
sushi.SendHTML(ctx, "<h1>Hello Sushi!</h1>")
|
ctx.SendHTML("<h1>Hello Sushi!</h1>")
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Listen(":8080")
|
app.Listen(":8080")
|
||||||
@ -156,7 +153,7 @@ func main() {
|
|||||||
app := sushi.New()
|
app := sushi.New()
|
||||||
|
|
||||||
// Initialize sessions
|
// Initialize sessions
|
||||||
session.InitSessions("sessions.json")
|
sushi.InitSessions("sessions.json")
|
||||||
|
|
||||||
// Add session middleware
|
// Add session middleware
|
||||||
app.Use(session.Middleware())
|
app.Use(session.Middleware())
|
||||||
@ -179,7 +176,7 @@ func main() {
|
|||||||
### 4. Login Handler
|
### 4. Login Handler
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func loginHandler(ctx sushi.Ctx, params []string) {
|
func loginHandler(ctx sushi.Ctx, params []any) {
|
||||||
email := string(ctx.PostArgs().Peek("email"))
|
email := string(ctx.PostArgs().Peek("email"))
|
||||||
password := string(ctx.PostArgs().Peek("password"))
|
password := string(ctx.PostArgs().Peek("password"))
|
||||||
|
|
||||||
@ -198,7 +195,7 @@ func loginHandler(ctx sushi.Ctx, params []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log the user in
|
// Log the user in
|
||||||
auth.Login(ctx, user.ID, user)
|
ctx.Login(user.ID, user)
|
||||||
|
|
||||||
ctx.Redirect("/dashboard")
|
ctx.Redirect("/dashboard")
|
||||||
}
|
}
|
||||||
@ -207,17 +204,17 @@ func loginHandler(ctx sushi.Ctx, params []string) {
|
|||||||
### 5. Logout Handler
|
### 5. Logout Handler
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func logoutHandler(ctx sushi.Ctx, params []string) {
|
func logoutHandler(ctx sushi.Ctx, params []any) {
|
||||||
auth.Logout(ctx)
|
ctx.Logout()
|
||||||
ctx.SendRedirect("/")
|
ctx.Redirect("/")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. Getting Current User
|
### 6. Getting Current User
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func dashboardHandler(ctx sushi.Ctx, params []string) {
|
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
||||||
user := auth.GetCurrentUser(ctx).(*User)
|
user := ctx.GetCurrentUser().(*User)
|
||||||
|
|
||||||
html := fmt.Sprintf("<h1>Welcome, %s!</h1>", user.Username)
|
html := fmt.Sprintf("<h1>Welcome, %s!</h1>", user.Username)
|
||||||
ctx.SendHTML(html)
|
ctx.SendHTML(html)
|
||||||
@ -233,7 +230,7 @@ import "git.sharkk.net/Sharkk/Sushi/csrf"
|
|||||||
app.Use(csrf.Middleware())
|
app.Use(csrf.Middleware())
|
||||||
|
|
||||||
// In your form template
|
// In your form template
|
||||||
func loginPageHandler(ctx sushi.Ctx, params []string) {
|
func loginPageHandler(ctx sushi.Ctx, params []any) {
|
||||||
csrfField := csrf.CSRFHiddenField(ctx)
|
csrfField := csrf.CSRFHiddenField(ctx)
|
||||||
|
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
@ -269,8 +266,8 @@ app.Get("/assets/*path", sushi.StaticEmbed(files))
|
|||||||
## Sessions
|
## Sessions
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func someHandler(ctx sushi.Ctx, params []string) {
|
func someHandler(ctx sushi.Ctx, params []any) {
|
||||||
sess := session.GetCurrentSession(ctx)
|
sess := ctx.GetCurrentSession()
|
||||||
|
|
||||||
// Set session data
|
// Set session data
|
||||||
sess.Set("user_preference", "dark_mode")
|
sess.Set("user_preference", "dark_mode")
|
||||||
@ -341,7 +338,7 @@ func findUserByEmail(email string) *User {
|
|||||||
func main() {
|
func main() {
|
||||||
app := sushi.New()
|
app := sushi.New()
|
||||||
|
|
||||||
session.InitSessions("sessions.json")
|
sushi.InitSessions("sessions.json")
|
||||||
app.Use(session.Middleware())
|
app.Use(session.Middleware())
|
||||||
app.Use(auth.Middleware(getUserByID))
|
app.Use(auth.Middleware(getUserByID))
|
||||||
|
|
||||||
@ -360,15 +357,15 @@ func main() {
|
|||||||
app.Listen(":8080")
|
app.Listen(":8080")
|
||||||
}
|
}
|
||||||
|
|
||||||
func homeHandler(ctx sushi.Ctx, params []string) {
|
func homeHandler(ctx sushi.Ctx, params []any) {
|
||||||
if auth.IsAuthenticated(ctx) {
|
if ctx.IsAuthenticated() {
|
||||||
ctx.SendRedirect("/dashboard")
|
ctx.Redirect("/dashboard")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.SendHTML(c`<a href="/login">Login</a>`)
|
ctx.SendHTML(`<a href="/login">Login</a>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginPageHandler(ctx sushi.Ctx, params []string) {
|
func loginPageHandler(ctx sushi.Ctx, params []any) {
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
<form method="POST" action="/login">
|
<form method="POST" action="/login">
|
||||||
%s
|
%s
|
||||||
@ -376,32 +373,32 @@ func loginPageHandler(ctx sushi.Ctx, params []string) {
|
|||||||
<input type="password" name="password" placeholder="Password" required><br>
|
<input type="password" name="password" placeholder="Password" required><br>
|
||||||
<button type="submit">Login</button>
|
<button type="submit">Login</button>
|
||||||
</form>
|
</form>
|
||||||
`, csrf.CSRFHiddenField(ctx))
|
`, csrf.HiddenField(ctx))
|
||||||
|
|
||||||
sushi.SendHTML(ctx, html)
|
ctx.SendHTML(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginHandler(ctx sushi.Ctx, params []string) {
|
func loginHandler(ctx sushi.Ctx, params []any) {
|
||||||
email := string(ctx.PostArgs().Peek("email"))
|
email := string(ctx.PostArgs().Peek("email"))
|
||||||
pass := string(ctx.PostArgs().Peek("password"))
|
pass := string(ctx.PostArgs().Peek("password"))
|
||||||
|
|
||||||
user := findUserByEmail(email)
|
user := findUserByEmail(email)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
sushi.SendError(ctx, 401, "Invalid credentials")
|
ctx.SendError(401, "Invalid credentials")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid, _ := password.VerifyPassword(pass, user.Password); !valid {
|
if valid, _ := password.VerifyPassword(pass, user.Password); !valid {
|
||||||
sushi.SendError(ctx, 401, "Invalid credentials")
|
ctx.SendError(401, "Invalid credentials")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
auth.Login(ctx, user.ID, user)
|
ctx.Login(user.ID, user)
|
||||||
sushi.SendRedirect(ctx, "/dashboard")
|
ctx.Redirect("/dashboard")
|
||||||
}
|
}
|
||||||
|
|
||||||
func dashboardHandler(ctx sushi.Ctx, params []string) {
|
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
||||||
user := auth.GetCurrentUser(ctx).(*User)
|
user := ctx.GetCurrentUser().(*User)
|
||||||
|
|
||||||
html := fmt.Sprintf(`
|
html := fmt.Sprintf(`
|
||||||
<h1>Welcome, %s!</h1>
|
<h1>Welcome, %s!</h1>
|
||||||
@ -409,13 +406,13 @@ func dashboardHandler(ctx sushi.Ctx, params []string) {
|
|||||||
%s
|
%s
|
||||||
<button type="submit">Logout</button>
|
<button type="submit">Logout</button>
|
||||||
</form>
|
</form>
|
||||||
`, user.Email, csrf.CSRFHiddenField(ctx))
|
`, user.Email, csrf.HiddenField(ctx))
|
||||||
|
|
||||||
sushi.SendHTML(ctx, html)
|
ctx.SendHTML(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
func logoutHandler(ctx sushi.Ctx, params []string) {
|
func logoutHandler(ctx sushi.Ctx, params []any) {
|
||||||
auth.Logout(ctx)
|
ctx.Logout()
|
||||||
sushi.SendRedirect(ctx, "/")
|
ctx.Redirect("/")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
110
forms.go
Normal file
110
forms.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package sushi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FormValue struct {
|
||||||
|
value string
|
||||||
|
exists bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form gets a form field for chaining
|
||||||
|
func (ctx Ctx) Form(key string) FormValue {
|
||||||
|
value := string(ctx.PostArgs().Peek(key))
|
||||||
|
exists := ctx.PostArgs().Has(key)
|
||||||
|
return FormValue{value: value, exists: exists}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the value as string
|
||||||
|
func (f FormValue) String() string {
|
||||||
|
return f.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringDefault returns string with default value
|
||||||
|
func (f FormValue) StringDefault(defaultValue string) string {
|
||||||
|
if f.value == "" {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
return f.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int returns the value as integer
|
||||||
|
func (f FormValue) Int() int {
|
||||||
|
if f.value == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if parsed, err := strconv.Atoi(f.value); err == nil {
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntDefault returns integer with default value
|
||||||
|
func (f FormValue) IntDefault(defaultValue int) int {
|
||||||
|
if f.value == "" {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
if parsed, err := strconv.Atoi(f.value); err == nil {
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float returns the value as float64
|
||||||
|
func (f FormValue) Float() float64 {
|
||||||
|
if f.value == "" {
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
if parsed, err := strconv.ParseFloat(f.value, 64); err == nil {
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// FloatDefault returns float64 with default value
|
||||||
|
func (f FormValue) FloatDefault(defaultValue float64) float64 {
|
||||||
|
if f.value == "" {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
if parsed, err := strconv.ParseFloat(f.value, 64); err == nil {
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool returns the value as boolean
|
||||||
|
func (f FormValue) Bool() bool {
|
||||||
|
value := strings.ToLower(f.value)
|
||||||
|
return value == "true" || value == "on" || value == "1" || value == "yes"
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolDefault returns boolean with default value
|
||||||
|
func (f FormValue) BoolDefault(defaultValue bool) bool {
|
||||||
|
if f.value == "" {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
return f.Bool()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exists returns true if the field was present in the form
|
||||||
|
func (f FormValue) Exists() bool {
|
||||||
|
return f.exists
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmpty returns true if the field is empty or doesn't exist
|
||||||
|
func (f FormValue) IsEmpty() bool {
|
||||||
|
return f.value == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFormArray gets multiple form values as string slice
|
||||||
|
func (ctx Ctx) GetFormArray(key string) []string {
|
||||||
|
var values []string
|
||||||
|
ctx.PostArgs().VisitAll(func(k, v []byte) {
|
||||||
|
if string(k) == key {
|
||||||
|
values = append(values, string(v))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return values
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user