mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
add GetRoute
for MVC Controllers. Give the chance to change rsome route's properties like Name (used for reverse routing in templates, optionally).
Former-commit-id: 5ee9b1f97ff3c98cd8e5faddd23a87bbafb8e2e0
This commit is contained in:
parent
c8ade43b64
commit
617258890e
|
@ -16,12 +16,12 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
|
> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
|
||||||
|
|
||||||
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris` or let the automatic updater do that for you.
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
# Mo, 01 Jenuary 2018 | v10.0.0
|
# Mo, 01 Jenuary 2018 | v10.0.0
|
||||||
|
|
||||||
Thanks to an amazing person, we have a new [logo](logo.svg) for Iris. The new logo was created by [@merry.dii
|
We must thanks [Mrs. Diana](https://www.instagram.com/merry.dii/) for our awesome new [logo](https://iris-go.com/images/logo.svg)!
|
||||||
](https://www.instagram.com/merry.dii/).
|
|
||||||
|
You can [contact](mailto:Kovalenkodiana8@gmail.com) her for any design-related enquiries or explore and send a direct message via [instagram](https://www.instagram.com/merry.dii/).
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ It doesn't always contain the "best ways" but it does cover each important featu
|
||||||
- [Tutorial: DropzoneJS Uploader](tutorial/dropzonejs)
|
- [Tutorial: DropzoneJS Uploader](tutorial/dropzonejs)
|
||||||
- [Tutorial: Caddy](tutorial/caddy)
|
- [Tutorial: Caddy](tutorial/caddy)
|
||||||
- [Tutorial:Iris Go Framework + MongoDB](https://medium.com/go-language/iris-go-framework-mongodb-552e349eab9c)
|
- [Tutorial:Iris Go Framework + MongoDB](https://medium.com/go-language/iris-go-framework-mongodb-552e349eab9c)
|
||||||
|
|
||||||
### Structuring
|
### Structuring
|
||||||
|
|
||||||
Nothing stops you from using your favorite folder structure. Iris is a low level web framework, it has got MVC first-class support but it doesn't limit your folder structure, this is your choice.
|
Nothing stops you from using your favorite folder structure. Iris is a low level web framework, it has got MVC first-class support but it doesn't limit your folder structure, this is your choice.
|
||||||
|
|
|
@ -25,6 +25,7 @@ type BaseController interface {
|
||||||
type shared interface {
|
type shared interface {
|
||||||
Name() string
|
Name() string
|
||||||
Router() router.Party
|
Router() router.Party
|
||||||
|
GetRoute(methodName string) *router.Route
|
||||||
Handle(httpMethod, path, funcName string, middleware ...context.Handler) *router.Route
|
Handle(httpMethod, path, funcName string, middleware ...context.Handler) *router.Route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +75,10 @@ type ControllerActivator struct {
|
||||||
// i.e: if login-example/user/controller.go, the FullName is "user.Controller".
|
// i.e: if login-example/user/controller.go, the FullName is "user.Controller".
|
||||||
fullName string
|
fullName string
|
||||||
|
|
||||||
// the methods names that is already binded to a handler,
|
// the already-registered routes, key = the controller's function name.
|
||||||
// the BeginRequest, EndRequest and BeforeActivation are reserved by the internal implementation.
|
// End-devs can change some properties of the *Route on the `BeforeActivator` by using the
|
||||||
reservedMethods []string
|
// `GetRoute(functionName)`. It's also protects for duplicatations.
|
||||||
|
routes map[string]*router.Route
|
||||||
|
|
||||||
// the bindings that comes from the Engine and the controller's filled fields if any.
|
// the bindings that comes from the Engine and the controller's filled fields if any.
|
||||||
// Can be binded to the the new controller's fields and method that is fired
|
// Can be binded to the the new controller's fields and method that is fired
|
||||||
|
@ -116,10 +118,7 @@ func newControllerActivator(router router.Party, controller interface{}, depende
|
||||||
// are being appended to the slice at the `parseMethods`,
|
// are being appended to the slice at the `parseMethods`,
|
||||||
// if a new method is registered via `Handle` its function name
|
// if a new method is registered via `Handle` its function name
|
||||||
// is also appended to that slice.
|
// is also appended to that slice.
|
||||||
//
|
routes: whatReservedMethods(typ),
|
||||||
// TODO: now that BaseController is totally optionally
|
|
||||||
// we have to check if BeginRequest and EndRequest should be here.
|
|
||||||
reservedMethods: whatReservedMethods(typ),
|
|
||||||
// CloneWithFieldsOf: include the manual fill-ed controller struct's fields to the dependencies.
|
// CloneWithFieldsOf: include the manual fill-ed controller struct's fields to the dependencies.
|
||||||
dependencies: di.Values(dependencies).CloneWithFieldsOf(controller),
|
dependencies: di.Values(dependencies).CloneWithFieldsOf(controller),
|
||||||
}
|
}
|
||||||
|
@ -127,13 +126,20 @@ func newControllerActivator(router router.Party, controller interface{}, depende
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func whatReservedMethods(typ reflect.Type) []string {
|
func whatReservedMethods(typ reflect.Type) map[string]*router.Route {
|
||||||
methods := []string{"BeforeActivation", "AfterActivation"}
|
methods := []string{"BeforeActivation", "AfterActivation"}
|
||||||
|
// BeforeActivatior/AfterActivation are not routes but they are
|
||||||
|
// reserved names*
|
||||||
if isBaseController(typ) {
|
if isBaseController(typ) {
|
||||||
methods = append(methods, "BeginRequest", "EndRequest")
|
methods = append(methods, "BeginRequest", "EndRequest")
|
||||||
}
|
}
|
||||||
|
|
||||||
return methods
|
routes := make(map[string]*router.Route, len(methods))
|
||||||
|
for _, m := range methods {
|
||||||
|
routes[m] = &router.Route{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependencies returns the write and read access of the dependencies that are
|
// Dependencies returns the write and read access of the dependencies that are
|
||||||
|
@ -182,6 +188,24 @@ func (c *ControllerActivator) Router() router.Party {
|
||||||
return c.router
|
return c.router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRoute returns a registered route based on the controller's method name.
|
||||||
|
// It can be used to change the route's name, which is useful for reverse routing
|
||||||
|
// inside views. Custom routes can be registered with `Handle`, which returns the *Route.
|
||||||
|
// This method exists mostly for the automatic method parsing based on the known patterns
|
||||||
|
// inside a controller.
|
||||||
|
//
|
||||||
|
// A check for `nil` is necessary for unregistered methods.
|
||||||
|
//
|
||||||
|
// See `Handle` too.
|
||||||
|
func (c *ControllerActivator) GetRoute(methodName string) *router.Route {
|
||||||
|
for name, route := range c.routes {
|
||||||
|
if name == methodName {
|
||||||
|
return route
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Singleton returns new if all incoming clients' requests
|
// Singleton returns new if all incoming clients' requests
|
||||||
// have the same controller instance.
|
// have the same controller instance.
|
||||||
// This is done automatically by iris to reduce the creation
|
// This is done automatically by iris to reduce the creation
|
||||||
|
@ -196,8 +220,8 @@ func (c *ControllerActivator) Singleton() bool {
|
||||||
|
|
||||||
// checks if a method is already registered.
|
// checks if a method is already registered.
|
||||||
func (c *ControllerActivator) isReservedMethod(name string) bool {
|
func (c *ControllerActivator) isReservedMethod(name string) bool {
|
||||||
for _, s := range c.reservedMethods {
|
for methodName := range c.routes {
|
||||||
if s == name {
|
if methodName == name {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +315,7 @@ func (c *ControllerActivator) Handle(method, path, funcName string, middleware .
|
||||||
// add this as a reserved method name in order to
|
// add this as a reserved method name in order to
|
||||||
// be sure that the same func will not be registered again,
|
// be sure that the same func will not be registered again,
|
||||||
// even if a custom .Handle later on.
|
// even if a custom .Handle later on.
|
||||||
c.reservedMethods = append(c.reservedMethods, funcName)
|
c.routes[funcName] = route
|
||||||
|
|
||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,13 +34,31 @@ type testControllerHandle struct {
|
||||||
reqField string
|
reqField string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testControllerHandle) BeforeActivation(b BeforeActivation) { // BeforeActivation(t *mvc.TController) {
|
func (c *testControllerHandle) BeforeActivation(b BeforeActivation) {
|
||||||
b.Handle("GET", "/histatic", "HiStatic")
|
b.Handle("GET", "/histatic", "HiStatic")
|
||||||
b.Handle("GET", "/hiservice", "HiService")
|
b.Handle("GET", "/hiservice", "HiService")
|
||||||
b.Handle("GET", "/hiparam/{ps:string}", "HiParamBy")
|
b.Handle("GET", "/hiparam/{ps:string}", "HiParamBy")
|
||||||
b.Handle("GET", "/hiparamempyinput/{ps:string}", "HiParamEmptyInputBy")
|
b.Handle("GET", "/hiparamempyinput/{ps:string}", "HiParamEmptyInputBy")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test `GetRoute` for custom routes.
|
||||||
|
func (c *testControllerHandle) AfterActivation(a AfterActivation) {
|
||||||
|
// change automatic parser's route change name.
|
||||||
|
rget := a.GetRoute("Get")
|
||||||
|
if rget == nil {
|
||||||
|
panic("route from function name: 'Get' doesn't exist on `AfterActivation`")
|
||||||
|
}
|
||||||
|
rget.Name = "index_route"
|
||||||
|
|
||||||
|
// change a custom route's name.
|
||||||
|
r := a.GetRoute("HiStatic")
|
||||||
|
if r == nil {
|
||||||
|
panic("route from function name: HiStatic doesn't exist on `AfterActivation`")
|
||||||
|
}
|
||||||
|
// change the name here, and test if name changed in the handler.
|
||||||
|
r.Name = "hi_static_route"
|
||||||
|
}
|
||||||
|
|
||||||
func (c *testControllerHandle) BeginRequest(ctx iris.Context) {
|
func (c *testControllerHandle) BeginRequest(ctx iris.Context) {
|
||||||
c.reqField = ctx.URLParam("reqfield")
|
c.reqField = ctx.URLParam("reqfield")
|
||||||
}
|
}
|
||||||
|
@ -48,10 +66,17 @@ func (c *testControllerHandle) BeginRequest(ctx iris.Context) {
|
||||||
func (c *testControllerHandle) EndRequest(ctx iris.Context) {}
|
func (c *testControllerHandle) EndRequest(ctx iris.Context) {}
|
||||||
|
|
||||||
func (c *testControllerHandle) Get() string {
|
func (c *testControllerHandle) Get() string {
|
||||||
|
if c.Ctx.GetCurrentRoute().Name() != "index_route" {
|
||||||
|
return "Get's route's name didn't change on AfterActivation"
|
||||||
|
}
|
||||||
return "index"
|
return "index"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testControllerHandle) HiStatic() string {
|
func (c *testControllerHandle) HiStatic() string {
|
||||||
|
if c.Ctx.GetCurrentRoute().Name() != "hi_static_route" {
|
||||||
|
return "HiStatic's route's name didn't change on AfterActivation"
|
||||||
|
}
|
||||||
|
|
||||||
return c.reqField
|
return c.reqField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user