diff --git a/mux.go b/mux.go index e22dcac..caa8ad5 100644 --- a/mux.go +++ b/mux.go @@ -146,6 +146,13 @@ func (r *Router) getRegexpGroup() *routeRegexpGroup { return nil } +func (r *Router) buildVars(m map[string]string) map[string]string { + if r.parent != nil { + m = r.parent.buildVars(m) + } + return m +} + // ---------------------------------------------------------------------------- // Route factories // ---------------------------------------------------------------------------- diff --git a/mux_test.go b/mux_test.go index bd76a01..b163639 100644 --- a/mux_test.go +++ b/mux_test.go @@ -514,6 +514,7 @@ func TestMatcherFunc(t *testing.T) { func TestBuildVarsFunc(t *testing.T) { tests := []routeTest{ { + title: "BuildVarsFunc set on route", route: new(Route).Path(`/111/{v1:\d}{v2:.*}`).BuildVarsFunc(func(vars map[string]string) map[string]string { vars["v1"] = "3" vars["v2"] = "a" @@ -523,6 +524,19 @@ func TestBuildVarsFunc(t *testing.T) { path: "/111/3a", shouldMatch: true, }, + { + title: "BuildVarsFunc set on route and parent route", + route: new(Route).PathPrefix(`/{v1:\d}`).BuildVarsFunc(func(vars map[string]string) map[string]string { + vars["v1"] = "2" + return vars + }).Subrouter().Path(`/{v2:\w}`).BuildVarsFunc(func(vars map[string]string) map[string]string { + vars["v2"] = "b" + return vars + }), + request: newRequest("GET", "http://localhost/1/a"), + path: "/2/b", + shouldMatch: true, + }, } for _, test := range tests { diff --git a/route.go b/route.go index e79afa7..b2900de 100644 --- a/route.go +++ b/route.go @@ -413,7 +413,7 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) { if r.regexp == nil { return nil, errors.New("mux: route doesn't have a host or path") } - values, err := r.buildVars(pairs...) + values, err := r.prepareVars(pairs...) if err != nil { return nil, err } @@ -447,7 +447,7 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) { if r.regexp == nil || r.regexp.host == nil { return nil, errors.New("mux: route doesn't have a host") } - values, err := r.buildVars(pairs...) + values, err := r.prepareVars(pairs...) if err != nil { return nil, err } @@ -471,7 +471,7 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) { if r.regexp == nil || r.regexp.path == nil { return nil, errors.New("mux: route doesn't have a path") } - values, err := r.buildVars(pairs...) + values, err := r.prepareVars(pairs...) if err != nil { return nil, err } @@ -484,17 +484,24 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) { }, nil } -// buildVars converts the route variable pairs into a map. If the route has a +// prepareVars converts the route variable pairs into a map. If the route has a // BuildVarsFunc, it is invoked. -func (r *Route) buildVars(pairs ...string) (map[string]string, error) { +func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { m, err := mapFromPairs(pairs...) if err != nil { return nil, err } + return r.buildVars(m), nil +} + +func (r *Route) buildVars(m map[string]string) map[string]string { + if r.parent != nil { + m = r.parent.buildVars(m) + } if r.buildVarsFunc != nil { m = r.buildVarsFunc(m) } - return m, nil + return m } // ---------------------------------------------------------------------------- @@ -505,6 +512,7 @@ func (r *Route) buildVars(pairs ...string) (map[string]string, error) { type parentRoute interface { getNamedRoutes() map[string]*Route getRegexpGroup() *routeRegexpGroup + buildVars(map[string]string) map[string]string } // getNamedRoutes returns the map where named routes are registered.