Skip to content

Commit

Permalink
Add support for parameters in Jekyll include tag
Browse files Browse the repository at this point in the history
Fixes #194
  • Loading branch information
kohlschuetter authored and msangel committed Nov 19, 2022
1 parent 1900a45 commit a48b5f8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
19 changes: 15 additions & 4 deletions src/main/java/liqp/parser/v4/NodeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
import liqp.exceptions.LiquidException;
import liqp.filters.Filter;
import liqp.Insertion;
import liqp.nodes.BlockNode;
import liqp.nodes.*;
import liqp.parser.Flavor;
import liquid.parser.v4.LiquidParserBaseVisitor;
import liquid.parser.v4.LiquidParser.Jekyll_include_paramsContext;

import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.TerminalNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import static liquid.parser.v4.LiquidParser.*;

Expand Down Expand Up @@ -379,19 +381,28 @@ public LNode visitCapture_tag_Str(Capture_tag_StrContext ctx) {
// ;
@Override
public LNode visitInclude_tag(Include_tagContext ctx) {
if (ctx.jekyll!=null) {
return new InsertionNode(insertions.get("include"), visit(ctx.file_name_or_output()));
if (ctx.jekyll != null) {
Stream<? extends LNode> stream = Stream.concat( //
Stream.of(visit(ctx.file_name_or_output())), //
ctx.jekyll_include_params().stream().map(this::visitJekyll_include_params) //
);

return new InsertionNode(insertions.get("include"), stream.toArray((n) -> new LNode[n]));
} else if (ctx.liquid != null) {
if (ctx.Str() != null) {
return new InsertionNode(insertions.get("include"), visit(ctx.expr()), new AtomNode(strip(ctx.Str().getText())));
} else {
return new InsertionNode(insertions.get("include"), visit(ctx.expr()));
}

}
throw new LiquidException("Unknown syntax of `Include` tag", ctx);
}

@Override
public LNode visitJekyll_include_params(Jekyll_include_paramsContext ctx) {
return new KeyValueNode(ctx.id().getText(), visit(ctx.expr()));
}

// file_name_or_output
// : ...
// | output #jekyll_include_output
Expand Down
25 changes: 19 additions & 6 deletions src/main/java/liqp/tags/Include.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import liqp.Template;
import liqp.TemplateContext;
import liqp.nodes.LNode;
import liqp.parser.Flavor;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class Include extends Tag {

Expand All @@ -27,17 +30,27 @@ public Object render(TemplateContext context, LNode... nodes) {
includeResourceFile = new File(includesDirectory, includeResource + extension);
}
else {
includeResourceFile = new File(context.parseSettings.flavor.snippetsFolderName, includeResource + extension);
includeResourceFile = new File(context.parseSettings.flavor.snippetsFolderName, includeResource + extension);
}

Template template = Template.parse(includeResourceFile, context.parseSettings, context.renderSettings);

// check if there's a optional "with expression"
if(nodes.length > 1) {
Object value = nodes[1].render(context);
context.put(includeResource, value);
if (nodes.length > 1) {
if (context.parseSettings.flavor != Flavor.JEKYLL) {
// check if there's a optional "with expression"
Object value = nodes[1].render(context);
context.put(includeResource, value);
} else {
// Jekyll-style variable assignments
Map<String, Object> variables = new HashMap<String, Object>();
for (int i = 1, n = nodes.length; i < n; i++) {
@SuppressWarnings("unchecked")
Map<String, Object> var = (Map<String, Object>) nodes[i].render(context);
variables.putAll(var);
}
return template.renderUnguarded(variables, context, true);
}
}

return template.renderUnguarded(context);

} catch(Exception e) {
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/liqp/tags/IncludeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ public void testIncludeVariableSyntaxTag() {
assertEquals("TEST", res);
}

@Test
public void testIncludeWithExpression() {
Template template = Template.parse("{% include include_read_var var=otherVar %}", jekyll());
String res = template.render("{ \"otherVar\" : \"TEST\"}");
assertEquals("TEST", res);
}

@Test
public void testIncludeWithMultipleExpressions() {
Template template = Template.parse(
"{% include include_read_var foo=bar var=otherVar var=\"var\" var=yetAnotherVar %}", jekyll());
String res = template.render("{ \"otherVar\" : \"TEST\", \"yetAnotherVar\": \"ANOTHER\"}");
assertEquals("ANOTHER", res);
}

@Test(expected = LiquidException.class)
public void renderWithShouldThrowExceptionInJekyll() throws RecognitionException {

Expand Down

0 comments on commit a48b5f8

Please sign in to comment.