Introduce "do" tag from Twig
Hello,
I was wondering if you thought about implementing do tag from twig - recently I wanted to modify a list in Pebble and I ended up using hacks like this:
{% set arr = [] %}
{{ arr.add("item") ? "" : "" }}
With do tag I could do it like this:
{% set arr = [] %}
{% do arr.add("item") %}
Or maybe there is another solution? If no, I would be happy to help with implementing the do tag.
Perhaps you could make something using this? https://pebbletemplates.io/wiki/guide/extending-pebble/#tags
I made one for you.
Create DoTokenParser.java from this code:
import com.mitchellbosecke.pebble.extension.NodeVisitor;
import com.mitchellbosecke.pebble.lexer.Token;
import com.mitchellbosecke.pebble.lexer.TokenStream;
import com.mitchellbosecke.pebble.node.AbstractRenderableNode;
import com.mitchellbosecke.pebble.node.RenderableNode;
import com.mitchellbosecke.pebble.node.expression.Expression;
import com.mitchellbosecke.pebble.parser.Parser;
import com.mitchellbosecke.pebble.template.EvaluationContextImpl;
import com.mitchellbosecke.pebble.template.PebbleTemplateImpl;
import com.mitchellbosecke.pebble.tokenParser.TokenParser;
import java.io.Writer;
public class DoTokenParser implements TokenParser {
public static class DoNode extends AbstractRenderableNode {
public final Expression<?> expression;
public DoNode(int lineNumber, Expression<?> expression) {
super(lineNumber);
this.expression = expression;
}
@Override
public void render(PebbleTemplateImpl self, Writer writer, EvaluationContextImpl context) {
expression.evaluate(self, context);
}
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
}
public String getTag() {
return "do";
}
@Override
public RenderableNode parse(Token token, Parser parser) {
TokenStream stream = parser.getStream();
int lineNumber = token.getLineNumber();
// skip the "do" token
stream.next();
// use the built in expression parser to parse the expression
Expression<?> expression = parser.getExpressionParser().parseExpression();
// expect to see "%}"
stream.expect(Token.Type.EXECUTE_END);
return new DoNode(lineNumber, expression);
}
}
And then use this on your PebbleEngine builder:
.extension(new AbstractExtension() {
@Override
public List<TokenParser> getTokenParsers() {
return Collections.singletonList(new DoTokenParser());
}
})
Yes, I thought about it but I think it might be useful for others too so instead of using extensions I suggested adding this to the core library.
Anyway, thanks for your help :)