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
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.sharkk.net/Sharkk/Sushi"
|
||||
"git.sharkk.net/Sharkk/Sushi/session"
|
||||
)
|
||||
import "git.sharkk.net/Sharkk/Sushi"
|
||||
|
||||
func main() {
|
||||
app := sushi.New()
|
||||
|
||||
// Initialize sessions
|
||||
session.InitSessions("sessions.json")
|
||||
sushi.InitSessions("sessions.json")
|
||||
|
||||
app.Get("/", func(ctx sushi.Ctx, params []any) {
|
||||
sushi.SendHTML(ctx, "<h1>Hello Sushi!</h1>")
|
||||
ctx.SendHTML("<h1>Hello Sushi!</h1>")
|
||||
})
|
||||
|
||||
app.Listen(":8080")
|
||||
@ -156,7 +153,7 @@ func main() {
|
||||
app := sushi.New()
|
||||
|
||||
// Initialize sessions
|
||||
session.InitSessions("sessions.json")
|
||||
sushi.InitSessions("sessions.json")
|
||||
|
||||
// Add session middleware
|
||||
app.Use(session.Middleware())
|
||||
@ -179,7 +176,7 @@ func main() {
|
||||
### 4. Login Handler
|
||||
|
||||
```go
|
||||
func loginHandler(ctx sushi.Ctx, params []string) {
|
||||
func loginHandler(ctx sushi.Ctx, params []any) {
|
||||
email := string(ctx.PostArgs().Peek("email"))
|
||||
password := string(ctx.PostArgs().Peek("password"))
|
||||
|
||||
@ -198,7 +195,7 @@ func loginHandler(ctx sushi.Ctx, params []string) {
|
||||
}
|
||||
|
||||
// Log the user in
|
||||
auth.Login(ctx, user.ID, user)
|
||||
ctx.Login(user.ID, user)
|
||||
|
||||
ctx.Redirect("/dashboard")
|
||||
}
|
||||
@ -207,17 +204,17 @@ func loginHandler(ctx sushi.Ctx, params []string) {
|
||||
### 5. Logout Handler
|
||||
|
||||
```go
|
||||
func logoutHandler(ctx sushi.Ctx, params []string) {
|
||||
auth.Logout(ctx)
|
||||
ctx.SendRedirect("/")
|
||||
func logoutHandler(ctx sushi.Ctx, params []any) {
|
||||
ctx.Logout()
|
||||
ctx.Redirect("/")
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Getting Current User
|
||||
|
||||
```go
|
||||
func dashboardHandler(ctx sushi.Ctx, params []string) {
|
||||
user := auth.GetCurrentUser(ctx).(*User)
|
||||
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
||||
user := ctx.GetCurrentUser().(*User)
|
||||
|
||||
html := fmt.Sprintf("<h1>Welcome, %s!</h1>", user.Username)
|
||||
ctx.SendHTML(html)
|
||||
@ -233,7 +230,7 @@ import "git.sharkk.net/Sharkk/Sushi/csrf"
|
||||
app.Use(csrf.Middleware())
|
||||
|
||||
// In your form template
|
||||
func loginPageHandler(ctx sushi.Ctx, params []string) {
|
||||
func loginPageHandler(ctx sushi.Ctx, params []any) {
|
||||
csrfField := csrf.CSRFHiddenField(ctx)
|
||||
|
||||
html := fmt.Sprintf(`
|
||||
@ -269,8 +266,8 @@ app.Get("/assets/*path", sushi.StaticEmbed(files))
|
||||
## Sessions
|
||||
|
||||
```go
|
||||
func someHandler(ctx sushi.Ctx, params []string) {
|
||||
sess := session.GetCurrentSession(ctx)
|
||||
func someHandler(ctx sushi.Ctx, params []any) {
|
||||
sess := ctx.GetCurrentSession()
|
||||
|
||||
// Set session data
|
||||
sess.Set("user_preference", "dark_mode")
|
||||
@ -341,7 +338,7 @@ func findUserByEmail(email string) *User {
|
||||
func main() {
|
||||
app := sushi.New()
|
||||
|
||||
session.InitSessions("sessions.json")
|
||||
sushi.InitSessions("sessions.json")
|
||||
app.Use(session.Middleware())
|
||||
app.Use(auth.Middleware(getUserByID))
|
||||
|
||||
@ -360,15 +357,15 @@ func main() {
|
||||
app.Listen(":8080")
|
||||
}
|
||||
|
||||
func homeHandler(ctx sushi.Ctx, params []string) {
|
||||
if auth.IsAuthenticated(ctx) {
|
||||
ctx.SendRedirect("/dashboard")
|
||||
func homeHandler(ctx sushi.Ctx, params []any) {
|
||||
if ctx.IsAuthenticated() {
|
||||
ctx.Redirect("/dashboard")
|
||||
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(`
|
||||
<form method="POST" action="/login">
|
||||
%s
|
||||
@ -376,32 +373,32 @@ func loginPageHandler(ctx sushi.Ctx, params []string) {
|
||||
<input type="password" name="password" placeholder="Password" required><br>
|
||||
<button type="submit">Login</button>
|
||||
</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"))
|
||||
pass := string(ctx.PostArgs().Peek("password"))
|
||||
|
||||
user := findUserByEmail(email)
|
||||
if user == nil {
|
||||
sushi.SendError(ctx, 401, "Invalid credentials")
|
||||
ctx.SendError(401, "Invalid credentials")
|
||||
return
|
||||
}
|
||||
|
||||
if valid, _ := password.VerifyPassword(pass, user.Password); !valid {
|
||||
sushi.SendError(ctx, 401, "Invalid credentials")
|
||||
ctx.SendError(401, "Invalid credentials")
|
||||
return
|
||||
}
|
||||
|
||||
auth.Login(ctx, user.ID, user)
|
||||
sushi.SendRedirect(ctx, "/dashboard")
|
||||
ctx.Login(user.ID, user)
|
||||
ctx.Redirect("/dashboard")
|
||||
}
|
||||
|
||||
func dashboardHandler(ctx sushi.Ctx, params []string) {
|
||||
user := auth.GetCurrentUser(ctx).(*User)
|
||||
func dashboardHandler(ctx sushi.Ctx, params []any) {
|
||||
user := ctx.GetCurrentUser().(*User)
|
||||
|
||||
html := fmt.Sprintf(`
|
||||
<h1>Welcome, %s!</h1>
|
||||
@ -409,13 +406,13 @@ func dashboardHandler(ctx sushi.Ctx, params []string) {
|
||||
%s
|
||||
<button type="submit">Logout</button>
|
||||
</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) {
|
||||
auth.Logout(ctx)
|
||||
sushi.SendRedirect(ctx, "/")
|
||||
func logoutHandler(ctx sushi.Ctx, params []any) {
|
||||
ctx.Logout()
|
||||
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