diff --git a/HISTORY.md b/HISTORY.md
index 346f92b5..6a705e65 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -21,6 +21,13 @@ 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 github.com/kataras/iris/v12@latest`.
+# We, 05 February 2020 | v12.1.6
+
+Fixes:
+
+- [jet.View - urlpath error](https://github.com/kataras/iris/issues/1438)
+- [Context.ServeFile send 'application/wasm' with a wrong extra field](https://github.com/kataras/iris/issues/1440)
+
# Su, 02 February 2020 | v12.1.5
Various improvements and linting.
diff --git a/HISTORY_ES.md b/HISTORY_ES.md
index b9ce74f5..d9f23833 100644
--- a/HISTORY_ES.md
+++ b/HISTORY_ES.md
@@ -21,9 +21,9 @@ Los desarrolladores no están obligados a actualizar si realmente no lo necesita
**Cómo actualizar**: Abra su línea de comandos y ejecute este comando: `go get github.com/kataras/iris/v12@latest`.
-# Su, 02 February 2020 | v12.1.5
+# We, 05 February 2020 | v12.1.6
-Not translated yet, please navigate to the [english version](HISTORY.md#su-02-february-2020--v1215) instead.
+Not translated yet, please navigate to the [english version](HISTORY.md#we-05-february-2020--v1216) instead.
# Sábado, 26 de octubre 2019 | v12.0.0
diff --git a/NOTICE b/NOTICE
index 614039b9..62c03895 100644
--- a/NOTICE
+++ b/NOTICE
@@ -51,6 +51,9 @@ Revision ID: 607b5b7cef034da2692f99a4c9bafb31a999ccda
jade 9ffefa50b5f3141 https://github.com/Joker/jade
6ac643e9d9ad611
6f4688705f
+ jet 33cfc27b3e00072 github.com/CloudyKit/jet
+ 655fdb3af24c325
+ 3ea5bffb8f
json-iterator 08047c174c6c03e https://github.com/json-iterator/go
8ec963a411bde1b
6d1ee67b26
diff --git a/README.md b/README.md
index c7528516..3d4d59b6 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# News
-![](https://iris-go.com/images/release.png) Iris version **12.1.5** has been [released](HISTORY.md#su-02-february-2020--v1215)!
+![](https://iris-go.com/images/release.png) Iris version **12.1.6** has been [released](HISTORY.md#we-05-february-2020--v1216)!
![](https://iris-go.com/images/cli.png) The official [Iris Command Line Interface](https://github.com/kataras/iris-cli) will soon be near you in 2020!
diff --git a/VERSION b/VERSION
index cb1c968e..ec3291b4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-12.1.5:https://github.com/kataras/iris/releases/tag/v12.1.5
\ No newline at end of file
+12.1.6:https://github.com/kataras/iris/releases/tag/v12.1.6
\ No newline at end of file
diff --git a/_examples/http-listening/custom-listener/unix-reuseport/main.go b/_examples/http-listening/custom-listener/unix-reuseport/main.go
index c20932f7..7b67d5fc 100644
--- a/_examples/http-listening/custom-listener/unix-reuseport/main.go
+++ b/_examples/http-listening/custom-listener/unix-reuseport/main.go
@@ -19,9 +19,7 @@ import (
"github.com/kataras/iris/v12"
)
-// $ go get github.com/valyala/tcplisten
-// $ go run main.go
-
+// You can run the same app as many times as you want.
func main() {
app := iris.New()
@@ -35,7 +33,7 @@ func main() {
FastOpen: true,
}
- l, err := listenerCfg.NewListener("tcp", ":8080")
+ l, err := listenerCfg.NewListener("tcp4", ":8080")
if err != nil {
panic(err)
}
diff --git a/_examples/view/template_jet_0/main.go b/_examples/view/template_jet_0/main.go
index 7cbaaab0..bd8762a8 100644
--- a/_examples/view/template_jet_0/main.go
+++ b/_examples/view/template_jet_0/main.go
@@ -125,16 +125,13 @@ func main() {
ctx.ViewData("showingAllDone", true)
ctx.ViewData("title", "Todos - All Done")
- // Key does not actual matter at all here.
- // However, you can enable it for better performance.
- // In order to enable key mapping for
- // jet specific renderer and ranger types
- // you have to initialize the View Engine
- // with `tmpl.DisableViewDataTypeCheck("_jet")`.
- //
- // Defaults to type checks, empty key.
- ctx.ViewData("_jet", (&doneTODOs{}).New(todos))
- ctx.View("todos/index.jet")
+ // Use ctx.ViewData("_jet", jetData)
+ // if using as middleware and you want
+ // to pre-set the value or even change it later on from another next middleware.
+ // ctx.ViewData("_jet", (&doneTODOs{}).New(todos))
+ // and ctx.View("todos/index.jet")
+ // OR
+ ctx.View("todos/index.jet", (&doneTODOs{}).New(todos))
})
port := os.Getenv("PORT")
diff --git a/_examples/view/template_jet_0/views/todos/show.jet b/_examples/view/template_jet_0/views/todos/show.jet
index 334e7813..403cd588 100644
--- a/_examples/view/template_jet_0/views/todos/show.jet
+++ b/_examples/view/template_jet_0/views/todos/show.jet
@@ -2,7 +2,7 @@
{{block documentBody()}}
Show TODO
- This uses a custom renderer by implementing the jet.Renderer interface.
+
This uses a custom renderer by implementing the jet.Renderer (or view.JetRenderer) interface.
{{.}}
diff --git a/_examples/view/template_jet_2/main.go b/_examples/view/template_jet_2/main.go
new file mode 100644
index 00000000..6363326a
--- /dev/null
+++ b/_examples/view/template_jet_2/main.go
@@ -0,0 +1,66 @@
+// Package main an example on how to naming your routes & use the custom 'url path' Jet Template Engine.
+package main
+
+import (
+ "github.com/kataras/iris/v12"
+)
+
+func main() {
+ app := iris.New()
+ app.RegisterView(iris.Jet("./views", ".jet").Reload(true))
+
+ mypathRoute := app.Get("/mypath", writePathHandler)
+ mypathRoute.Name = "my-page1"
+
+ mypath2Route := app.Get("/mypath2/{paramfirst}/{paramsecond}", writePathHandler)
+ mypath2Route.Name = "my-page2"
+
+ mypath3Route := app.Get("/mypath3/{paramfirst}/statichere/{paramsecond}", writePathHandler)
+ mypath3Route.Name = "my-page3"
+
+ mypath4Route := app.Get("/mypath4/{paramfirst}/statichere/{paramsecond}/{otherparam}/{something:path}", writePathHandler)
+ // same as: app.Get("/mypath4/:paramfirst/statichere/:paramsecond/:otherparam/*something", writePathHandler)
+ mypath4Route.Name = "my-page4"
+
+ // same with Handle/Func
+ mypath5Route := app.Handle("GET", "/mypath5/{paramfirst}/statichere/{paramsecond}/{otherparam}/anything/{something:path}", writePathHandler)
+ mypath5Route.Name = "my-page5"
+
+ mypath6Route := app.Get("/mypath6/{paramfirst}/{paramsecond}/statichere/{paramThirdAfterStatic}", writePathHandler)
+ mypath6Route.Name = "my-page6"
+
+ app.Get("/", func(ctx iris.Context) {
+ // for /mypath6...
+ paramsAsArray := []string{"theParam1", "theParam2", "paramThirdAfterStatic"}
+ ctx.ViewData("ParamsAsArray", paramsAsArray)
+ if err := ctx.View("page.jet"); err != nil {
+ panic(err)
+ }
+ })
+
+ app.Get("/redirect/{namedRoute}", func(ctx iris.Context) {
+ routeName := ctx.Params().Get("namedRoute")
+ r := app.GetRoute(routeName)
+ if r == nil {
+ ctx.StatusCode(iris.StatusNotFound)
+ ctx.Writef("Route with name %s not found", routeName)
+ return
+ }
+
+ println("The path of " + routeName + "is: " + r.Path)
+ // if routeName == "my-page1"
+ // prints: The path of of my-page1 is: /mypath
+ // if it's a path which takes named parameters
+ // then use "r.ResolvePath(paramValuesHere)"
+ ctx.Redirect(r.Path)
+ // http://localhost:8080/redirect/my-page1 will redirect to -> http://localhost:8080/mypath
+ })
+
+ // http://localhost:8080
+ // http://localhost:8080/redirect/my-page1
+ app.Run(iris.Addr(":8080"))
+}
+
+func writePathHandler(ctx iris.Context) {
+ ctx.Writef("Hello from %s.", ctx.Path())
+}
diff --git a/_examples/view/template_jet_2/views/page.jet b/_examples/view/template_jet_2/views/page.jet
new file mode 100644
index 00000000..d0a0f220
--- /dev/null
+++ b/_examples/view/template_jet_2/views/page.jet
@@ -0,0 +1,24 @@
+/mypath
+
+
+/mypath2/{paramfirst}/{paramsecond}
+
+
+
+/mypath3/{paramfirst}/statichere/{paramsecond}
+
+
+
+
+ /mypath4/{paramfirst}/statichere/{paramsecond}/{otherparam}/{something:path}
+
+
+
+
+ /mypath5/{paramfirst}/statichere/{paramsecond}/{otherparam}/anything/{anything:path}
+
+
+
+
+ /mypath6/{paramfirst}/{paramsecond}/statichere/{paramThirdAfterStatic}
+
diff --git a/doc.go b/doc.go
index 4a20bb09..1f2f6fd2 100644
--- a/doc.go
+++ b/doc.go
@@ -38,7 +38,7 @@ Source code and other details for the project are available at GitHub:
Current Version
-12.1.5
+12.1.6
Installation
diff --git a/go.mod b/go.mod
index ba8d2054..bced6f93 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.13
require (
github.com/BurntSushi/toml v0.3.1
- github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible
+ github.com/CloudyKit/jet/v3 v3.0.0
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible
diff --git a/iris.go b/iris.go
index 94f036dc..34cf205e 100644
--- a/iris.go
+++ b/iris.go
@@ -41,7 +41,7 @@ import (
)
// Version is the current version number of the Iris Web Framework.
-const Version = "12.1.5"
+const Version = "12.1.6"
// HTTP status codes as registered with IANA.
// See: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml.
@@ -583,9 +583,17 @@ func (app *Application) NewHost(srv *http.Server) *host.Supervisor {
srv.ErrorLog = log.New(app.logger.Printer.Output, "[HTTP Server] ", 0)
}
- if srv.Addr == "" {
- srv.Addr = ":8080"
+ if addr := srv.Addr; addr == "" {
+ addr = ":8080"
+ if len(app.Hosts) > 0 {
+ if v := app.Hosts[0].Server.Addr; v != "" {
+ addr = v
+ }
+ }
+
+ srv.Addr = addr
}
+
app.logger.Debugf("Host: addr is %s", srv.Addr)
// create the new host supervisor
diff --git a/view/jet.go b/view/jet.go
index f72b46b6..f411aab3 100644
--- a/view/jet.go
+++ b/view/jet.go
@@ -10,7 +10,7 @@ import (
"github.com/kataras/iris/v12/context"
- "github.com/CloudyKit/jet"
+ "github.com/CloudyKit/jet/v3"
)
const jetEngineName = "jet"
@@ -64,29 +64,15 @@ func Jet(directory, extension string) *JetEngine {
}
s := &JetEngine{
- directory: directory,
- extension: extension,
- loader: jet.NewOSFileSystemLoader(directory),
+ directory: directory,
+ extension: extension,
+ loader: jet.NewOSFileSystemLoader(directory),
+ jetRangerRendererContextKey: "_jet",
}
return s
}
-// DisableViewDataTypeCheck accepts a context key name to use
-// to map the jet specific renderer and ranger over context's view data.
-//
-// If "jetDataContextKey" is not empty then `ExecuteWriter` will not check for
-// types to check if an element passed through `Context.ViewData`
-// contains a jet.Renderer or jet.Ranger or both.
-// Instead will map those with simple key data naming (faster).
-// Also it wont check if a value is already a reflect.Value (jet expects this type as values).
-//
-// Defaults to empty.
-func (s *JetEngine) DisableViewDataTypeCheck(jetRangerRendererContextKey string) *JetEngine {
- s.jetRangerRendererContextKey = jetRangerRendererContextKey
- return s
-}
-
// String returns the name of this view engine, the "jet".
func (s *JetEngine) String() string {
return jetEngineName
@@ -118,7 +104,7 @@ func (s *JetEngine) AddFunc(funcName string, funcBody interface{}) {
// instead it wants:
// func(JetArguments) reflect.Value.
- s.AddVar(funcName, func(args JetArguments) reflect.Value {
+ s.AddVar(funcName, jet.Func(func(args JetArguments) reflect.Value {
n := args.NumOfArguments()
if n == 0 { // no input, don't execute the function, panic instead.
panic(funcName + " expects one or more input arguments")
@@ -140,7 +126,7 @@ func (s *JetEngine) AddFunc(funcName string, funcBody interface{}) {
}
return reflect.ValueOf(generalFunc(firstInput, variadicInputs...))
- })
+ }))
return
}
@@ -366,53 +352,7 @@ func (s *JetEngine) AddRuntimeVars(ctx context.Context, vars JetRuntimeVars) {
AddJetRuntimeVars(ctx, vars)
}
-type rangerAndRenderer struct {
- ranger jet.Ranger
- renderer jet.Renderer
-}
-
-func (rr rangerAndRenderer) Range() (reflect.Value, reflect.Value, bool) {
- return rr.ranger.Range()
-}
-
-func (rr rangerAndRenderer) Render(jetRuntime *jet.Runtime) {
- rr.renderer.Render(jetRuntime)
-}
-
-func rangerRenderer(bindingData interface{}) (interface{}, bool) {
- if ranger, ok := bindingData.(jet.Ranger); ok {
- // Externally fixes a BUG on the jet template parser:
- // eval.go#executeList(list *ListNode):NodeRange.isSet.getRanger(expression = st.evalPrimaryExpressionGroup)
- // which does not act the "ranger" as element, instead is converted to a value of struct, which makes a jet.Ranger func(*myStruct) Range...
- // not a compatible jet.Ranger.
- // getRanger(st.context) should work but author of the jet library is not currently available,
- // to allow a recommentation or a PR and I don't really want to vendor it because
- // some end-users may use the jet import path to pass things like Global Funcs and etc.
- // So to fix it (at least temporarily and only for ref Ranger) we ptr the ptr the "ranger", not the bindingData, and this may
- // have its downside because the same bindingData may be compatible with other node actions like range or custom Render
- // but we have no other way at the moment. The same problem exists on the `Renderer` too!
- // The solution below fixes the above issue but any fields of the struct are not available,
- // this is ok because most of the times if not always, the users of jet don't use fields on Ranger and custom Renderer inside the templates.
-
- if renderer, ok := bindingData.(jet.Renderer); ok {
- // this can make a Ranger and Renderer both work together, unlike the jet parser itself.
- return rangerAndRenderer{ranger, renderer}, true
- }
-
- return &ranger, true
- }
-
- if renderer, ok := bindingData.(jet.Renderer); ok {
- // Here the fields are not available but usually if completes the jet.Renderer no
- // fields are used in the template.
- return &renderer, true // see above ^.
- }
-
- return nil, false
-}
-
// ExecuteWriter should execute a template by its filename with an optional layout and bindingData.
-// See `DisableViewDataTypeCheck` too.
func (s *JetEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
tmpl, err := s.Set.GetTemplate(filename)
if err != nil {
@@ -434,46 +374,28 @@ func (s *JetEngine) ExecuteWriter(w io.Writer, filename string, layout string, b
return tmpl.Execute(w, vars, nil)
}
- jetRangerRenderer, ok := rangerRenderer(bindingData)
- if ok {
- return tmpl.Execute(w, vars, jetRangerRenderer)
+ if vars == nil {
+ vars = make(JetRuntimeVars)
}
if m, ok := bindingData.(context.Map); ok {
+ var jetData interface{}
for k, v := range m {
- if s.jetRangerRendererContextKey == "" {
- switch value := v.(type) {
- case jet.Ranger, jet.Renderer:
- jetRangerRenderer, _ = rangerRenderer(value)
- case reflect.Value:
- if vars == nil {
- vars = make(JetRuntimeVars)
- }
- // if it's already a reflect value.
- vars[k] = value
- default:
- if vars == nil {
- vars = make(JetRuntimeVars)
- }
- vars.Set(k, v)
- }
-
- continue
- }
-
if k == s.jetRangerRendererContextKey {
- jetRangerRenderer = v
+ jetData = v
continue
}
- if vars == nil {
- vars = make(JetRuntimeVars)
+ if value, ok := v.(reflect.Value); ok {
+ vars[k] = value
+ } else {
+ vars[k] = reflect.ValueOf(v)
}
-
- vars.Set(k, v)
}
- return tmpl.Execute(w, vars, jetRangerRenderer)
+ if jetData != nil {
+ bindingData = jetData
+ }
}
return tmpl.Execute(w, vars, bindingData)