Skip to content

Commit

Permalink
Permit variables in Liquid-style tag 'include with' (#299)
Browse files Browse the repository at this point in the history
* Only String literals were permitted as parameter of `include with 'param'`
* Now it is possible to reference objects: `include with var`
  • Loading branch information
pmenhart authored Apr 24, 2024
1 parent 4d5600c commit 4854bbc
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 5 deletions.
2 changes: 2 additions & 0 deletions ruby/cases_include_with_syntax_with.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
else
Liquid::Template.file_system = Liquid::LocalFileSystem.new("cases_variable_inside_import/_includes", "%s.liquid")
assertEqual("color: 'red'", render({"var" => "there"}, "{% include 'color' with 'red' %}"))
assertEqual("color: 'blue'", render({"clr" => "blue"}, "{% include 'color' with clr %}"))
assertEqual("color: 'yellow'", render({}, "{% assign clr = 'yellow' %}{% include 'color' with clr %}"))
# liquid variable evaluate
assertEqual("there", render({"var" => "there", "tmpl" => "include_read_var"}, "{% include tmpl %}"))
end
Expand Down
2 changes: 1 addition & 1 deletion src/main/antlr4/liquid/parser/v4/LiquidParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ capture_tag
;

include_tag
: {isLiquidStyleInclude()}? TagStart liquid=Include expr (With Str)? TagEnd
: {isLiquidStyleInclude()}? TagStart liquid=Include expr (With expr)? TagEnd
| {isJekyllStyleInclude()}? TagStart jekyll=Include file_name_or_output (jekyll_include_params)* TagEnd
;

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/liqp/parser/v4/NodeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,10 @@ public LNode visitInclude_tag(Include_tagContext ctx) {
if (ctx.jekyll != null) {
return getJekyllIncludeInsertionNode("include", ctx.file_name_or_output(), ctx.jekyll_include_params());
} else if (ctx.liquid != null) {
if (ctx.Str() != null) {
return new InsertionNode(insertions.get("include"), visit(ctx.expr()), new AtomNode(strip(ctx.Str().getText())));
if (ctx.With() != null) {
return new InsertionNode(insertions.get("include"), visit(ctx.expr(0)), visit(ctx.expr(1)));
} else {
return new InsertionNode(insertions.get("include"), visit(ctx.expr()));
return new InsertionNode(insertions.get("include"), visit(ctx.expr(0)));
}
}
throw new LiquidException("Unknown syntax of `Include` tag", ctx);
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/liqp/parser/v4/LiquidParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,16 @@ public void testInclude_tag() {
equalTo(array("{%", "include", "some-file.extwithmu", "%}"))
);

assertThat(
texts("{% include some-file.ext with mu %}", "include_tag", true),
equalTo(array("{%", "include", "some-file.ext", "with", "mu", "%}"))
);

assertThat(
texts("{% include 'some-file.ext' with 'mu' %}", "include_tag", true),
equalTo(array("{%", "include", "'some-file.ext'", "with", "'mu'", "%}"))
);

assertThat(
texts("{% include {{variable}} %}", "include_tag", false),
equalTo(array("{%", "include", "{{variable}}", "%}"))
Expand Down
23 changes: 22 additions & 1 deletion src/test/java/liqp/tags/IncludeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public void renderTest() throws RecognitionException {
"{% include 'color' with 'red' %}\n" +
"{% include 'color' with 'blue' %}\n" +
"{% assign shape = 'square' %}\n" +
"{% include 'color' with 'red' %}";
"{% include 'color' with 'red' %}\n" +
"{%- assign cVar = 'yellow' %}\n" +
"{% include 'color' with cVar %}";

Template template = TemplateParser.DEFAULT.parse(source);

Expand All @@ -43,6 +45,8 @@ public void renderTest() throws RecognitionException {
"shape: 'circle'\n" +
"\n" +
"color: 'red'\n" +
"shape: 'square'\n" +
"color: 'yellow'\n" +
"shape: 'square'"));
}

Expand Down Expand Up @@ -107,6 +111,23 @@ public void renderWithShouldWorkInLiquid() throws RecognitionException {
assertEquals("color: 'red'\nshape: ''", render);
}

@Test
public void renderWithVariableShouldWorkInLiquid() throws RecognitionException {
TemplateParser parser = new TemplateParser.Builder() //
.withFlavor(Flavor.LIQUID)
.withShowExceptionsFromInclude(true)
.withErrorMode(TemplateParser.ErrorMode.STRICT)
.build();

Template template = parser.parse("{% assign c = 'blue' %}{% include 'color' with c %}");
String render = template.render();
assertEquals("color: 'blue'\nshape: ''", render);

template = parser.parse("{% include 'color' with theme.color %}");
render = template.render("{ \"theme\": {\"color\": \"orange\"}}");
assertEquals("color: 'orange'\nshape: ''", render);
}

@Test
public void renderTestWithIncludeDirectorySpecifiedInContextLiquidFlavor() throws Exception {
File jekyll = new File(new File("").getAbsolutePath(), "src/test/jekyll");
Expand Down

0 comments on commit 4854bbc

Please sign in to comment.