Exemple #1
0
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))
}
Exemple #3
0
// 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,