Hello community, here is the log from the commit of package go-mustache.go for openSUSE:Factory checked in at 2012-02-14 11:24:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/go-mustache.go (Old) and /work/SRC/openSUSE:Factory/.go-mustache.go.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "go-mustache.go", Maintainer is "" Changes: -------- --- /work/SRC/openSUSE:Factory/go-mustache.go/go-mustache.go.changes 2011-09-23 02:01:33.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.go-mustache.go.new/go-mustache.go.changes 2012-02-14 11:24:45.000000000 +0100 @@ -1,0 +2,5 @@ +Thu Feb 9 12:45:53 UTC 2012 - [email protected] + +- gofixes for latest weekly (2012-02-07) + +------------------------------------------------------------------- Old: ---- mustache.go-0.0.0+git20110813.tar.bz2 New: ---- mustache.go-0.0.0+git20120208.tar.bz2 opensuse-build-fix.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ go-mustache.go.spec ++++++ --- /var/tmp/diff_new_pack.uWqb4a/_old 2012-02-14 11:24:46.000000000 +0100 +++ /var/tmp/diff_new_pack.uWqb4a/_new 2012-02-14 11:24:46.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package go-mustache.go # -# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. # Copyright (c), 2010, Sascha Peilicke <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -19,13 +19,14 @@ Name: go-mustache.go -Version: 0.0.0+git20110813 +Version: 0.0.0+git20120208 Release: 1 Summary: The mustache template language in Go Group: Development/Languages/Other License: MIT Url: http://github.com/hoisie/mustache.go Source0: mustache.go-%{version}.tar.bz2 +Patch0: opensuse-build-fix.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: go-devel %{go_provides} @@ -40,11 +41,12 @@ %prep %setup -q -n mustache.go +%patch0 -p1 %build %install -%{go_make_install} +%goinstall github.com/hoisie/mustache.go/ %files %defattr(-,root,root,-) ++++++ mustache.go-0.0.0+git20110813.tar.bz2 -> mustache.go-0.0.0+git20120208.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mustache.go/Makefile new/mustache.go/Makefile --- old/mustache.go/Makefile 2011-08-13 12:11:15.000000000 +0200 +++ new/mustache.go/Makefile 2012-02-09 13:21:10.000000000 +0100 @@ -1,6 +1,7 @@ include $(GOROOT)/src/Make.inc -TARG=mustache +TARG=github.com/hoisie/mustache.go + GOFILES=\ mustache.go\ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mustache.go/Readme.md new/mustache.go/Readme.md --- old/mustache.go/Readme.md 2011-08-13 12:11:15.000000000 +0200 +++ new/mustache.go/Readme.md 2012-02-09 13:21:10.000000000 +0100 @@ -8,9 +8,11 @@ Also check out some [example mustache files](http://github.com/defunkt/mustache/tree/master/examples/) -## Usage +## Installation +To install mustache.go, simply run `goinstall github.com/hoisie/mustache.go`. To use it in a program, use `import "github.com/hoisie/mustache.go"` -There are only four methods in this package: +## Usage +There are four main methods in this package: func Render(data string, context ...interface{}) string @@ -20,6 +22,7 @@ func ParseFile(filename string) (*template, os.Error) +There are also two additional methods for using layouts (explained below). The Render method takes a string and a data source, which is generally a map or struct, and returns the output string. If the template file contains an error, the return value is a description of the error. There's a similar method, RenderFile, which takes a filename as an argument and uses that for the template contents. @@ -29,7 +32,7 @@ If you're planning to render the same template multiple times, you do it efficiently by compiling the template first: - tmpl,_ := mustache.Parse("hello {{c}}") + tmpl,_ := mustache.ParseString("hello {{c}}") var buf bytes.Buffer; for i := 0; i < 10; i++ { tmpl.Render (map[string]string { "c":"world"}, &buf) @@ -40,7 +43,64 @@ ## Escaping mustache.go follows the official mustache HTML escaping rules. That is, if you enclose a variable with two curly brackets, `{{var}}`, the contents are HTML-escaped. For instance, strings like `5 > 2` are converted to `5 > 2`. To use raw characters, use three curly brackets `{{{var}}}`. - + +## Layouts + +It is a common pattern to include a template file as a "wrapper" for other templates. The wrapper may include a header and a footer, for instance. Mustache.go supports this pattern with the following two methods: + + func RenderInLayout(data string, layout string, context ...interface{}) string + + func RenderFileInLayout(filename string, layoutFile string, context ...interface{}) string + +The layout file must have a variable called `{{content}}`. For example, given the following files: + +layout.html.mustache: + + <html> + <head><title>Hi</title></head> + <body> + {{{content}}} + </body> + </html> + +template.html.mustache: + + <h1> Hello World! </h1> + +A call to `RenderFileInLayout("template.html.mustache", "layout.html.mustache", nil)` will produce: + + <html> + <head><title>Hi</title></head> + <body> + <h1> Hello World! </h1> + </body> + </html> + +## A note about method receivers + +Mustache.go supports calling methods on objects, but you have to be aware of Go's limitations. For example, lets's say you have the following type: + + type Person struct { + FirstName string + LastName string + } + + func (p *Person) Name1() string { + return p.FirstName + " " + p.LastName + } + + func (p Person) Name2() string { + return p.FirstName + " " + p.LastName + } + +While they appear to be identical methods, `Name1` has a pointer receiver, and `Name2` has a value receiver. Objects of type `Person`(non-pointer) can only access `Name2`, while objects of type `*Person`(person) can access both. This is by design in the Go language. + +So if you write the following: + + mustache.Render("{{Name1}}", Person{"John", "Smith"}) + +It'll be blank. You either have to use `&Person{"John", "Smith"}`, or call `Name2` + ## Supported features * Variables diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mustache.go/mustache.go new/mustache.go/mustache.go --- old/mustache.go/mustache.go 2011-08-13 12:11:15.000000000 +0200 +++ new/mustache.go/mustache.go 2012-02-09 13:44:33.000000000 +0100 @@ -2,7 +2,6 @@ import ( "bytes" - "container/vector" "fmt" "io" "io/ioutil" @@ -25,7 +24,7 @@ name string inverted bool startline int - elems *vector.Vector + elems []interface{} } type Template struct { @@ -35,7 +34,7 @@ p int curline int dir string - elems *vector.Vector + elems []interface{} } type parseError struct { @@ -162,7 +161,7 @@ // put text into an item text = text[0 : len(text)-len(tmpl.otag)] - section.elems.Push(&textElement{[]byte(text)}) + section.elems = append(section.elems, &textElement{[]byte(text)}) if tmpl.p < len(tmpl.data) && tmpl.data[tmpl.p] == '{' { text, err = tmpl.readString("}" + tmpl.ctag) } else { @@ -194,12 +193,12 @@ tmpl.p += 2 } - se := sectionElement{name, tag[0] == '^', tmpl.curline, new(vector.Vector)} + se := sectionElement{name, tag[0] == '^', tmpl.curline, []interface{}{}} err := tmpl.parseSection(&se) if err != nil { return err } - section.elems.Push(&se) + section.elems = append(section.elems, &se) case '/': name := strings.TrimSpace(tag[1:]) if name != section.name { @@ -213,7 +212,7 @@ if err != nil { return err } - section.elems.Push(partial) + section.elems = append(section.elems, partial) case '=': if tag[len(tag)-1] != '=' { return parseError{tmpl.curline, "Invalid meta tag"} @@ -227,10 +226,10 @@ case '{': if tag[len(tag)-1] == '}' { //use a raw tag - section.elems.Push(&varElement{tag[1 : len(tag)-1], true}) + section.elems = append(section.elems, &varElement{tag[1 : len(tag)-1], true}) } default: - section.elems.Push(&varElement{tag, false}) + section.elems = append(section.elems, &varElement{tag, false}) } } @@ -240,16 +239,15 @@ func (tmpl *Template) parse() os.Error { for { text, err := tmpl.readString(tmpl.otag) - if err == os.EOF { //put the remaining text in a block - tmpl.elems.Push(&textElement{[]byte(text)}) + tmpl.elems = append(tmpl.elems, &textElement{[]byte(text)}) return nil } // put text into an item text = text[0 : len(text)-len(tmpl.otag)] - tmpl.elems.Push(&textElement{[]byte(text)}) + tmpl.elems = append(tmpl.elems, &textElement{[]byte(text)}) if tmpl.p < len(tmpl.data) && tmpl.data[tmpl.p] == '{' { text, err = tmpl.readString("}" + tmpl.ctag) @@ -280,12 +278,12 @@ tmpl.p += 2 } - se := sectionElement{name, tag[0] == '^', tmpl.curline, new(vector.Vector)} + se := sectionElement{name, tag[0] == '^', tmpl.curline, []interface{}{}} err := tmpl.parseSection(&se) if err != nil { return err } - tmpl.elems.Push(&se) + tmpl.elems = append(tmpl.elems, &se) case '/': return parseError{tmpl.curline, "unmatched close tag"} case '>': @@ -294,7 +292,7 @@ if err != nil { return err } - tmpl.elems.Push(partial) + tmpl.elems = append(tmpl.elems, partial) case '=': if tag[len(tag)-1] != '=' { return parseError{tmpl.curline, "Invalid meta tag"} @@ -308,10 +306,10 @@ case '{': //use a raw tag if tag[len(tag)-1] == '}' { - tmpl.elems.Push(&varElement{tag[1 : len(tag)-1], true}) + tmpl.elems = append(tmpl.elems, &varElement{tag[1 : len(tag)-1], true}) } default: - tmpl.elems.Push(&varElement{tag, false}) + tmpl.elems = append(tmpl.elems, &varElement{tag, false}) } } @@ -369,16 +367,16 @@ // Evaluate interfaces and pointers looking for a value that can look up the name, via a // struct field, method, or map key, and return the result of the lookup. -func lookup(contextChain *vector.Vector, name string) (reflect.Value) { +func lookup(contextChain []interface{}, name string) reflect.Value { defer func() { if r := recover(); r != nil { - fmt.Printf("Panic while looking up %s - %s", name, r) + fmt.Printf("Panic while looking up %q: %s\n", name, r) } }() - + Outer: - for i := contextChain.Len() - 1; i >= 0; i-- { - v := contextChain.At(i).(reflect.Value) + for _, ctx := range contextChain { //i := len(contextChain) - 1; i >= 0; i-- { + v := ctx.(reflect.Value) for v.IsValid() { typ := v.Type() if n := v.Type().NumMethod(); n > 0 { @@ -449,10 +447,10 @@ return v } -func renderSection(section *sectionElement, contextChain *vector.Vector, buf io.Writer) { +func renderSection(section *sectionElement, contextChain []interface{}, buf io.Writer) { value := lookup(contextChain, section.name) - var context = contextChain.At(contextChain.Len() - 1).(reflect.Value) - var contexts = new(vector.Vector) + var context = contextChain[len(contextChain)-1].(reflect.Value) + var contexts = []interface{}{} // if the value is nil, check if it's an inverted section isNil := isNil(value) if isNil && !section.inverted || !isNil && section.inverted { @@ -462,36 +460,42 @@ switch val := valueInd; val.Kind() { case reflect.Slice: for i := 0; i < val.Len(); i++ { - contexts.Push(val.Index(i)) + contexts = append(contexts, val.Index(i)) } case reflect.Array: for i := 0; i < val.Len(); i++ { - contexts.Push(val.Index(i)) + contexts = append(contexts, val.Index(i)) } case reflect.Map, reflect.Struct: - contexts.Push(value) + contexts = append(contexts, value) default: - contexts.Push(context) + contexts = append(contexts, context) } } + chain2 := make([]interface{}, len(contextChain)+1) + copy(chain2[1:], contextChain) //by default we execute the section - for j := 0; j < contexts.Len(); j++ { - ctx := contexts.At(j).(reflect.Value) - contextChain.Push(ctx) - for i := 0; i < section.elems.Len(); i++ { - renderElement(section.elems.At(i), contextChain, buf) + for _, ctx := range contexts { + chain2[0] = ctx + for _, elem := range section.elems { + renderElement(elem, chain2, buf) } - contextChain.Pop() } } -func renderElement(element interface{}, contextChain *vector.Vector, buf io.Writer) { +func renderElement(element interface{}, contextChain []interface{}, buf io.Writer) { switch elem := element.(type) { case *textElement: buf.Write(elem.text) case *varElement: + defer func() { + if r := recover(); r != nil { + fmt.Printf("Panic while looking up %q: %s\n", elem.name, r) + } + }() val := lookup(contextChain, elem.name) + if val.IsValid() { if elem.raw { fmt.Fprint(buf, val.Interface()) @@ -507,26 +511,34 @@ } } -func (tmpl *Template) renderTemplate(contextChain *vector.Vector, buf io.Writer) { - for i := 0; i < tmpl.elems.Len(); i++ { - renderElement(tmpl.elems.At(i), contextChain, buf) +func (tmpl *Template) renderTemplate(contextChain []interface{}, buf io.Writer) { + for _, elem := range tmpl.elems { + renderElement(elem, contextChain, buf) } } func (tmpl *Template) Render(context ...interface{}) string { var buf bytes.Buffer - var contextChain vector.Vector + var contextChain []interface{} for _, c := range context { val := reflect.ValueOf(c) - contextChain.Push(val) + contextChain = append(contextChain, val) } - tmpl.renderTemplate(&contextChain, &buf) + tmpl.renderTemplate(contextChain, &buf) return buf.String() } +func (tmpl *Template) RenderInLayout(layout *Template, context ...interface{}) string { + content := tmpl.Render(context...) + allContext := make([]interface{}, len(context)+1) + copy(allContext[1:], context) + allContext[0] = map[string]string{"content": content} + return layout.Render(allContext...) +} + func ParseString(data string) (*Template, os.Error) { cwd := os.Getenv("CWD") - tmpl := Template{data, "{{", "}}", 0, 1, cwd, new(vector.Vector)} + tmpl := Template{data, "{{", "}}", 0, 1, cwd, []interface{}{}} err := tmpl.parse() if err != nil { @@ -544,7 +556,7 @@ dirname, _ := path.Split(filename) - tmpl := Template{string(data), "{{", "}}", 0, 1, dirname, new(vector.Vector)} + tmpl := Template{string(data), "{{", "}}", 0, 1, dirname, []interface{}{}} err = tmpl.parse() if err != nil { @@ -556,20 +568,41 @@ func Render(data string, context ...interface{}) string { tmpl, err := ParseString(data) - if err != nil { return err.String() } - return tmpl.Render(context...) } +func RenderInLayout(data string, layoutData string, context ...interface{}) string { + layoutTmpl, err := ParseString(layoutData) + if err != nil { + return err.String() + } + tmpl, err := ParseString(data) + if err != nil { + return err.String() + } + return tmpl.RenderInLayout(layoutTmpl, context...) +} + func RenderFile(filename string, context ...interface{}) string { tmpl, err := ParseFile(filename) + if err != nil { + return err.String() + } + return tmpl.Render(context...) +} +func RenderFileInLayout(filename string, layoutFile string, context ...interface{}) string { + layoutTmpl, err := ParseFile(layoutFile) if err != nil { return err.String() } - return tmpl.Render(context...) + tmpl, err := ParseFile(filename) + if err != nil { + return err.String() + } + return tmpl.RenderInLayout(layoutTmpl, context...) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mustache.go/mustache_test.go new/mustache.go/mustache_test.go --- old/mustache.go/mustache_test.go 2011-08-13 12:11:15.000000000 +0200 +++ new/mustache.go/mustache_test.go 2012-02-09 13:21:10.000000000 +0100 @@ -15,8 +15,8 @@ } type Data struct { - a bool - b string + A bool + B string } type User struct { @@ -48,7 +48,6 @@ return &settings{true}, nil } - func (u *User) Func6() (*vector.Vector, os.Error) { var v vector.Vector v.Push(&settings{true}) @@ -71,6 +70,15 @@ return v } +type Category struct { + Tag string + Description string +} + +func (c Category) DisplayName() string { + return c.Tag + " - " + c.Description +} + var tests = []Test{ {`hello world`, nil, "hello world"}, {`hello {{name}}`, map[string]string{"name": "world"}, "hello world"}, @@ -89,21 +97,21 @@ {`{{#has}}{{/has}}`, &User{"Mike", 1}, ""}, //section tests - {`{{#a}}{{b}}{{/a}}`, Data{true, "hello"}, "hello"}, - {`{{#a}}{{{b}}}{{/a}}`, Data{true, "5 > 2"}, "5 > 2"}, - {`{{#a}}{{b}}{{/a}}`, Data{true, "5 > 2"}, "5 > 2"}, - {`{{#a}}{{b}}{{/a}}`, Data{false, "hello"}, ""}, + {`{{#A}}{{B}}{{/A}}`, Data{true, "hello"}, "hello"}, + {`{{#A}}{{{B}}}{{/A}}`, Data{true, "5 > 2"}, "5 > 2"}, + {`{{#A}}{{B}}{{/A}}`, Data{true, "5 > 2"}, "5 > 2"}, + {`{{#A}}{{B}}{{/A}}`, Data{false, "hello"}, ""}, {`{{a}}{{#b}}{{b}}{{/b}}{{c}}`, map[string]string{"a": "a", "b": "b", "c": "c"}, "abc"}, - {`{{#a}}{{b}}{{/a}}`, struct { - a []struct { - b string + {`{{#A}}{{B}}{{/A}}`, struct { + A []struct { + B string } }{[]struct { - b string + B string }{{"a"}, {"b"}, {"c"}}}, "abc", }, - {`{{#a}}{{b}}{{/a}}`, struct{ a []map[string]string }{[]map[string]string{{"b": "a"}, {"b": "b"}, {"b": "c"}}}, "abc"}, + {`{{#A}}{{b}}{{/A}}`, struct{ A []map[string]string }{[]map[string]string{{"b": "a"}, {"b": "b"}, {"b": "c"}}}, "abc"}, {`{{#users}}{{Name}}{{/users}}`, map[string]interface{}{"users": []User{{"Mike", 1}}}, "Mike"}, @@ -145,6 +153,9 @@ {`hello {{#section}}{{name}}{{/section}}`, map[string]interface{}{"name": "bob", "section": map[string]string{"name": "world"}}, "hello world"}, {`hello {{#bool}}{{#section}}{{name}}{{/section}}{{/bool}}`, map[string]interface{}{"bool": true, "section": map[string]string{"name": "world"}}, "hello world"}, {`{{#users}}{{canvas}}{{/users}}`, map[string]interface{}{"canvas": "hello", "users": []User{{"Mike", 1}}}, "hello"}, + {`{{#categories}}{{DisplayName}}{{/categories}}`, map[string][]*Category{ + "categories": {&Category{"a", "b"}}, + }, "a - b"}, } func TestBasic(t *testing.T) { @@ -184,14 +195,13 @@ } func TestMultiContext(t *testing.T) { - output := Render(`{{hello}} {{world}}`, map[string]string{"hello": "hello"}, struct{ world string }{"world"}) - output2 := Render(`{{hello}} {{world}}`, struct{ world string }{"world"}, map[string]string{"hello": "hello"}) + output := Render(`{{hello}} {{World}}`, map[string]string{"hello": "hello"}, struct{ World string }{"world"}) + output2 := Render(`{{hello}} {{World}}`, struct{ World string }{"world"}, map[string]string{"hello": "hello"}) if output != "hello world" || output2 != "hello world" { t.Fatalf("TestMultiContext expected %q got %q", "hello world", output) } } - var malformed = []Test{ {`{{#a}}{{}}{{/a}}`, Data{true, "hello"}, "empty tag"}, {`{{}}`, nil, "empty tag"}, @@ -207,3 +217,27 @@ } } } + +type LayoutTest struct { + layout string + tmpl string + context interface{} + expected string +} + +var layoutTests = []LayoutTest{ + {`Header {{content}} Footer`, `Hello World`, nil, `Header Hello World Footer`}, + {`Header {{content}} Footer`, `Hello {{s}}`, map[string]string{"s": "World"}, `Header Hello World Footer`}, + {`Header {{content}} Footer`, `Hello {{content}}`, map[string]string{"content": "World"}, `Header Hello World Footer`}, + {`Header {{extra}} {{content}} Footer`, `Hello {{content}}`, map[string]string{"content": "World", "extra": "extra"}, `Header extra Hello World Footer`}, + {`Header {{content}} {{content}} Footer`, `Hello {{content}}`, map[string]string{"content": "World"}, `Header Hello World Hello World Footer`}, +} + +func TestLayout(t *testing.T) { + for _, test := range layoutTests { + output := RenderInLayout(test.tmpl, test.layout, test.context) + if output != test.expected { + t.Fatalf("%q expected %q got %q", test.tmpl, test.expected, output) + } + } +} ++++++ opensuse-build-fix.patch ++++++ diff --git a/mustache.go b/mustache.go index a4ed68e..67a6e91 100644 --- a/mustache.go +++ b/mustache.go @@ -2,6 +2,7 @@ package mustache import ( "bytes" + "errors" "fmt" "io" "io/ioutil" @@ -42,7 +43,7 @@ type parseError struct { message string } -func (p parseError) String() string { return fmt.Sprintf("line %d: %s", p.line, p.message) } +func (p parseError) Error() string { return fmt.Sprintf("line %d: %s", p.line, p.message) } var ( esc_quot = []byte(""") @@ -78,13 +79,13 @@ func htmlEscape(w io.Writer, s []byte) { w.Write(s[last:]) } -func (tmpl *Template) readString(s string) (string, os.Error) { +func (tmpl *Template) readString(s string) (string, error) { i := tmpl.p newlines := 0 for true { //are we at the end of the string? if i+len(s) > len(tmpl.data) { - return tmpl.data[tmpl.p:], os.EOF + return tmpl.data[tmpl.p:], io.EOF } if tmpl.data[i] == '\n' { @@ -120,7 +121,7 @@ func (tmpl *Template) readString(s string) (string, os.Error) { return "", nil } -func (tmpl *Template) parsePartial(name string) (*Template, os.Error) { +func (tmpl *Template) parsePartial(name string) (*Template, error) { filenames := []string{ path.Join(tmpl.dir, name), path.Join(tmpl.dir, name+".mustache"), @@ -139,7 +140,7 @@ func (tmpl *Template) parsePartial(name string) (*Template, os.Error) { } } if filename == "" { - return nil, os.NewError(fmt.Sprintf("Could not find partial %q", name)) + return nil, errors.New(fmt.Sprintf("Could not find partial %q", name)) } partial, err := ParseFile(filename) @@ -151,11 +152,11 @@ func (tmpl *Template) parsePartial(name string) (*Template, os.Error) { return partial, nil } -func (tmpl *Template) parseSection(section *sectionElement) os.Error { +func (tmpl *Template) parseSection(section *sectionElement) error { for { text, err := tmpl.readString(tmpl.otag) - if err == os.EOF { + if err == io.EOF { return parseError{section.startline, "Section " + section.name + " has no closing tag"} } @@ -168,7 +169,7 @@ func (tmpl *Template) parseSection(section *sectionElement) os.Error { text, err = tmpl.readString(tmpl.ctag) } - if err == os.EOF { + if err == io.EOF { //put the remaining text in a block return parseError{tmpl.curline, "unmatched open tag"} } @@ -236,10 +237,10 @@ func (tmpl *Template) parseSection(section *sectionElement) os.Error { return nil } -func (tmpl *Template) parse() os.Error { +func (tmpl *Template) parse() error { for { text, err := tmpl.readString(tmpl.otag) - if err == os.EOF { + if err == io.EOF { //put the remaining text in a block tmpl.elems = append(tmpl.elems, &textElement{[]byte(text)}) return nil @@ -255,7 +256,7 @@ func (tmpl *Template) parse() os.Error { text, err = tmpl.readString(tmpl.ctag) } - if err == os.EOF { + if err == io.EOF { //put the remaining text in a block return parseError{tmpl.curline, "unmatched open tag"} } @@ -536,7 +537,7 @@ func (tmpl *Template) RenderInLayout(layout *Template, context ...interface{}) s return layout.Render(allContext...) } -func ParseString(data string) (*Template, os.Error) { +func ParseString(data string) (*Template, error) { cwd := os.Getenv("CWD") tmpl := Template{data, "{{", "}}", 0, 1, cwd, []interface{}{}} err := tmpl.parse() @@ -548,7 +549,7 @@ func ParseString(data string) (*Template, os.Error) { return &tmpl, err } -func ParseFile(filename string) (*Template, os.Error) { +func ParseFile(filename string) (*Template, error) { data, err := ioutil.ReadFile(filename) if err != nil { return nil, err @@ -569,7 +570,7 @@ func ParseFile(filename string) (*Template, os.Error) { func Render(data string, context ...interface{}) string { tmpl, err := ParseString(data) if err != nil { - return err.String() + return err.Error() } return tmpl.Render(context...) } @@ -577,11 +578,11 @@ func Render(data string, context ...interface{}) string { func RenderInLayout(data string, layoutData string, context ...interface{}) string { layoutTmpl, err := ParseString(layoutData) if err != nil { - return err.String() + return err.Error() } tmpl, err := ParseString(data) if err != nil { - return err.String() + return err.Error() } return tmpl.RenderInLayout(layoutTmpl, context...) } @@ -589,7 +590,7 @@ func RenderInLayout(data string, layoutData string, context ...interface{}) stri func RenderFile(filename string, context ...interface{}) string { tmpl, err := ParseFile(filename) if err != nil { - return err.String() + return err.Error() } return tmpl.Render(context...) } @@ -597,12 +598,12 @@ func RenderFile(filename string, context ...interface{}) string { func RenderFileInLayout(filename string, layoutFile string, context ...interface{}) string { layoutTmpl, err := ParseFile(layoutFile) if err != nil { - return err.String() + return err.Error() } tmpl, err := ParseFile(filename) if err != nil { - return err.String() + return err.Error() } return tmpl.RenderInLayout(layoutTmpl, context...) } -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
