Skip to content

Commit

Permalink
fix #1330
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Aug 9, 2019
1 parent 7f64919 commit fe9bfbc
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 30 deletions.
7 changes: 4 additions & 3 deletions _examples/sessions/database/redis/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
// tested with redis version 3.0.503.
// for windows see: https://github.com/ServiceStack/redis-windows
func main() {
// replace with your running redis' server settings:
// These are the default values,
// you can replace them based on your running redis' server settings:
db := redis.New(redis.Config{
Network: "tcp",
Addr: "127.0.0.1:6379",
Expand All @@ -25,14 +26,14 @@ func main() {
Driver: redis.Redigo(), // redis.Radix() can be used instead.
})

// optionally configure the underline driver:
// Optionally configure the underline driver:
// driver := redis.Redigo()
// driver.MaxIdle = ...
// driver.IdleTimeout = ...
// driver.Wait = ...
// redis.Config {Driver: driver}

// close connection when control+C/cmd+C
// Close connection when control+C/cmd+C
iris.RegisterOnInterrupt(func() {
db.Close()
})
Expand Down
25 changes: 21 additions & 4 deletions _examples/view/template_jet_0/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,27 @@ func main() {
ctx.View("todos/show.jet", todo)
})
app.Get("/all-done", func(ctx iris.Context) {
vars := make(view.JetRuntimeVars) // <-- or keep use the jet.VarMap, decision up to you, it refers to the same type.
vars.Set("showingAllDone", true)
view.AddJetRuntimeVars(ctx, vars) // <--
ctx.View("todos/index.jet", (&doneTODOs{}).New(todos))
// vars := make(view.JetRuntimeVars)
// vars.Set("showingAllDone", true)
// vars.Set("title", "Todos - All Done")
// view.AddJetRuntimeVars(ctx, vars)
// ctx.View("todos/index.jet", (&doneTODOs{}).New(todos))
//
// OR

ctx.ViewData("showingAllDone", true)
ctx.ViewData("title", "Todos - All Done")

// Key does not actual matters at all here.
// However, you can enable it for better performance.
// In order to enable key mapping for
// jet specific renderer and ranger types
// then initialize the View Engine
// by `tmpl.DisableViewDataTypeCheck("_jet")`.
//
// Defaults to type checks, empty key.
ctx.ViewData("_jet", (&doneTODOs{}).New(todos))
ctx.View("todos/index.jet")
})

port := os.Getenv("PORT")
Expand Down
4 changes: 2 additions & 2 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -1018,8 +1018,8 @@ var Gzip = func(ctx Context) {
ctx.Next()
}

// Map is just a shortcut of the map[string]interface{}.
type Map map[string]interface{}
// Map is just a type alias of the map[string]interface{} type.
type Map = map[string]interface{}

// +------------------------------------------------------------+
// | Context Implementation |
Expand Down
110 changes: 89 additions & 21 deletions view/jet.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type JetEngine struct {
// Note that global vars and functions are set in a single spot on the jet parser.
// If AddFunc or AddVar called before `Load` then these will be set here to be used via `Load` and clear.
vars map[string]interface{}

jetRendererRangerContextKey string
}

var _ Engine = (*JetEngine)(nil)
Expand Down Expand Up @@ -66,6 +68,20 @@ func Jet(directory, extension string) *JetEngine {
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(jetDataContextKey string) {
s.jetRendererRangerContextKey = jetDataContextKey
}

// String returns the name of this view engine, the "jet".
func (s *JetEngine) String() string {
return jetEngineName
Expand Down Expand Up @@ -358,24 +374,7 @@ func (rr rangerAndRenderer) Render(jetRuntime *jet.Runtime) {
rr.renderer.Render(jetRuntime)
}

// ExecuteWriter should execute a template by its filename with an optional layout and bindingData.
func (s *JetEngine) ExecuteWriter(w io.Writer, filename string, layout string, bindingData interface{}) error {
tmpl, err := s.Set.GetTemplate(filename)
if err != nil {
return err
}

var vars JetRuntimeVars

if ctx, ok := w.(context.Context); ok {
runtimeVars := ctx.Values().Get(JetRuntimeVarsContextKey)
if runtimeVars != nil {
if jetVars, ok := runtimeVars.(JetRuntimeVars); ok {
vars = jetVars
}
}
}

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)
Expand All @@ -392,16 +391,85 @@ func (s *JetEngine) ExecuteWriter(w io.Writer, filename string, layout string, b

if renderer, ok := bindingData.(jet.Renderer); ok {
// this can make a Ranger and Renderer both work together, unlike the jet parser itself.
return tmpl.Execute(w, vars, rangerAndRenderer{ranger, renderer})
return rangerAndRenderer{ranger, renderer}, true
}

return tmpl.Execute(w, vars, &ranger)
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 tmpl.Execute(w, vars, &renderer) // see above ^.
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 {
return err
}

var vars JetRuntimeVars

if ctx, ok := w.(context.Context); ok {
runtimeVars := ctx.Values().Get(JetRuntimeVarsContextKey)
if runtimeVars != nil {
if jetVars, ok := runtimeVars.(JetRuntimeVars); ok {
vars = jetVars
}
}
}

if bindingData == nil {
return tmpl.Execute(w, vars, nil)
}

jetRangerRenderer, ok := rangerRenderer(bindingData)
if ok {
return tmpl.Execute(w, vars, jetRangerRenderer)
}

if m, ok := bindingData.(context.Map); ok {
for k, v := range m {
if s.jetRendererRangerContextKey == "" {

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.jetRendererRangerContextKey {
jetRangerRenderer = v
continue
}

if vars == nil {
vars = make(JetRuntimeVars)
}

vars.Set(k, v)
}

return tmpl.Execute(w, vars, jetRangerRenderer)
}

return tmpl.Execute(w, vars, bindingData)
Expand Down

0 comments on commit fe9bfbc

Please sign in to comment.