add util func to get the url fix #282
UrlFor(endpoint string, values ...string) string
Showing
6 changed files
with
157 additions
and
2 deletions
| ... | @@ -87,6 +87,9 @@ func (app *App) AutoRouter(c ControllerInterface) *App { | ... | @@ -87,6 +87,9 @@ func (app *App) AutoRouter(c ControllerInterface) *App { |
| 87 | return app | 87 | return app |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | func (app *App) UrlFor(endpoint string, values ...string) string { | ||
| 91 | return app.Handlers.UrlFor(endpoint, values...) | ||
| 92 | } | ||
| 90 | func (app *App) Filter(pattern, action string, filter FilterFunc) *App { | 93 | func (app *App) Filter(pattern, action string, filter FilterFunc) *App { |
| 91 | app.Handlers.AddFilter(pattern, action, filter) | 94 | app.Handlers.AddFilter(pattern, action, filter) |
| 92 | return app | 95 | return app | ... | ... |
| ... | @@ -16,6 +16,7 @@ import ( | ... | @@ -16,6 +16,7 @@ import ( |
| 16 | "net/http" | 16 | "net/http" |
| 17 | "net/url" | 17 | "net/url" |
| 18 | "os" | 18 | "os" |
| 19 | "reflect" | ||
| 19 | "strconv" | 20 | "strconv" |
| 20 | "strings" | 21 | "strings" |
| 21 | "time" | 22 | "time" |
| ... | @@ -175,6 +176,17 @@ func (c *Controller) Abort(code string) { | ... | @@ -175,6 +176,17 @@ func (c *Controller) Abort(code string) { |
| 175 | panic(code) | 176 | panic(code) |
| 176 | } | 177 | } |
| 177 | 178 | ||
| 179 | func (c *Controller) UrlFor(endpoint string, values ...string) string { | ||
| 180 | if len(endpoint) <= 0 { | ||
| 181 | return "" | ||
| 182 | } | ||
| 183 | if endpoint[0] == '.' { | ||
| 184 | return UrlFor(reflect.Indirect(reflect.ValueOf(c.AppController)).Type().Name()+endpoint, values...) | ||
| 185 | } else { | ||
| 186 | return UrlFor(endpoint, values...) | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 178 | func (c *Controller) ServeJson(encoding ...bool) { | 190 | func (c *Controller) ServeJson(encoding ...bool) { |
| 179 | var hasIndent bool | 191 | var hasIndent bool |
| 180 | var hasencoding bool | 192 | var hasencoding bool | ... | ... |
| ... | @@ -259,6 +259,121 @@ func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc | ... | @@ -259,6 +259,121 @@ func (p *ControllerRegistor) AddFilter(pattern, action string, filter FilterFunc |
| 259 | p.filters[action] = append(p.filters[action], mr) | 259 | p.filters[action] = append(p.filters[action], mr) |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | func (p *ControllerRegistor) UrlFor(endpoint string, values ...string) string { | ||
| 263 | paths := strings.Split(endpoint, ".") | ||
| 264 | if len(paths) <= 1 { | ||
| 265 | Warn("urlfor endpoint must like path.controller.method") | ||
| 266 | return "" | ||
| 267 | } | ||
| 268 | if len(values)%2 != 0 { | ||
| 269 | Warn("urlfor params must key-value pair") | ||
| 270 | return "" | ||
| 271 | } | ||
| 272 | urlv := url.Values{} | ||
| 273 | if len(values) > 0 { | ||
| 274 | key := "" | ||
| 275 | for k, v := range values { | ||
| 276 | if k%2 == 0 { | ||
| 277 | key = v | ||
| 278 | } else { | ||
| 279 | urlv.Set(key, v) | ||
| 280 | } | ||
| 281 | } | ||
| 282 | } | ||
| 283 | controllName := strings.Join(paths[:len(paths)-1], ".") | ||
| 284 | methodName := paths[len(paths)-1] | ||
| 285 | for _, route := range p.fixrouters { | ||
| 286 | if route.controllerType.Name() == controllName { | ||
| 287 | var finded bool | ||
| 288 | if inSlice(strings.ToLower(methodName), HTTPMETHOD) { | ||
| 289 | if route.hasMethod { | ||
| 290 | if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { | ||
| 291 | finded = false | ||
| 292 | } else if m, ok = route.methods["*"]; ok && m != methodName { | ||
| 293 | finded = false | ||
| 294 | } else { | ||
| 295 | finded = true | ||
| 296 | } | ||
| 297 | } else { | ||
| 298 | finded = true | ||
| 299 | } | ||
| 300 | } else if route.hasMethod { | ||
| 301 | for _, md := range route.methods { | ||
| 302 | if md == methodName { | ||
| 303 | finded = true | ||
| 304 | } | ||
| 305 | } | ||
| 306 | } | ||
| 307 | if !finded { | ||
| 308 | continue | ||
| 309 | } | ||
| 310 | if len(values) > 0 { | ||
| 311 | return route.pattern + "?" + urlv.Encode() | ||
| 312 | } | ||
| 313 | return route.pattern | ||
| 314 | } | ||
| 315 | } | ||
| 316 | for _, route := range p.routers { | ||
| 317 | if route.controllerType.Name() == controllName { | ||
| 318 | var finded bool | ||
| 319 | if inSlice(strings.ToLower(methodName), HTTPMETHOD) { | ||
| 320 | if route.hasMethod { | ||
| 321 | if m, ok := route.methods[strings.ToLower(methodName)]; ok && m != methodName { | ||
| 322 | finded = false | ||
| 323 | } else if m, ok = route.methods["*"]; ok && m != methodName { | ||
| 324 | finded = false | ||
| 325 | } else { | ||
| 326 | finded = true | ||
| 327 | } | ||
| 328 | } else { | ||
| 329 | finded = true | ||
| 330 | } | ||
| 331 | } else if route.hasMethod { | ||
| 332 | for _, md := range route.methods { | ||
| 333 | if md == methodName { | ||
| 334 | finded = true | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | if !finded { | ||
| 339 | continue | ||
| 340 | } | ||
| 341 | var returnurl string | ||
| 342 | var i int | ||
| 343 | var startreg bool | ||
| 344 | for _, v := range route.regex.String() { | ||
| 345 | if v == '(' { | ||
| 346 | startreg = true | ||
| 347 | continue | ||
| 348 | } else if v == ')' { | ||
| 349 | startreg = false | ||
| 350 | returnurl = returnurl + urlv.Get(route.params[i]) | ||
| 351 | i++ | ||
| 352 | } else if !startreg { | ||
| 353 | returnurl = string(append([]rune(returnurl), v)) | ||
| 354 | } | ||
| 355 | } | ||
| 356 | if route.regex.MatchString(returnurl) { | ||
| 357 | return returnurl | ||
| 358 | } | ||
| 359 | } | ||
| 360 | } | ||
| 361 | if p.enableAuto { | ||
| 362 | for cName, methodList := range p.autoRouter { | ||
| 363 | if strings.ToLower(strings.TrimSuffix(paths[len(paths)-2], "Controller")) == cName { | ||
| 364 | if _, ok := methodList[methodName]; ok { | ||
| 365 | if len(values) > 0 { | ||
| 366 | return "/" + strings.TrimSuffix(paths[len(paths)-2], "Controller") + "/" + methodName + "?" + urlv.Encode() | ||
| 367 | } else { | ||
| 368 | return "/" + strings.TrimSuffix(paths[len(paths)-2], "Controller") + "/" + methodName | ||
| 369 | } | ||
| 370 | } | ||
| 371 | } | ||
| 372 | } | ||
| 373 | } | ||
| 374 | return "" | ||
| 375 | } | ||
| 376 | |||
| 262 | // AutoRoute | 377 | // AutoRoute |
| 263 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { | 378 | func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) { |
| 264 | defer func() { | 379 | defer func() { | ... | ... |
| ... | @@ -25,6 +25,29 @@ func (this *TestController) Myext() { | ... | @@ -25,6 +25,29 @@ func (this *TestController) Myext() { |
| 25 | this.Ctx.Output.Body([]byte(this.Ctx.Input.Params(":ext"))) | 25 | this.Ctx.Output.Body([]byte(this.Ctx.Input.Params(":ext"))) |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | func (this *TestController) GetUrl() { | ||
| 29 | this.Ctx.Output.Body([]byte(this.UrlFor(".Myext"))) | ||
| 30 | } | ||
| 31 | |||
| 32 | func TestUrlFor(t *testing.T) { | ||
| 33 | handler := NewControllerRegistor() | ||
| 34 | handler.Add("/api/list", &TestController{}, "*:List") | ||
| 35 | handler.Add("/person/:last/:first", &TestController{}) | ||
| 36 | handler.AddAuto(&TestController{}) | ||
| 37 | if handler.UrlFor("TestController.List") != "/api/list" { | ||
| 38 | t.Errorf("TestController.List must equal to /api/list") | ||
| 39 | } | ||
| 40 | if handler.UrlFor("TestController.Get", ":last", "xie", ":first", "asta") != "/person/xie/asta" { | ||
| 41 | t.Errorf("TestController.Get must equal to /person/xie/asta") | ||
| 42 | } | ||
| 43 | if handler.UrlFor("TestController.Myext") != "/Test/Myext" { | ||
| 44 | t.Errorf("TestController.Myext must equal to /Test/Myext") | ||
| 45 | } | ||
| 46 | if handler.UrlFor("TestController.GetUrl") != "/Test/GetUrl" { | ||
| 47 | t.Errorf("TestController.GetUrl must equal to /Test/GetUrl") | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 28 | func TestUserFunc(t *testing.T) { | 51 | func TestUserFunc(t *testing.T) { |
| 29 | r, _ := http.NewRequest("GET", "/api/list", nil) | 52 | r, _ := http.NewRequest("GET", "/api/list", nil) |
| 30 | w := httptest.NewRecorder() | 53 | w := httptest.NewRecorder() | ... | ... |
| ... | @@ -43,6 +43,8 @@ func init() { | ... | @@ -43,6 +43,8 @@ func init() { |
| 43 | beegoTplFuncMap["le"] = le // <= | 43 | beegoTplFuncMap["le"] = le // <= |
| 44 | beegoTplFuncMap["lt"] = lt // < | 44 | beegoTplFuncMap["lt"] = lt // < |
| 45 | beegoTplFuncMap["ne"] = ne // != | 45 | beegoTplFuncMap["ne"] = ne // != |
| 46 | |||
| 47 | beegoTplFuncMap["urlfor"] = UrlFor // != | ||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | // AddFuncMap let user to register a func in the template | 50 | // AddFuncMap let user to register a func in the template | ... | ... |
| ... | @@ -385,6 +385,6 @@ func GetRandomString(n int) string { | ... | @@ -385,6 +385,6 @@ func GetRandomString(n int) string { |
| 385 | // /login | 385 | // /login |
| 386 | // /login?next=/ | 386 | // /login?next=/ |
| 387 | // /user/John%20Doe | 387 | // /user/John%20Doe |
| 388 | func UrlFor(endpoint string, values ...string) { | 388 | func UrlFor(endpoint string, values ...string) string { |
| 389 | 389 | return BeeApp.UrlFor(endpoint, values...) | |
| 390 | } | 390 | } | ... | ... |
-
Please register or sign in to post a comment