diff --git a/.gitignore b/.gitignore
index f30e625..5292519 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
-logs/
-.idea/
\ No newline at end of file
+logs/
\ No newline at end of file
diff --git a/example/main.go b/example/main.go
new file mode 100644
index 0000000..949ba36
--- /dev/null
+++ b/example/main.go
@@ -0,0 +1,117 @@
+package main
+
+import (
+ "log/slog"
+
+ "ron"
+)
+
+type SomethingElements struct {
+ Name string
+ Description string
+}
+
+var elements = []SomethingElements{
+ {"element 1", "description 1"},
+ {"element 2", "description 2"},
+ {"element 3", "description 3"},
+ {"element 4", "description 4"},
+ {"element 5", "description 5"},
+ {"element 6", "description 6"},
+ {"element 7", "description 7"},
+ {"element 8", "description 8"},
+ {"element 9", "description 9"},
+ {"element 10", "description 10"},
+ {"element 11", "description 11"},
+ {"element 12", "description 12"},
+ {"element 13", "description 13"},
+ {"element 14", "description 14"},
+ {"element 15", "description 15"},
+ {"element 16", "description 16"},
+ {"element 17", "description 17"},
+ {"element 18", "description 18"},
+ {"element 19", "description 19"},
+ {"element 20", "description 20"},
+ {"element 21", "description 21"},
+ {"element 22", "description 22"},
+ {"element 23", "description 23"},
+ {"element 24", "description 24"},
+ {"element 25", "description 25"},
+ {"element 26", "description 26"},
+ {"element 27", "description 27"},
+ {"element 28", "description 28"},
+ {"element 29", "description 29"},
+ {"element 30", "description 30"},
+ {"element 31", "description 31"},
+ {"element 32", "description 32"},
+ {"element 33", "description 33"},
+ {"element 34", "description 34"},
+ {"element 35", "description 35"},
+ {"element 36", "description 36"},
+ {"element 37", "description 37"},
+ {"element 38", "description 38"},
+ {"element 39", "description 39"},
+ {"element 40", "description 40"},
+ {"element 41", "description 41"},
+ {"element 42", "description 42"},
+ {"element 43", "description 43"},
+ {"element 44", "description 44"},
+ {"element 45", "description 45"},
+ {"element 46", "description 46"},
+ {"element 47", "description 47"},
+ {"element 48", "description 48"},
+ {"element 49", "description 49"},
+}
+
+func main() {
+ r := ron.New(func(e *ron.Engine) {
+ e.LogLevel = slog.LevelDebug
+ })
+
+ htmlRender := ron.NewHTMLRender()
+ r.Render = htmlRender
+
+ r.Static("static", "static")
+
+ r.GET("/json", helloWorldJSON)
+ r.POST("/another", anotherHelloWorld)
+ r.GET("/html", helloWorldHTML)
+ r.GET("/component", componentHTML)
+
+ r.Run(":8080")
+}
+
+func helloWorld(c *ron.Context) {
+ slog.Info("Dummy info message")
+ c.W.Write([]byte("hello world"))
+}
+
+func anotherHelloWorld(c *ron.Context) {
+ c.W.Write([]byte("another hello world"))
+}
+
+func helloWorldJSON(c *ron.Context) {
+ c.JSON(200, ron.Data{"message": "hello world"})
+}
+
+func helloWorldHTML(c *ron.Context) {
+
+ pages := ron.Pages{
+ TotalElements: len(elements),
+ ElementsPerPage: 5,
+ }
+
+ pages.PaginationParams(c.R)
+ elementsPaginated := pages.PaginateArray(elements)
+
+ td := &ron.TemplateData{
+ Data: ron.Data{"title": "hello world", "message": "hello world from html", "elements": elementsPaginated},
+ Pages: pages,
+ }
+
+ c.HTML(200, "page.index.gohtml", td)
+}
+
+func componentHTML(c *ron.Context) {
+ c.HTML(200, "component.list.gohtml", nil)
+}
diff --git a/example/static/img/dummy.png b/example/static/img/dummy.png
new file mode 100644
index 0000000..885878c
Binary files /dev/null and b/example/static/img/dummy.png differ
diff --git a/example/templates/component.list.gohtml b/example/templates/component.list.gohtml
new file mode 100644
index 0000000..342f35f
--- /dev/null
+++ b/example/templates/component.list.gohtml
@@ -0,0 +1,4 @@
+
diff --git a/example/templates/page.index.gohtml b/example/templates/page.index.gohtml
new file mode 100644
index 0000000..f1eef8a
--- /dev/null
+++ b/example/templates/page.index.gohtml
@@ -0,0 +1,52 @@
+
+
+
+
+
+ {{ .Data.title }}
+
+
+
+
+
+
+{{ .Data.message }}
+
+{{ range .Data.elements }}
+
+
+ -
+ {{ .Name }}
+ {{ .Description }}
+
+
+
+{{ end }}
+
+{{ if not .Pages.HasPrevious }}
+primera página
+{{ else }}
+primera
+anterior
+{{ end }}
+
+{{ range .Pages.PageRange 5 }}
+{{ if .Active }}
+{{ .Number }}
+{{ else }}
+{{ .Number }}
+{{ end }}
+{{ end }}
+
+{{ if not .Pages.HasNext }}
+última página
+{{ else }}
+siguiente
+última
+{{ end }}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ron.go b/ron.go
index 75fcb78..aeea964 100644
--- a/ron.go
+++ b/ron.go
@@ -24,27 +24,10 @@ type (
E *Engine
}
- router struct {
- path string
- method string
- handler func(*Context)
- group *routerGroup
- }
-
- routerGroup struct {
- prefix string
- middlewares middlewareChain
- engine *Engine
- }
-
- middlewareChain []func(http.Handler) http.Handler
-
Engine struct {
- LogLevel slog.Level
- Render *Render
- mux *http.ServeMux
- middlewares middlewareChain
- router []router
+ mux *http.ServeMux
+ LogLevel slog.Level
+ Render *Render
}
)
@@ -70,32 +53,8 @@ func (e *Engine) apply(opts ...EngineOptions) *Engine {
return e
}
-func (e *Engine) applyMiddlewares(handler http.Handler) http.Handler {
- for i := len(e.middlewares) - 1; i >= 0; i-- {
- handler = e.middlewares[i](handler)
- }
- return handler
-}
-
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- handler := e.applyMiddlewares(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- for _, route := range e.router {
- if strings.HasPrefix(r.URL.Path, route.path) && r.Method == route.method {
- groupHandler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- route.handler(&Context{W: w, R: r, E: e})
- }))
- if route.group != nil {
- for i := len(route.group.middlewares) - 1; i >= 0; i-- {
- groupHandler = route.group.middlewares[i](groupHandler)
- }
- }
- groupHandler.ServeHTTP(w, r)
- return
- }
- }
- http.NotFound(w, r)
- }))
- handler.ServeHTTP(w, r)
+ e.handleRequest(w, r)
}
func (e *Engine) Run(addr string) error {
@@ -107,35 +66,24 @@ func (e *Engine) handleRequest(w http.ResponseWriter, r *http.Request) {
e.mux.ServeHTTP(w, r)
}
-func (e *Engine) USE(middleware ...func(http.Handler) http.Handler) {
- e.middlewares = append(e.middlewares, middleware...)
-}
-
func (e *Engine) GET(path string, handler func(*Context)) {
- e.router = append(e.router, router{path: path, method: http.MethodGet, handler: handler})
+ e.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodGet {
+ http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
+ return
+ }
+ handler(&Context{W: w, R: r, E: e})
+ })
}
func (e *Engine) POST(path string, handler func(*Context)) {
- e.router = append(e.router, router{path: path, method: http.MethodPost, handler: handler})
-}
-
-func (e *Engine) GROUP(prefix string) *routerGroup {
- return &routerGroup{
- prefix: prefix,
- engine: e,
- }
-}
-
-func (rg *routerGroup) USE(middleware ...func(http.Handler) http.Handler) {
- rg.middlewares = append(rg.middlewares, middleware...)
-}
-
-func (rg *routerGroup) GET(path string, handler func(*Context)) {
- rg.engine.router = append(rg.engine.router, router{path: rg.prefix + path, method: http.MethodGet, handler: handler, group: rg})
-}
-
-func (rg *routerGroup) POST(path string, handler func(*Context)) {
- rg.engine.router = append(rg.engine.router, router{path: rg.prefix + path, method: http.MethodPost, handler: handler, group: rg})
+ e.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
+ return
+ }
+ handler(&Context{W: w, R: r, E: e})
+ })
}
// Static serves static files from a specified directory, accessible through a defined URL path.
@@ -159,9 +107,7 @@ func (e *Engine) Static(path, dir string) {
}
fs := http.FileServer(http.Dir(dir))
- e.GET(path, func(c *Context) {
- http.StripPrefix(path, fs).ServeHTTP(c.W, c.R)
- })
+ e.mux.Handle(path, http.StripPrefix(path, fs))
slog.Info("Static files served", "path", path, "dir", dir)
}
diff --git a/ron_test.go b/ron_test.go
index 7b25e30..05593f1 100644
--- a/ron_test.go
+++ b/ron_test.go
@@ -10,14 +10,14 @@ import (
func Test_defaultEngine(t *testing.T) {
e := defaultEngine()
if e == nil {
- t.Error("Expected engine, Actual: nil")
+ t.Error("Expected Engine, Actual: nil")
}
}
func Test_New(t *testing.T) {
e := New()
if e == nil {
- t.Error("Expected engine, Actual: nil")
+ t.Error("Expected Engine, Actual: nil")
}
if e.Render != nil {
t.Error("No expected Renderer, Actual: Renderer")
@@ -88,96 +88,6 @@ func Test_POST(t *testing.T) {
}
}
-func Test_USE(t *testing.T) {
- e := New()
- e.USE(func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("MIDDLEWARE"))
- next.ServeHTTP(w, r)
- })
- })
- e.GET("/", func(c *Context) {
- c.W.WriteHeader(http.StatusOK)
- c.W.Write([]byte("GET"))
- })
-
- rr := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/", nil)
- e.ServeHTTP(rr, req)
-
- if status := rr.Code; status != http.StatusOK {
- t.Errorf("Expected status code: %d, Actual: %d", http.StatusOK, status)
- }
-
- if rr.Body.String() != "MIDDLEWAREGET" {
- t.Errorf("Expected: MIDDLEWAREGET, Actual: %s", rr.Body.String())
- }
-}
-
-func Test_GROUP(t *testing.T) {
- tests := []struct {
- method string
- path string
- expectedCode int
- expectedBody string
- }{
- {"GET", "/group/", http.StatusOK, "GET"},
- {"POST", "/group/", http.StatusOK, "POST"},
- }
-
- e := New()
- g := e.GROUP("/group")
- g.GET("/", func(c *Context) {
- c.W.WriteHeader(http.StatusOK)
- c.W.Write([]byte("GET"))
- })
- g.POST("/", func(c *Context) {
- c.W.WriteHeader(http.StatusOK)
- c.W.Write([]byte("POST"))
- })
-
- for _, tt := range tests {
- rr := httptest.NewRecorder()
- req, _ := http.NewRequest(tt.method, tt.path, nil)
- e.ServeHTTP(rr, req)
-
- if status := rr.Code; status != tt.expectedCode {
- t.Errorf("Expected status code: %d, Actual: %d", tt.expectedCode, status)
- }
-
- if rr.Body.String() != tt.expectedBody {
- t.Errorf("Expected: %s, Actual: %s", tt.expectedBody, rr.Body.String())
- }
- }
-}
-
-func Test_GROUPUSE(t *testing.T) {
- e := New()
- g := e.GROUP("/group")
- g.USE(func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("MIDDLEWARE"))
- next.ServeHTTP(w, r)
- })
- })
- g.GET("/", func(c *Context) {
- c.W.WriteHeader(http.StatusOK)
- c.W.Write([]byte("GET"))
- })
-
- rr := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/group/", nil)
- e.ServeHTTP(rr, req)
-
- if status := rr.Code; status != http.StatusOK {
- t.Errorf("Expected status code: %d, Actual: %d", http.StatusOK, status)
- }
-
- if rr.Body.String() != "MIDDLEWAREGET" {
- t.Errorf("Expected: MIDDLEWAREGET, Actual: %s", rr.Body.String())
- }
-}
-
func Test_Static(t *testing.T) {
os.Mkdir("assets", os.ModePerm)
f, _ := os.Create("assets/style.css")