Update to version 8.5.1. It contains a minor fix. Read HISTORY.md

https://github.com/kataras/iris/blob/master/HISTORY.md#tu-10-october-2017--v851

Former-commit-id: af1424c691613ccde911bef7d1371aa52e6abb79
This commit is contained in:
Gerasimos (Makis) Maropoulos 2017-10-10 16:58:14 +03:00
parent 713e5c3362
commit de3fc8ae46
11 changed files with 122 additions and 15 deletions

View File

@ -18,6 +18,12 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`.
# Tu, 10 October 2017 | v8.5.1
## MVC
- fix any manual or before middleware's `ctx.ViewData(key, value)` gets overridden by setting `mvc.Controller.Data` or `return mvc.View {Data: ...}`. See the [test case](mvc/method_result_test.go#L226).
# Mo, 09 October 2017 | v8.5.0 # Mo, 09 October 2017 | v8.5.0
## MVC ## MVC

View File

@ -67,7 +67,7 @@ $ go get -u github.com/kataras/iris
- Iris takes advantage of the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature. You get truly reproducible builds, as this method guards against upstream renames and deletes. - Iris takes advantage of the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature. You get truly reproducible builds, as this method guards against upstream renames and deletes.
- [Latest changes | v8.5.0](https://github.com/kataras/iris/blob/master/HISTORY.md#mo-09-october-2017--v850) - [Latest changes | v8.5.1](https://github.com/kataras/iris/blob/master/HISTORY.md#tu-10-october-2017--v851)
## Getting Started ## Getting Started
@ -698,7 +698,6 @@ func (s *MovieMemoryService) GetAll() []models.Movie {
} }
``` ```
```go ```go
// file: controllers/movie_controller.go // file: controllers/movie_controller.go

View File

@ -86,7 +86,7 @@ _Psst_, we've produced a small video about your feelings regrating to Iris! You
### 📑 Table Of Content ### 📑 Table Of Content
* [Installation](#-installation) * [Installation](#-installation)
* [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#mo-09-october-2017--v850) * [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#tu-10-october-2017--v851)
* [Learn](#-learn) * [Learn](#-learn)
* [Structuring](_examples/#structuring) * [Structuring](_examples/#structuring)
* [HTTP Listening](_examples/#http-listening) * [HTTP Listening](_examples/#http-listening)

View File

@ -1 +1 @@
8.5.0:https://github.com/kataras/iris/blob/master/HISTORY.md#mo-09-october-2017--v850 8.5.1:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-10-october-2017--v851

View File

@ -174,20 +174,41 @@ If `app.Controller("/assets", new(file.Controller))`
- `func(*Controller) GetByWildard(path string)` - `GET:/assets/{param:path}` - `func(*Controller) GetByWildard(path string)` - `GET:/assets/{param:path}`
Supported types for method functions receivers: int, int64, bool and string.
Response via output arguments, optionally, i.e
```go
func(c *ExampleController) Get() string |
(string, string) |
(string, int) |
int |
(int, string |
(string, error) |
error |
(int, error) |
(customStruct, error) |
customStruct |
(customStruct, int) |
(customStruct, string) |
mvc.Result or (mvc.Result, error)
```
where [mvc.Result](https://github.com/kataras/iris/blob/master/mvc/method_result.go) is an interface which contains only that function: `Dispatch(ctx iris.Context)`.
**Using Iris MVC for code reuse** **Using Iris MVC for code reuse**
By creating components that are independent of one another, developers are able to reuse components quickly and easily in other applications. The same (or similar) view for one application can be refactored for another application with different data because the view is simply handling how the data is being displayed to the user. By creating components that are independent of one another, developers are able to reuse components quickly and easily in other applications. The same (or similar) view for one application can be refactored for another application with different data because the view is simply handling how the data is being displayed to the user.
If you're new to back-end web development read about the MVC architectural pattern first, a good start is that [wikipedia article](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller). If you're new to back-end web development read about the MVC architectural pattern first, a good start is that [wikipedia article](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller).
Follow the examples below, Follow the examples below,
- [Hello world](mvc/hello-world/main.go) - [Hello world](mvc/hello-world/main.go)
- [Session Controller](mvc/session-controller/main.go) - [Session Controller](mvc/session-controller/main.go)
- [A simple but featured Controller with model and views](mvc/controller-with-model-and-view). - [A simple but featured Controller with model and views](mvc/controller-with-model-and-view)
- [Login showcase](mvc/login/main.go) **NEW** - [Login showcase](mvc/login/main.go) **NEW**
- [Using Method Result (plus Service-oriented design)](mvc/using-method-result)
### Subdomains ### Subdomains

2
doc.go
View File

@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
Current Version Current Version
8.5.0 8.5.1
Installation Installation

View File

@ -32,7 +32,7 @@ import (
const ( const (
// Version is the current version number of the Iris Web Framework. // Version is the current version number of the Iris Web Framework.
Version = "8.5.0" Version = "8.5.1"
) )
// HTTP status codes as registered with IANA. // HTTP status codes as registered with IANA.

View File

@ -131,7 +131,7 @@ func (t TController) HandlerOf(methodFunc methodfunc.MethodFunc) context.Handler
t.persistenceController.Handle(c) t.persistenceController.Handle(c)
} }
// if previous (binded) handlers stoped the execution // if previous (binded) handlers stopped the execution
// we should know that. // we should know that.
if ctx.IsStopped() { if ctx.IsStopped() {
return return

View File

@ -347,7 +347,19 @@ func (c *Controller) EndRequest(ctx context.Context) {
ctx.ViewLayout(layout) ctx.ViewLayout(layout)
} }
if len(c.Data) > 0 { if len(c.Data) > 0 {
ctx.Values().Set(ctx.Application().ConfigurationReadOnly().GetViewDataContextKey(), c.Data) dataKey := ctx.Application().ConfigurationReadOnly().GetViewDataContextKey()
// In order to respect any c.Ctx.ViewData that may called manually before;
if ctx.Values().Get(dataKey) == nil {
// if no c.Ctx.ViewData then it's empty do a
// pure set, it's faster.
ctx.Values().Set(dataKey, c.Data)
} else {
// else do a range loop and set the data one by one.
for k, v := range c.Data {
ctx.ViewData(k, v)
}
}
} }
ctx.View(view) ctx.View(view)

View File

@ -222,3 +222,50 @@ func TestControllerMethodResultTypes(t *testing.T) {
// it will fire the error's text // it will fire the error's text
Body().Equal("omit return of testCustomStruct and fire error") Body().Equal("omit return of testCustomStruct and fire error")
} }
type testControllerViewResultRespectCtxViewData struct {
T *testing.T
mvc.C
}
func (t *testControllerViewResultRespectCtxViewData) BeginRequest(ctx context.Context) {
t.C.BeginRequest(ctx)
ctx.ViewData("name_begin", "iris_begin")
}
func (t *testControllerViewResultRespectCtxViewData) EndRequest(ctx context.Context) {
t.C.EndRequest(ctx)
// check if data is not overriden by return mvc.View {Data: context.Map...}
dataWritten := ctx.GetViewData()
if dataWritten == nil {
t.T.Fatalf("view data is nil, both BeginRequest and Get failed to write the data")
return
}
if dataWritten["name_begin"] == nil {
t.T.Fatalf(`view data[name_begin] is nil,
BeginRequest's ctx.ViewData call have been overriden by Get's return mvc.View {Data: }.
Total view data: %v`, dataWritten)
}
if dataWritten["name"] == nil {
t.T.Fatalf("view data[name] is nil, Get's return mvc.View {Data: } didn't work. Total view data: %v", dataWritten)
}
}
func (t *testControllerViewResultRespectCtxViewData) Get() mvc.Result {
return mvc.View{
Name: "doesnt_exists.html",
Data: context.Map{"name": "iris"}, // we care about this only.
Code: iris.StatusInternalServerError,
}
}
func TestControllerViewResultRespectCtxViewData(t *testing.T) {
app := iris.New()
app.Controller("/", new(testControllerViewResultRespectCtxViewData), t)
e := httptest.New(t, app)
e.GET("/").Expect().Status(iris.StatusInternalServerError)
}

View File

@ -5,6 +5,8 @@ import (
"github.com/kataras/iris/context" "github.com/kataras/iris/context"
"github.com/kataras/iris/mvc/activator/methodfunc" "github.com/kataras/iris/mvc/activator/methodfunc"
"github.com/fatih/structs"
) )
// View completes the `methodfunc.Result` interface. // View completes the `methodfunc.Result` interface.
@ -66,12 +68,32 @@ func (r View) Dispatch(ctx context.Context) { // r as Response view.
} }
if r.Data != nil { if r.Data != nil {
ctx.Values().Set( // In order to respect any c.Ctx.ViewData that may called manually before;
ctx.Application().ConfigurationReadOnly().GetViewDataContextKey(), dataKey := ctx.Application().ConfigurationReadOnly().GetViewDataContextKey()
r.Data, if ctx.Values().Get(dataKey) == nil {
) // if no c.Ctx.ViewData then it's empty do a
// pure set, it's faster.
ctx.Values().Set(dataKey, r.Data)
} else {
// else check if r.Data is map or struct, if struct convert it to map,
// do a range loop and set the data one by one.
// context.Map is actually a map[string]interface{} but we have to make that check;
if m, ok := r.Data.(map[string]interface{}); ok {
setViewData(ctx, m)
} else if m, ok := r.Data.(context.Map); ok {
setViewData(ctx, m)
} else if structs.IsStruct(r.Data) {
setViewData(ctx, structs.Map(r))
}
}
} }
ctx.View(r.Name) ctx.View(r.Name)
} }
} }
func setViewData(ctx context.Context, data map[string]interface{}) {
for k, v := range data {
ctx.ViewData(k, v)
}
}