diff --git a/element.go b/element.go index 5c6ad0c..60dd4a6 100644 --- a/element.go +++ b/element.go @@ -13,6 +13,7 @@ const ( TypeBlock = "block" TypeExpression = "expression" TypeLiteral = "literal" + TypeInclude = "include" ) var ( @@ -53,7 +54,7 @@ func (e *Element) parse() error { return errors.New(fmt.Sprintf("The element has no tokens. (line no: %d)", e.LineNo)) } switch { - case e.Type == TypeContent || e.Type == TypeBlock || e.Type == TypeExpression || e.Type == TypeLiteral || e.comment(): + case e.Type == TypeContent || e.Type == TypeBlock || e.Type == TypeExpression || e.Type == TypeLiteral || e.Type == TypeInclude || e.comment(): default: for i, token := range e.Tokens { switch { @@ -215,6 +216,21 @@ func (e *Element) Html(bf *bytes.Buffer) error { return errors.New(fmt.Sprintf("The sub template does not have the %s block.", name)) } block.Html(bf) + case e.Type == TypeInclude: + if len(e.Tokens) < 2 { + return errors.New(fmt.Sprintf("The include element does not have a path. (line no: %d)", e.LineNo)) + } + tpl := e.getTemplate() + g := tpl.Generator + incTpl, err := g.Parse(tpl.Dir() + e.Tokens[1] + goldExtension) + if err != nil { + return err + } + incHtml, err := incTpl.Html() + if err != nil { + return err + } + bf.WriteString(incHtml) default: e.writeOpenTag(bf) if e.hasTextValues() { @@ -341,6 +357,8 @@ func (e *Element) setType() { e.Type = TypeContent case len(e.Tokens) > 0 && e.Tokens[0] == "block": e.Type = TypeBlock + case len(e.Tokens) > 0 && e.Tokens[0] == "include": + e.Type = TypeInclude case len(e.Tokens) > 0 && e.Tokens[0] == "|": e.Type = TypeLiteral case expression(e.Text): diff --git a/element_test.go b/element_test.go index b22e168..a9a3a7a 100644 --- a/element_test.go +++ b/element_test.go @@ -36,14 +36,14 @@ func TestElementParse(t *testing.T) { t.Errorf("Error(%s) occurred.", err.Error()) } - // When an element's type is TypeExpression. + // When an element's type is TypeLiteral. e = &Element{Tokens: []string{"test"}, Type: TypeLiteral} err = e.parse() if err != nil { t.Errorf("Error(%s) occurred.", err.Error()) } - // When an element's type is TypeExpression. + // When an element's type is TypeTag. e, err = NewElement("div data-test=test test test2", 1, 0, nil, nil, nil) if err != nil { t.Errorf("Error(%s) occurred.", err.Error()) @@ -397,6 +397,43 @@ func TestElementHtml(t *testing.T) { if bf.String() != expectedString { t.Errorf("Buffer stirng should be %s", expectedString) } + + // When the element's type is include and tokens' length < 2. + e, err = NewElement("include", 1, 0, nil, nil, nil) + expectedErrMsg = fmt.Sprintf("The include element does not have a path. (line no: %d)", e.LineNo) + if err := e.Html(&bf); err == nil || err.Error() != expectedErrMsg { + t.Errorf("Error(%s) should be returned.", expectedErrMsg) + } + + // When the element's type is include and g.Parse returns an error. + g := NewGenerator(false) + tpl = NewTemplate("path", g) + e, err = NewElement("include ./somepath/somefile", 1, 0, nil, tpl, nil) + bf = bytes.Buffer{} + expectedErrMsg = "open ././somepath/somefile.gold: no such file or directory" + if err := e.Html(&bf); err == nil || err.Error() != expectedErrMsg { + t.Errorf("Error(%s) should be returned.", expectedErrMsg) + } + + // When the element's type is include and incTpl.Html returns an error. + g = NewGenerator(false) + tpl = NewTemplate("./test/TestElementHtml/somefile.gold", g) + e, err = NewElement("include ./001", 1, 0, nil, tpl, nil) + bf = bytes.Buffer{} + expectedErrMsg = "The block element does not have a name. (line no: 1)" + if err := e.Html(&bf); err == nil || err.Error() != expectedErrMsg { + t.Errorf("Error(%s) should be returned.", expectedErrMsg) + } + + // When the element's type is include. + g = NewGenerator(false) + tpl = NewTemplate("./test/TestElementHtml/somefile.gold", g) + e, err = NewElement("include ./002", 1, 0, nil, tpl, nil) + bf = bytes.Buffer{} + if err := e.Html(&bf); err != nil { + t.Errorf("An error(%s) occurred.", err.Error()) + } + } func TestElementWriteOpenTag(t *testing.T) { @@ -611,6 +648,13 @@ func TestElementSetType(t *testing.T) { if e.Type != TypeTag { t.Errorf("Type should be %s", TypeTag) } + + // When the element's text is an include element. + e = &Element{Tokens: []string{"include"}} + e.setType() + if e.Type != TypeInclude { + t.Errorf("Type should be %s", TypeInclude) + } } func TestElementGetBlock(t *testing.T) { diff --git a/test/TestElementHtml/001.gold b/test/TestElementHtml/001.gold new file mode 100644 index 0000000..48cf2ad --- /dev/null +++ b/test/TestElementHtml/001.gold @@ -0,0 +1 @@ +block diff --git a/test/TestElementHtml/002.gold b/test/TestElementHtml/002.gold new file mode 100644 index 0000000..190303d --- /dev/null +++ b/test/TestElementHtml/002.gold @@ -0,0 +1,2 @@ +#container + | aaa