mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41: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.
|
||||
|
||||
**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
|
||||
|
||||
Thanks to an amazing person, we have a new [logo](logo.svg) for Iris. The new logo was created by [@merry.dii
|
||||
](https://www.instagram.com/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)!
|
||||
|
||||
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:
|
||||
|
||||
|
|
|
@ -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: Caddy](tutorial/caddy)
|
||||
- [Tutorial:Iris Go Framework + MongoDB](https://medium.com/go-language/iris-go-framework-mongodb-552e349eab9c)
|
||||
|
||||
### 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.
|
||||
|
|
|
@ -25,6 +25,7 @@ type BaseController interface {
|
|||
type shared interface {
|
||||
Name() string
|
||||
Router() router.Party
|
||||
GetRoute(methodName string) *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".
|
||||
fullName string
|
||||
|
||||
// the methods names that is already binded to a handler,
|
||||
// the BeginRequest, EndRequest and BeforeActivation are reserved by the internal implementation.
|
||||
reservedMethods []string
|
||||
// the already-registered routes, key = the controller's function name.
|
||||
// End-devs can change some properties of the *Route on the `BeforeActivator` by using the
|
||||
// `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.
|
||||
// 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`,
|
||||
// if a new method is registered via `Handle` its function name
|
||||
// is also appended to that slice.
|
||||
//
|
||||
// TODO: now that BaseController is totally optionally
|
||||
// we have to check if BeginRequest and EndRequest should be here.
|
||||
reservedMethods: whatReservedMethods(typ),
|
||||
routes: whatReservedMethods(typ),
|
||||
// CloneWithFieldsOf: include the manual fill-ed controller struct's fields to the dependencies.
|
||||
dependencies: di.Values(dependencies).CloneWithFieldsOf(controller),
|
||||
}
|
||||
|
@ -127,13 +126,20 @@ func newControllerActivator(router router.Party, controller interface{}, depende
|
|||
return c
|
||||
}
|
||||
|
||||
func whatReservedMethods(typ reflect.Type) []string {
|
||||
func whatReservedMethods(typ reflect.Type) map[string]*router.Route {
|
||||
methods := []string{"BeforeActivation", "AfterActivation"}
|
||||
// BeforeActivatior/AfterActivation are not routes but they are
|
||||
// reserved names*
|
||||
if isBaseController(typ) {
|
||||
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
|
||||
|
@ -182,6 +188,24 @@ func (c *ControllerActivator) Router() router.Party {
|
|||
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
|
||||
// have the same controller instance.
|
||||
// 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.
|
||||
func (c *ControllerActivator) isReservedMethod(name string) bool {
|
||||
for _, s := range c.reservedMethods {
|
||||
if s == name {
|
||||
for methodName := range c.routes {
|
||||
if methodName == name {
|
||||
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
|
||||
// be sure that the same func will not be registered again,
|
||||
// even if a custom .Handle later on.
|
||||
c.reservedMethods = append(c.reservedMethods, funcName)
|
||||
c.routes[funcName] = route
|
||||
|
||||
return route
|
||||
}
|
||||
|
|
|
@ -34,13 +34,31 @@ type testControllerHandle struct {
|
|||
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", "/hiservice", "HiService")
|
||||
b.Handle("GET", "/hiparam/{ps:string}", "HiParamBy")
|
||||
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) {
|
||||
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) Get() string {
|
||||
if c.Ctx.GetCurrentRoute().Name() != "index_route" {
|
||||
return "Get's route's name didn't change on AfterActivation"
|
||||
}
|
||||
return "index"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user