From 8e9f3481508b3febf02e58151011730a7d5c6363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20P=C3=A9rez?= Date: Tue, 19 Nov 2024 20:14:15 +0100 Subject: [PATCH] Revert "add routes groups and middlewares capabilities" This reverts commit 13b2b3794ac0ace31e5848381da711d9f015dd57. --- .gitignore | 3 +- example/main.go | 117 ++++++++++++++++++++++++ example/static/img/dummy.png | Bin 0 -> 1785 bytes example/templates/component.list.gohtml | 4 + example/templates/page.index.gohtml | 52 +++++++++++ ron.go | 92 ++++--------------- ron_test.go | 94 +------------------ 7 files changed, 195 insertions(+), 167 deletions(-) create mode 100644 example/main.go create mode 100644 example/static/img/dummy.png create mode 100644 example/templates/component.list.gohtml create mode 100644 example/templates/page.index.gohtml 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 0000000000000000000000000000000000000000..885878ca0b06af9f79305c4ba33729187a048467 GIT binary patch literal 1785 zcmb_ci&qi`7iabPc?{E)pPCw4`#zcvtj$8Fi(2L*hp*5Ov~s- zcL4x^-9cyk5CFgq6aer^{=aq_JwH3_WEqV^cyOdYgTdI|-exkH0)arGP-rxo#l^** zo}T*p`i#T*UPhSNr88(E0ATU_qkcknvv2?a{+$`*cPjFyl6R^;;$Xl&@#UCXgAKr- z*ErjW@n7s7!(O;ID%u7!9lvyM3_LG07w=Qzx8}ZWXORmW?P#alB{xrIf4W_d*;r)C zlfi4(jamLNS?Fw8+nigjUOT%iUGl2dRSCipOWoTksnc(g>f(;il0D#(h)R%QyfCGP zD(rn7ix__93o}nudxfnNbyn!K6b>c16^Ew^@joQ3u6tP95KyqGymp>uzuStIiC=xa zsI(^34&_)1Ov7kxY89RIg+&gXBOl+uuU@v!L@-Jw{I?R)HwFU}V_I}^Ei_VtxszwJ z1F-=+HcAI4)mjt{fHqV}wYq?m&uY0h+NS5i;L@iro#D1qsr#v1i|N^}lhXb*2~vJJdLk}c=M*eb}}uU3s)!i`8;?Mb*f?b6ydPE z5ek=ZTSG1i4GaUVlAXb6+i$A6-2d0Au#l_yz6&SVrA^9l!GhS9*E>+mOTqR<4#uL( zK9o6P2b?_z+Yh;DmmxPz;R~5O2fuhNItU8OrhxT5+My}dhhE5k4W3Z+#VhjDbu{mIf>|zB_l|N-1$#@*rh$`CH{Xh3DV=lEDO0`qb` zF`P|Z=rpZD^+CKbq}Cc6L8;P!I)1=f*9itja==jJ3Mz`N{F!!NNT-3T>rS*WC(2J= zA#f&y-$y_W{te*=nTRM?NlhO~$oz$fqOuwll!A?cr?5HXJBA~}!JG`csptp6#V!n5 zRxlwbmwwKYB(hfkiEv5b(TH(Y$xOkdk4VM=dk#NQO4XSOSsVPa`7LeA-8O#33)ib9 z5lg)xBj&)+_C?flouMY`TWx2O!7+V^`~ybxk$GZyxxV z?{!BWBMw`w%u^8;4?~glI|SQQ8G7?GlK9HWR|8G5-)Fz87~K{=>+vndQWiB1dqXj;C%;Ep?wm zk}+A1;>o3F@|yZY8xQJQ0HIq%3B#!(;(ZxK`e2@2-jdQx-t3Nk?BmLAMy^(RMdeXS zr_>W2Uw+)dduxPgL4blhVr}CB+<7$LE6`n9x=WkQ_pHA49O7NPV8v%m!N))Q)P=a2 zcAA*|R-fRnY7`taMpi9gct6bD>@J8)9T|xBdR@qT+jZ=t+62?P^SkscUnD<6cT(*oultXki@h01|rEmZ{`n7wLA=461oGqT~~!^k{R z7K5u{4?Sz#^onbJag5BvffM*bi7lMT`V)u)CY_up4tWkRH$0*~;BeHcT&ck9^ z%wAWw&a(F_al|J)+be*Tuj!|h`ZBOPKn#Vu( e$|JXLugd=;Z;*eeU#;(Vcm59({$IHO literal 0 HcmV?d00001 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 @@ +
    +
  • elem1
  • +
  • elem2
  • +
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")