func (s *TestSuite) TestMisc(c *C) { // Must // TODO: Add better error message (see issue #18) c.Check( func() { pongo2.Must(testSuite2.FromFile("template_tests/inheritance/base2.tpl")) }, PanicMatches, `\[Error \(where: fromfile\) in .*template_tests/inheritance/doesnotexist.tpl | Line 1 Col 12 near 'doesnotexist.tpl'\] open .*template_tests/inheritance/doesnotexist.tpl: no such file or directory`, ) // Context context := pongo2.NewContext().Set("'illegal", nil) c.Check(parseTemplateFn("", context), PanicMatches, ".*not a valid identifier.*") // Registers c.Check(func() { pongo2.RegisterFilter("escape", nil) }, PanicMatches, ".*is already registered.*") c.Check(func() { pongo2.RegisterTag("for", nil) }, PanicMatches, ".*is already registered.*") // ApplyFilter v, err := pongo2.ApplyFilter("title", pongo2.AsValue("this is a title"), nil) if err != nil { c.Fatal(err) } c.Check(v.String(), Equals, "This Is A Title") c.Check(func() { _, err := pongo2.ApplyFilter("doesnotexist", nil, nil) if err != nil { panic(err) } }, PanicMatches, `\[Error \(where: applyfilter\)\] Filter with name 'doesnotexist' not found.`) }
func (u *user) Is_admin() *pongo2.Value { return pongo2.AsValue(isAdmin(u)) }
// Write the given source bytes as Amber converted to HTML, to a writer. // filename and luafilename are only used if there are errors. func pongoPage(w http.ResponseWriter, req *http.Request, filename, luafilename string, pongodata []byte, funcs template.FuncMap, cache *FileCache) { var buf bytes.Buffer linkInGCSS := false // If style.gcss is present, and a header is present, and it has not already been linked in, link it in GCSSfilename := filepath.Join(filepath.Dir(filename), defaultStyleFilename) if fs.exists(GCSSfilename) { if debugMode { gcssblock, err := cache.read(GCSSfilename, shouldCache(".gcss")) if err != nil { fmt.Fprintf(w, "Unable to read %s: %s", filename, err) return } gcssdata := gcssblock.MustData() // Try compiling the GCSS file before the Amber file if err := validGCSS(gcssdata); err != nil { // Invalid GCSS, return an error page prettyError(w, req, GCSSfilename, gcssdata, err.Error(), "gcss") return } } linkInGCSS = true } // Prepare a Pongo2 template tpl, err := pongo2.DefaultSet.FromBytes(pongodata) if err != nil { if debugMode { prettyError(w, req, filename, pongodata, err.Error(), "html") } else { log.Errorf("Could not compile Pongo2 template:\n%s\n%s", err, string(pongodata)) } return } // TODO: Double check that all sorts of Lua functions are handled // Go through the global Lua scope for k, v := range funcs { // Check if the name in question is a function if f, ok := v.(func(...string) (string, error)); ok { // Wrap the Lua functions as Pongo2 functions funcs[k] = func(vals ...*pongo2.Value) *pongo2.Value { // Convert the Pongo2 arguments to string arguments strs := make([]string, len(vals)) for i, sv := range vals { strs[i] = sv.String() } // Call the Lua function retval, err := f(strs...) // Return the error if things go wrong if err != nil { return pongo2.AsValue(err) } // Return the returned value if things went well return pongo2.AsValue(retval) } } } // Make the Lua functions available to Pongo pongo2.Globals.Update(pongo2.Context(funcs)) // Render the Pongo2 template to the buffer if err := tpl.ExecuteWriter(pongo2.Globals, &buf); err != nil { if debugMode { prettyError(w, req, filename, pongodata, err.Error(), "html") } else { log.Errorf("Could not execute Pongo2 template:\n%s", err) } return } // Check if we are dealing with HTML if bytes.Contains(buf.Bytes(), []byte("<html>")) { if linkInGCSS { // Link in stylesheet htmldata := buf.Bytes() linkToStyleHTML(&htmldata, defaultStyleFilename) buf.Reset() _, err := buf.Write(htmldata) if err != nil { if debugMode { prettyError(w, req, filename, pongodata, err.Error(), "html") } else { log.Errorf("Can not write bytes to a buffer! Out of memory?\n%s", err) } } } // If the auto-refresh feature has been enabled if autoRefreshMode { // Insert JavaScript for refreshing the page into the generated HTML changedBytes := insertAutoRefresh(req, buf.Bytes()) buf.Reset() _, err := buf.Write(changedBytes) if err != nil { if debugMode { prettyError(w, req, filename, pongodata, err.Error(), "html") } else { log.Errorf("Can not write bytes to a buffer! Out of memory?\n%s", err) } } } // If doctype is missing, add doctype for HTML5 at the top changedBytes := insertDoctype(buf.Bytes()) buf.Reset() buf.Write(changedBytes) } // Write the rendered template to the client NewDataBlock(buf.Bytes()).ToClient(w, req) }
}, "func_variadic_sum_int": func(args ...int) int { // Create a sum s := 0 for _, i := range args { s += i } return s }, "func_variadic_sum_int2": func(args ...*pongo2.Value) *pongo2.Value { // Create a sum s := 0 for _, i := range args { s += i.Integer() } return pongo2.AsValue(s) }, }, "complex": pongo2.ContextMap{ "is_admin": isAdmin, "post": post{ Text: "<h2>Hello!</h2><p>Welcome to my new blog page. I'm using pongo2 which supports {{ variables }} and {% tags %}.</p>", Created: time2, }, "comments": []*comment{ &comment{ Author: &user{ Name: "user1", Validated: true, }, Date: time1,