diff --git a/README.md b/README.md
index 09f94a7..84a866d 100644
--- a/README.md
+++ b/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, "
Hello Sushi!
")
+ ctx.SendHTML("Hello Sushi!
")
})
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("Welcome, %s!
", 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`Login`)
+ ctx.SendHTML(`Login`)
}
-func loginPageHandler(ctx sushi.Ctx, params []string) {
+func loginPageHandler(ctx sushi.Ctx, params []any) {
html := fmt.Sprintf(`
- `, 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(`
Welcome, %s!
@@ -409,13 +406,13 @@ func dashboardHandler(ctx sushi.Ctx, params []string) {
%s
- `, 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("/")
}
```
diff --git a/forms.go b/forms.go
new file mode 100644
index 0000000..b66522f
--- /dev/null
+++ b/forms.go
@@ -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
+}