From d57557dc554d7967f35762830b2d35b0451f94b4 Mon Sep 17 00:00:00 2001 From: astaxie Date: Wed, 1 Jan 2014 17:57:57 +0800 Subject: [PATCH] add AutoRouterWithPrefix --- app.go | 8 ++++++++ beego.go | 20 +++++++++++++++++++- router.go | 39 ++++++++++++++++++++++++++++++++++++--- router_test.go | 12 ++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/app.go b/app.go index da18718e..f252367b 100644 --- a/app.go +++ b/app.go @@ -118,6 +118,14 @@ func (app *App) AutoRouter(c ControllerInterface) *App { return app } +// AutoRouterWithPrefix adds beego-defined controller handler with prefix. +// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page, +// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function. +func (app *App) AutoRouterWithPrefix(prefix string, c ControllerInterface) *App { + app.Handlers.AddAutoPrefix(prefix, c) + return app +} + // UrlFor creates a url with another registered controller handler with params. // The endpoint is formed as path.controller.name to defined the controller method which will run. // The values need key-pair data to assign into controller method. diff --git a/beego.go b/beego.go index b3ce46e1..fd61a942 100644 --- a/beego.go +++ b/beego.go @@ -50,6 +50,15 @@ func (gr GroupRouters) AddRouter(pattern string, c ControllerInterface, mappingM gr = append(gr, newRG) } +func (gr GroupRouters) AddAuto(c ControllerInterface) { + newRG := groupRouter{ + "", + c, + "", + } + gr = append(gr, newRG) +} + // AddGroupRouter with the prefix // it will register the router in BeeApp // the follow code is write in modules: @@ -62,7 +71,9 @@ func (gr GroupRouters) AddRouter(pattern string, c ControllerInterface, mappingM // AddRouterGroup("/admin", auth.GR) func AddGroupRouter(prefix string, groups GroupRouters) *App { for _, v := range groups { - if v.mappingMethods != "" { + if v.pattern == "" { + BeeApp.AutoRouterWithPrefix(prefix, v.controller) + } else if v.mappingMethods != "" { BeeApp.Router(prefix+v.pattern, v.controller, v.mappingMethods) } else { BeeApp.Router(prefix+v.pattern, v.controller) @@ -95,6 +106,13 @@ func AutoRouter(c ControllerInterface) *App { return BeeApp } +// AutoPrefix adds controller handler to BeeApp with prefix. +// it's same to App.AutoRouterWithPrefix. +func AutoPrefix(prefix string, c ControllerInterface) *App { + BeeApp.AutoRouterWithPrefix(prefix, c) + return BeeApp +} + // ErrorHandler registers http.HandlerFunc to each http err code string. // usage: // beego.ErrorHandler("404",NotFound) diff --git a/router.go b/router.go index 401fddbb..f7c92ce7 100644 --- a/router.go +++ b/router.go @@ -33,6 +33,14 @@ const ( var ( // supported http methods. HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head"} + // these beego.Controller's methods shouldn't reflect to AutoRouter + exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", + "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", + "ServeXml", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool", + "GetFloat", "GetFile", "SaveToFile", "StartSession", "SetSession", "GetSession", + "DelSession", "SessionRegenerateID", "DestroySession", "IsAjax", "GetSecureCookie", + "SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml", + "GetControllerAndAction"} ) type controllerInfo struct { @@ -221,8 +229,8 @@ func (p *ControllerRegistor) Add(pattern string, c ControllerInterface, mappingM // Add auto router to ControllerRegistor. // example beego.AddAuto(&MainContorlller{}), // MainController has method List and Page. -// visit the url /main/list to exec List function -// /main/page to exec Page function. +// visit the url /main/list to execute List function +// /main/page to execute Page function. func (p *ControllerRegistor) AddAuto(c ControllerInterface) { p.enableAuto = true reflectVal := reflect.ValueOf(c) @@ -235,7 +243,32 @@ func (p *ControllerRegistor) AddAuto(c ControllerInterface) { p.autoRouter[firstParam] = make(map[string]reflect.Type) } for i := 0; i < rt.NumMethod(); i++ { - p.autoRouter[firstParam][rt.Method(i).Name] = ct + if !utils.InSlice(rt.Method(i).Name, exceptMethod) { + p.autoRouter[firstParam][rt.Method(i).Name] = ct + } + } +} + +// Add auto router to ControllerRegistor with prefix. +// example beego.AddAutoPrefix("/admin",&MainContorlller{}), +// MainController has method List and Page. +// visit the url /admin/main/list to execute List function +// /admin/main/page to execute Page function. +func (p *ControllerRegistor) AddAutoPrefix(prefix string, c ControllerInterface) { + p.enableAuto = true + reflectVal := reflect.ValueOf(c) + rt := reflectVal.Type() + ct := reflect.Indirect(reflectVal).Type() + firstParam := strings.Trim(prefix, "/") + "/" + strings.ToLower(strings.TrimSuffix(ct.Name(), "Controller")) + if _, ok := p.autoRouter[firstParam]; ok { + return + } else { + p.autoRouter[firstParam] = make(map[string]reflect.Type) + } + for i := 0; i < rt.NumMethod(); i++ { + if !utils.InSlice(rt.Method(i).Name, exceptMethod) { + p.autoRouter[firstParam][rt.Method(i).Name] = ct + } } } diff --git a/router_test.go b/router_test.go index a79ab5b4..c1a7f213 100644 --- a/router_test.go +++ b/router_test.go @@ -198,3 +198,15 @@ func TestPrepare(t *testing.T) { t.Errorf(w.Body.String() + "user define func can't run") } } + +func TestAutoPrefix(t *testing.T) { + r, _ := http.NewRequest("GET", "/admin/test/list", nil) + w := httptest.NewRecorder() + + handler := NewControllerRegistor() + handler.AddAutoPrefix("/admin", &TestController{}) + handler.ServeHTTP(w, r) + if w.Body.String() != "i am list" { + t.Errorf("TestAutoPrefix can't run") + } +}