Skip to content

Commit

Permalink
ifchanged-tag added.
Browse files Browse the repository at this point in the history
  • Loading branch information
flosch committed Jul 29, 2014
1 parent 1deab40 commit be02e47
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 5 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ Please use the [issue tracker](https://github.com/flosch/pongo2/issues) if you'r

Please also have a look on the [caveats](https://github.com/flosch/pongo2#caveats) and on the [official add-ons](https://github.com/flosch/pongo2#official).

## New in pongo2
## Features (and new in pongo2)

* Entirely rewritten from the ground-up.
* [Easy API to create new filters and tags](http://godoc.org/github.com/flosch/pongo2#RegisterFilter) ([including parsing arguments](http://godoc.org/github.com/flosch/pongo2#Parser)); take a look on an example and the differences between pongo1 and pongo2: [old](https://github.com/flosch/pongo/blob/master/filters.go#L65) and [new](https://github.com/flosch/pongo2/blob/master/filters_builtin.go#L72).
* [Advanced C-like expressions](https://github.com/flosch/pongo2/blob/master/template_tests/expressions.tpl).
* [Complex function calls within expressions](https://github.com/flosch/pongo2/blob/master/template_tests/function_calls_wrapper.tpl).
* Additional features
* Macros (see [template_tests/macro.tpl](https://github.com/flosch/pongo2/blob/master/template_tests/macro.tpl))
* [Easy API to create new filters and tags](http://godoc.org/github.com/flosch/pongo2#RegisterFilter) ([including parsing arguments](http://godoc.org/github.com/flosch/pongo2#Parser))
* Additional features:
* Macros (see [template_tests/macro.tpl](https://github.com/flosch/pongo2/blob/master/template_tests/macro.tpl))

## Recent API changes within pongo2

Expand Down
26 changes: 26 additions & 0 deletions pongo2_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,32 @@ Yep!`,
Text: "<b>hello!</b> there",
},
},
"comments2": []*comment{
&comment{
Author: &user{
Name: "user1",
Validated: true,
},
Date: time2,
Text: "\"pongo2 is nice!\"",
},
&comment{
Author: &user{
Name: "user1",
Validated: true,
},
Date: time1,
Text: "comment2 with <script>unsafe</script> tags in it",
},
&comment{
Author: &user{
Name: "user3",
Validated: false,
},
Date: time1,
Text: "<b>hello!</b> there",
},
},
},
}

Expand Down
117 changes: 117 additions & 0 deletions tags_ifchanged.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package pongo2

import (
"bytes"
)

type tagIfchangedNode struct {
watched_expr []INodeEvaluator
last_values []*Value
last_content []byte
thenWrapper *NodeWrapper
elseWrapper *NodeWrapper
}

func (node *tagIfchangedNode) Execute(ctx *ExecutionContext, buffer *bytes.Buffer) error {

if len(node.watched_expr) == 0 {
// Check against own rendered body

buf := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB
err := node.thenWrapper.Execute(ctx, buf)
if err != nil {
return err
}

buf_bytes := buf.Bytes()
if !bytes.Equal(node.last_content, buf_bytes) {
// Rendered content changed, output it
buffer.Write(buf_bytes)
node.last_content = buf_bytes
}
} else {
now_values := make([]*Value, 0, len(node.watched_expr))
for _, expr := range node.watched_expr {
val, err := expr.Evaluate(ctx)
if err != nil {
return err
}
now_values = append(now_values, val)
}

// Compare old to new values now
changed := len(node.last_values) == 0

for idx, old_val := range node.last_values {
if !old_val.EqualValueTo(now_values[idx]) {
changed = true
break // we can stop here because ONE value changed
}
}

node.last_values = now_values

if changed {
// Render thenWrapper
err := node.thenWrapper.Execute(ctx, buffer)
if err != nil {
return err
}
} else {
// Render elseWrapper
err := node.elseWrapper.Execute(ctx, buffer)
if err != nil {
return err
}
}
}

return nil
}

func tagIfchangedParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, error) {
ifchanged_node := &tagIfchangedNode{}

for arguments.Remaining() > 0 {
// Parse condition
expr, err := arguments.ParseExpression()
if err != nil {
return nil, err
}
ifchanged_node.watched_expr = append(ifchanged_node.watched_expr, expr)
}

if arguments.Remaining() > 0 {
return nil, arguments.Error("Ifchanged-arguments are malformed.", nil)
}

// Wrap then/else-blocks
wrapper, endargs, err := doc.WrapUntilTag("else", "endifchanged")
if err != nil {
return nil, err
}
ifchanged_node.thenWrapper = wrapper

if endargs.Count() > 0 {
return nil, endargs.Error("Arguments not allowed here.", nil)
}

if wrapper.Endtag == "else" {
// if there's an else in the if-statement, we need the else-Block as well
wrapper, endargs, err = doc.WrapUntilTag("endifchanged")
if err != nil {
return nil, err
}
ifchanged_node.elseWrapper = wrapper

if endargs.Count() > 0 {
return nil, endargs.Error("Arguments not allowed here.", nil)
}
}

return ifchanged_node, nil
}

func init() {
RegisterTag("ifchanged", tagIfchangedParser)
}
2 changes: 1 addition & 1 deletion tags_spaceless.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

type tagSpacelessNode struct {
wrapper *NodeWrapper
wrapper *NodeWrapper
}

var tagSpacelessRegexp = regexp.MustCompile(`(?U:(<.*>))([\t\n\v\f\r ]+)(?U:(<.*>))`)
Expand Down
9 changes: 9 additions & 0 deletions template_tests/ifchanged.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% for comment in complex.comments2 %}
{% ifchanged %}New comment from another user {{ comment.Author.Name }}{% endifchanged %}
{% ifchanged comment.Author.Validated %}
Validated changed to {{ comment.Author.Validated }}
{% else %}
Validated value not changed
{% endifchanged %}
{% ifchanged comment.Author.Name comment.Date %}Comment's author name or date changed{% endifchanged %}
{% endfor %}
18 changes: 18 additions & 0 deletions template_tests/ifchanged.tpl.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

New comment from another user user1

Validated changed to True

Comment's author name or date changed



Validated value not changed

Comment's author name or date changed

New comment from another user user3

Validated changed to False

Comment's author name or date changed

0 comments on commit be02e47

Please sign in to comment.