9446563e by astaxie

add util func to get the url fix #282

UrlFor(endpoint string, values ...string) string
1 parent 167ad203
...@@ -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 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!