github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/flosch/pongo2.v3/context.go (about)

     1  package pongo2
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  )
     7  
     8  var reIdentifiers = regexp.MustCompile("^[a-zA-Z0-9_]+$")
     9  
    10  // Use this Context type to provide constants, variables, instances or functions to your template.
    11  //
    12  // pongo2 automatically provides meta-information or functions through the "pongo2"-key.
    13  // Currently, context["pongo2"] contains the following keys:
    14  //  1. version: returns the version string
    15  //
    16  // Template examples for accessing items from your context:
    17  //     {{ myconstant }}
    18  //     {{ myfunc("test", 42) }}
    19  //     {{ user.name }}
    20  //     {{ pongo2.version }}
    21  type Context map[string]interface{}
    22  
    23  func (c Context) checkForValidIdentifiers() *Error {
    24  	for k, v := range c {
    25  		if !reIdentifiers.MatchString(k) {
    26  			return &Error{
    27  				Sender:   "checkForValidIdentifiers",
    28  				ErrorMsg: fmt.Sprintf("Context-key '%s' (value: '%+v') is not a valid identifier.", k, v),
    29  			}
    30  		}
    31  	}
    32  	return nil
    33  }
    34  
    35  func (c Context) Update(other Context) Context {
    36  	for k, v := range other {
    37  		c[k] = v
    38  	}
    39  	return c
    40  }
    41  
    42  // If you're writing a custom tag, your tag's Execute()-function will
    43  // have access to the ExecutionContext. This struct stores anything
    44  // about the current rendering process's Context including
    45  // the Context provided by the user (field Public).
    46  // You can safely use the Private context to provide data to the user's
    47  // template (like a 'forloop'-information). The Shared-context is used
    48  // to share data between tags. All ExecutionContexts share this context.
    49  //
    50  // Please be careful when accessing the Public data.
    51  // PLEASE DO NOT MODIFY THE PUBLIC CONTEXT (read-only).
    52  //
    53  // To create your own execution context within tags, use the
    54  // NewChildExecutionContext(parent) function.
    55  type ExecutionContext struct {
    56  	template *Template
    57  
    58  	Autoescape bool
    59  	Public     Context
    60  	Private    Context
    61  	Shared     Context
    62  }
    63  
    64  var pongo2MetaContext = Context{
    65  	"version": Version,
    66  }
    67  
    68  func newExecutionContext(tpl *Template, ctx Context) *ExecutionContext {
    69  	privateCtx := make(Context)
    70  
    71  	// Make the pongo2-related funcs/vars available to the context
    72  	privateCtx["pongo2"] = pongo2MetaContext
    73  
    74  	return &ExecutionContext{
    75  		template: tpl,
    76  
    77  		Public:     ctx,
    78  		Private:    privateCtx,
    79  		Autoescape: true,
    80  	}
    81  }
    82  
    83  func NewChildExecutionContext(parent *ExecutionContext) *ExecutionContext {
    84  	newctx := &ExecutionContext{
    85  		template: parent.template,
    86  
    87  		Public:     parent.Public,
    88  		Private:    make(Context),
    89  		Autoescape: parent.Autoescape,
    90  	}
    91  	newctx.Shared = parent.Shared
    92  
    93  	// Copy all existing private items
    94  	newctx.Private.Update(parent.Private)
    95  
    96  	return newctx
    97  }
    98  
    99  func (ctx *ExecutionContext) Error(msg string, token *Token) *Error {
   100  	filename := ctx.template.name
   101  	var line, col int
   102  	if token != nil {
   103  		// No tokens available
   104  		// TODO: Add location (from where?)
   105  		filename = token.Filename
   106  		line = token.Line
   107  		col = token.Col
   108  	}
   109  	return &Error{
   110  		Template: ctx.template,
   111  		Filename: filename,
   112  		Line:     line,
   113  		Column:   col,
   114  		Token:    token,
   115  		Sender:   "execution",
   116  		ErrorMsg: msg,
   117  	}
   118  }
   119  
   120  func (ctx *ExecutionContext) Logf(format string, args ...interface{}) {
   121  	ctx.template.set.logf(format, args...)
   122  }