Skip to content

Commit

Permalink
Fix 179
Browse files Browse the repository at this point in the history
  • Loading branch information
msangel committed Dec 9, 2020
1 parent 40ac77f commit fb68a8a
Show file tree
Hide file tree
Showing 29 changed files with 368 additions and 27 deletions.
3 changes: 3 additions & 0 deletions _includes/include_iterations_variables.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
list: {{ list }}
inner: {{ inner }}
n: {{ n }}
1 change: 1 addition & 0 deletions _includes/include_read_var.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ var }}
66 changes: 66 additions & 0 deletions ruby/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## About this folder

This folder is a playground where developers can test original liquid/jekyll code with real ruby via docker machines without need of installing ruby on local machine, as well as these libraries.

### How to use
Simply write your ruby script and run it with predefined runners.

Run in jekyll: ` ./run_with_jekyll.sh your_script.rb`

Run in liquid: ` ./run_with_liquid.sh your_script.rb`

In fact, this may be same script, just unsure yourself you are safe in both cases:
```ruby

$is_Jekyll = false
begin
require "jekyll"
puts "testing cases using jekyll"
$is_Jekyll = true
rescue LoadError
require "liquid"
puts "testing cases using liquid"
end
def isJekyll
$is_Jekyll
end

# write your code here

if isJekyll
# add jekyll-specific code here
else
# add liquid-specific code here
end
```

For more complex tuning of *jekyll* environment, where the creation of `site` variable needed, here`s example how you can do that:
```ruby

config = Jekyll::Utils.deep_merge_hashes(Marshal.load(Marshal.dump(Jekyll::Configuration::DEFAULTS)), {
"destination" => "dest",
"incremental" => false,
"includes_dir" => "_includes",
"source" => ".",
"skip_config_files" => true,
"timezone" => "UTC",
"url" => "http://example.com",
"baseurl" => "/base",
"disable_disk_cache" => true
})
@site = Jekyll::Site.new(Jekyll::Configuration.from(config))
@context = Liquid::Context.new({}, {}, :site => @site)

def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(@context, data);
end
```

*Liquid* is more simple one:
```ruby
Liquid::Template.file_system = Liquid::LocalFileSystem.new("_includes/", "%s.liquid")

def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(data);
end
```
3 changes: 2 additions & 1 deletion ruby/_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ def build_configs(overrides, base_hash = default_configuration)
def site_configuration(overrides = {})
full_overrides = build_configs(overrides, build_configs(
"destination" => dest_dir,
"incremental" => false
"incremental" => false,
"disable_disk_cache" => true
))
Jekyll::Configuration.from(full_overrides.merge(
"source" => source_dir
Expand Down
1 change: 1 addition & 0 deletions ruby/cases_ifchanged_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(data);
end

pp render({}, "{% ifchanged %}1{% endifchanged %}{%for item in (1..4) %}{% ifchanged %}{{ item }}{% endifchanged %}{% endfor %}{% ifchanged %}4{% endifchanged %}{% ifchanged %}5{% endifchanged %}")
assertEqual("12345", render({}, "{% ifchanged %}1{% endifchanged %}{%for item in (1..4) %}{% ifchanged %}{{ item }}{% endifchanged %}{% endfor %}{% ifchanged %}4{% endifchanged %}{% ifchanged %}5{% endifchanged %}"))
6 changes: 4 additions & 2 deletions ruby/cases_increment_decrement_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(data);
end

assertEqual("-1-2-2", render({}, "{% decrement var %}{% decrement var %}{{ var }}"))
assertEqual("0152", render({}, "{% increment var %}{% assign var=5 %}{% increment var %}{{ var }}{% increment var %}"))
# assertEqual("-1-2-2", render({}, "{% decrement var %}{% decrement var %}{{ var }}"))
assertEqual("06", render({}, "{% increment var %}{% assign a = var | plus: 5 %}{{ a }}"))

# assertEqual("0152", render({}, "{% increment var %}{% assign var=5 %}{% increment var %}{{ var }}{% increment var %}"))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% assign incl_var = 'incl_var' %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% cycle 1,2,3,4 %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% decrement var1 %},{% increment var2 %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-->{% ifchanged %}2{% endifchanged %}<--
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ var }}
70 changes: 70 additions & 0 deletions ruby/cases_variable_inside_import/case.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env ruby

require 'pp'

$is_Jekyll = false
begin
require "jekyll"
puts "testing cases using jekyll"
$is_Jekyll = true
rescue LoadError
require "liquid"
puts "testing cases using liquid"
end
def isJekyll
$is_Jekyll
end

if isJekyll
config = Jekyll::Utils.deep_merge_hashes(Marshal.load(Marshal.dump(Jekyll::Configuration::DEFAULTS)), {
"destination" => "dest",
"incremental" => false,
"includes_dir" => "cases_variable_inside_import/_includes/",
"source" => ".",
"skip_config_files" => true,
"timezone" => "UTC",
"url" => "http://example.com",
"baseurl" => "/base",
"disable_disk_cache" => true
})
@site = Jekyll::Site.new(Jekyll::Configuration.from(config))
@context = Liquid::Context.new({}, {}, :site => @site)

def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(@context, data);
end

else
Liquid::Template.file_system = Liquid::LocalFileSystem.new("cases_variable_inside_import/_includes/", "%s.liquid")

def render(data = {}, source)
Liquid::Template.parse(source, {:strict_variables => true}).render!(data);
end
end

def assertEqual(expected, real)
if expected != real
raise "#{real} is not #{expected}"
end
end

# liquid requires template without extension
#
# tested: Decrement, Increment, Cycle, TableRow, ifchanged
# things to test: tags: , , For, ,
# visibility of variables from "with expression",
if isJekyll
assertEqual("variable", render({}, "{% assign var = 'variable' %}{% include include_read_var.liquid %}"));
assertEqual("incl_var", render({}, "{% include include_create_new_var.liquid %}{{ incl_var }}"))

# Like increment, variables declared inside decrement are independent from variables created through assign or capture.
assertEqual("[-1,0][-2,1][-3,2][-3, 3]", render({}, "[{% decrement var1 %},{% increment var2 %}][{% include include_decrement_var.liquid %}][{% decrement var1 %},{% increment var2 %}][{{ var1 }}, {{ var2 }}]"))
assertEqual("1234", render({}, "{% cycle 1,2,3,4 %}{% assign list = \"1\" | split: \",\" %}{% for n in list %}{% cycle 1,2,3,4 %}{% endfor %}{% cycle 1,2,3,4 %}{% include include_cycle.liquid %}"))
assertEqual("12--><--3", render({}, "{% ifchanged %}1{% endifchanged %}{% ifchanged %}2{% endifchanged %}{% include include_ifchanged.liquid %}{% ifchanged %}3{% endifchanged %}"))
else
assertEqual("variable", render({}, "{% assign var = 'variable' %}{% include 'include_read_var' %}"));
assertEqual("incl_var", render({}, "{% include 'include_create_new_var' %}{{ incl_var }}"))
assertEqual("[-1,0][-2,1][-3,2][-3, 3]", render({}, "[{% decrement var1 %},{% increment var2 %}][{% include 'include_decrement_var' %}][{% decrement var1 %},{% increment var2 %}][{{ var1 }}, {{ var2 }}]"))
assertEqual("1234", render({}, "{% cycle 1,2,3,4 %}{% assign list = \"1\" | split: \",\" %}{% for n in list %}{% cycle 1,2,3,4 %}{% endfor %}{% cycle 1,2,3,4 %}{% include 'include_cycle' %}"))
assertEqual("12--><--3", render({}, "{% ifchanged %}1{% endifchanged %}{% ifchanged %}2{% endifchanged %}{% include 'include_ifchanged' %}{% ifchanged %}3{% endifchanged %}"))
end
4 changes: 4 additions & 0 deletions ruby/docker_images/jekyll/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ RUN apk update && apk add --no-cache \
libc6-compat

RUN gem install jekyll
RUN gem install ruby-debug-ide

RUN mkdir -p /srv/jekyll
WORKDIR /srv/jekyll
VOLUME /srv/jekyll

EXPOSE 1234

# ENTRYPOINT ["sh"]
ENTRYPOINT ["ruby"]
1 change: 1 addition & 0 deletions ruby/docker_images/liquid/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ RUN apk update && apk add --no-cache \
libc6-compat

RUN gem install liquid
RUN gem install ruby-debug-ide

RUN mkdir -p /srv/liquid
WORKDIR /srv/liquid
Expand Down
1 change: 1 addition & 0 deletions ruby/run_with_jekyll.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ fi

docker run -it --rm --name jekyll \
--volume=$PWD:/srv/jekyll \
-p 1234:1234 \
ruby_with_jekyll \
$1
1 change: 1 addition & 0 deletions snippets/include_create_new_var.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% assign incl_var = 'incl_var' %}
1 change: 1 addition & 0 deletions snippets/include_cycle.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% cycle 1,2,3,4 %}
1 change: 1 addition & 0 deletions snippets/include_decrement_var.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% decrement var1 %},{% increment var2 %}
1 change: 1 addition & 0 deletions snippets/include_decrement_var_not_interfere.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% decrement var %}
1 change: 1 addition & 0 deletions snippets/include_ifchanged.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
>{% ifchanged %}2{% endifchanged %}<
1 change: 1 addition & 0 deletions snippets/include_iteration.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% for item in (1..2) %}{{ item }}{% endfor %}
1 change: 1 addition & 0 deletions snippets/include_read_var.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ var }}
1 change: 1 addition & 0 deletions snippets/include_var.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% assign val = 'INNER'%}
1 change: 1 addition & 0 deletions src/main/java/liqp/RenderSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

public class RenderSettings {

public static final RenderSettings EXCEPTIONS_FROM_INCLUDE = new RenderSettings.Builder().withShowExceptionsFromInclude(true).build();

public enum EvaluateMode {
LAZY,
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/liqp/Template.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -252,6 +253,10 @@ public static Template parse(File file, ParseSettings parseSettings, RenderSetti
return new Template(file, Tag.getTags(), Filter.getFilters(parseSettings.flavor), parseSettings, renderSettings);
}

public static Template parse(String template, ParseSettings parseSettings, RenderSettings renderSettings) throws IOException {
return new Template(template, Tag.getTags(), Filter.getFilters(parseSettings.flavor), parseSettings, renderSettings);
}

public static Template parse(InputStream input) {
return new Template(input, Tag.getTags(), Filter.getFilters(ParseSettings.DEFAULT_FLAVOR), new ParseSettings.Builder().build());
}
Expand Down Expand Up @@ -444,19 +449,28 @@ public String call() {
* @return a string denoting the rendered template.
*/
public String renderUnguarded(Map<String, Object> variables) {
return renderUnguarded(variables, null);
}

private String renderUnguarded(Map<String, Object> variables, TemplateContext parent) {
if (variables.containsKey(Include.INCLUDES_DIRECTORY_KEY)) {
Object includeDirectory = variables.get(Include.INCLUDES_DIRECTORY_KEY);
if (includeDirectory instanceof File) {
variables.put(Include.INCLUDES_DIRECTORY_KEY, ((File) includeDirectory).getAbsolutePath());
} else if (includeDirectory instanceof Path) {
variables.put(Include.INCLUDES_DIRECTORY_KEY, ((Path) includeDirectory).toAbsolutePath().toString());
}
}
variables = renderSettings.evaluate(parseSettings.mapper, variables);

final NodeVisitor visitor = new NodeVisitor(this.tags, this.filters, this.parseSettings);
try {
LNode node = visitor.visit(root);
this.templateContext = new TemplateContext(protectionSettings, renderSettings, parseSettings, variables);
if (parent == null) {
this.templateContext = new TemplateContext(protectionSettings, renderSettings, parseSettings, variables);
} else {
this.templateContext = new TemplateContext(parent);
}
if (this.contextHolder != null) {
contextHolder.setContext(templateContext);
}
Expand All @@ -472,6 +486,15 @@ public String renderUnguarded(Map<String, Object> variables) {
}
}

/**
* Renders the template using parent context
* @param parent
* @return
*/
public String renderUnguarded(TemplateContext parent) {
return renderUnguarded(new HashMap<String, Object>(), parent);
}

// Use toStringTree()
@Deprecated
public String toStringAST() {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/liqp/tags/Include.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Object render(TemplateContext context, LNode... nodes) {
context.put(includeResource, value);
}

return template.render(context.getVariables());
return template.renderUnguarded(context);

} catch(Exception e) {
if (context.renderSettings.showExceptionsFromInclude) {
Expand Down
1 change: 1 addition & 0 deletions src/test/java/liqp/TemplateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import liqp.parser.Inspectable;
import org.antlr.v4.runtime.RecognitionException;
import org.junit.Rule;
import org.junit.Test;

import java.io.File;
Expand Down
Loading

0 comments on commit fb68a8a

Please sign in to comment.