Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TemplateContext: provide access to Filters, Insertions, parent context #274

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
generate-branches-badge: true
branches-badge-filename: branches.svg
- name: Commit and push the badge (if it changed)
if: ${{ matrix.jacoco && contains(github.ref, 'master') }}
if: ${{ matrix.jacoco && github.head_ref == 'master' }}
uses: EndBug/add-and-commit@v7
with:
default_author: github_actions
Expand Down
6 changes: 4 additions & 2 deletions ruby/case_numeric_camparing_as_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

require_relative '_helpers.rb'

pp render({}, "{% assign comparingValue = 98.0 %}{{ 98 > comparingValue }}")
assertEqual("true", render({}, "{% assign comparingValue = 98.0 %}{{ '98' == comparingValue }}"))
# pp render({}, "{% assign comparingValue = 98.0 %}{{ 98 > comparingValue }}")
# assertEqual("true", render({}, "{% assign comparingValue = 98.0 %}{{ '98' == comparingValue }}"))

assertEqual("true", render({}, "{% if 98 > '98' %}true{% else %}false{% endif %}"))
50 changes: 40 additions & 10 deletions src/main/antlr4/liquid/parser/v4/LiquidParser.g4
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
parser grammar LiquidParser;

@parser::header {
// add java imports here
import liqp.TemplateParser;
}

@parser::members {
private boolean isLiquid = true;
private boolean liquidStyleInclude = true;
private boolean evaluateInOutputTag = false;
private TemplateParser.ErrorMode errorMode = TemplateParser.ErrorMode.lax;

private boolean isLiquidStyleInclude(){
return liquidStyleInclude;
}

private boolean isLiquid(){
return isLiquid;
private boolean isJekyllStyleInclude(){
return !liquidStyleInclude;
}

private boolean isJekyll(){
return !isLiquid;
private boolean isEvaluateInOutputTag() {
return evaluateInOutputTag;
}

public LiquidParser(TokenStream input, boolean isLiquid) {
private boolean isStrict() {
return errorMode == TemplateParser.ErrorMode.strict;
}
private boolean isWarn() {
return errorMode == TemplateParser.ErrorMode.warn;
}

private boolean isLax() {
return errorMode == TemplateParser.ErrorMode.lax;
}

public LiquidParser(TokenStream input, boolean isLiquidStyleInclude, boolean evaluateInOutputTag, TemplateParser.ErrorMode errorMode) {
this(input);
this.isLiquid = isLiquid;
this.liquidStyleInclude = isLiquidStyleInclude;
this.evaluateInOutputTag = evaluateInOutputTag;
this.errorMode = errorMode;
}

public void reportTokenError(String message, Token token) {
Expand Down Expand Up @@ -177,8 +201,8 @@ capture_tag
;

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

// only valid for Flavor.JEKYLL
Expand All @@ -193,7 +217,13 @@ jekyll_include_params
;

output
: outStart expr filter* OutEnd
: {evaluateInOutputTag}? outStart evaluate=expr filter* OutEnd
| {isStrict()}? outStart term filter* OutEnd
| {isWarn() || isLax()}? outStart term filter* unparsed=not_out_end? OutEnd
;

not_out_end
: ~( OutEnd )*
;

filter
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/liqp/Examples.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ public static void demoStrictVariables() {
TemplateParser parser = new TemplateParser.Builder() //
.withRenderSettings(new RenderSettings.Builder() //
.withStrictVariables(true) //
.withRaiseExceptionsInStrictMode(true) //
.build()) //
.withErrorMode(TemplateParser.ErrorMode.strict)
.build();

parser.parse("{{mu}}").render();
Expand Down
59 changes: 0 additions & 59 deletions src/main/java/liqp/Insertion.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,6 @@
*/
public abstract class Insertion extends LValue {

/**
* A map holding all insertions.
*/
private static final Map<String, Insertion> INSERTIONS = new HashMap<>();

private static Insertions CURRENT_INSERTIONS = null;

private static void updateCurrentInsertions() {
CURRENT_INSERTIONS = Insertions.of(INSERTIONS);
}

/**
* The name of this insertions.
*/
Expand Down Expand Up @@ -55,22 +44,6 @@ public String getName() {
return name;
}

/**
* Returns all tags registered for global use.
*
* Note that this method is unsafe, as {@link #registerInsertion(Insertion)} affects all uses
* of this class.
*
* Use {@link Insertions} instead.
*
* @return all default tags.
*/
@Deprecated
public static Map<String, Insertion> getInsertions() {
checkInitialized();
return new HashMap<>(INSERTIONS);
}

/**
* Renders this insertion.
*
Expand All @@ -85,36 +58,4 @@ public static Map<String, Insertion> getInsertions() {
* @return an Object denoting the rendered AST.
*/
public abstract Object render(TemplateContext context, LNode... nodes);

/**
* Registers an insertion for global use.
*
* If an insertion exists under the same name, it is replaced by this one.
*
* Note that this method is unsafe, as it affects all uses of this class.
* Use {@link Insertions} instead.
*
* @param insertion
* the insertion to be registered.
* @deprecated Use {@link liqp.ParseSettings.Builder#with(Insertion)}
*/
@Deprecated
public static void registerInsertion(Insertion insertion) {
checkInitialized();
INSERTIONS.put(insertion.name, insertion);
updateCurrentInsertions();
}

static Insertions getCurrentInsertions() {
checkInitialized();
return CURRENT_INSERTIONS;
}

private static void checkInitialized() {
if (CURRENT_INSERTIONS == null) {
Insertions.STANDARD_INSERTIONS.writeTo(INSERTIONS);

updateCurrentInsertions();
}
}
}
13 changes: 11 additions & 2 deletions src/main/java/liqp/Insertions.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static Insertions of(Collection<Insertion> insertions) {
return EMPTY;
}
return new Insertions(insertions.stream().collect(Collectors.toMap(Insertion::getName, Function
.identity())));
.identity(), (a, b) -> b)));
}

/**
Expand Down Expand Up @@ -149,7 +149,7 @@ public Insertions mergeWith(Insertions other) {
* @return The set of names.
*/
private Set<String> getNames(Predicate<? super Map.Entry<String, Insertion>> predicate) {
return this.map.entrySet().stream().filter(predicate).map(x -> x.getKey()).collect(Collectors
return this.map.entrySet().stream().filter(predicate).map(Map.Entry::getKey).collect(Collectors
.toSet());
}

Expand Down Expand Up @@ -203,4 +203,13 @@ public Insertion get(String name) {
public Collection<Insertion> values() {
return Collections.unmodifiableCollection(map.values());
}

/**
* Returns an unmodifiable map of the stored {@link Insertion} names.
*
* @return The map.
*/
public Map<String, Insertion> asMap() {
return Collections.unmodifiableMap(map);
}
}
38 changes: 17 additions & 21 deletions src/main/java/liqp/LValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,35 +77,31 @@ public static boolean areEqual(Object a, Object b) {
return Math.abs(delta) < 0.00000000001;
}

if (AtomNode.isEmpty(a) && (b instanceof CharSequence)) {
return ((CharSequence)b).length() == 0;
if (isEmpty(a) && isEmpty(b)) {
return true;
}

if (AtomNode.isEmpty(b) && (a instanceof CharSequence)) {
return ((CharSequence)a).length() == 0;
}
return a.equals(b);
}

if (AtomNode.isEmpty(a) && (b instanceof Collection)) {
return ((Collection)b).size() == 0;
}

if (AtomNode.isEmpty(b) && (a instanceof Collection)) {
return ((Collection)a).size() == 0;
private static boolean isEmpty(Object val) {
if (AtomNode.isEmpty(val)) {
return true;
}

if (AtomNode.isEmpty(a) && (b.getClass().isArray())) {
return ((Object[])b).length == 0;
if ((val instanceof CharSequence)) {
return ((CharSequence)val).length() == 0;
}

if (AtomNode.isEmpty(b) && (a.getClass().isArray())) {
return ((Object[])a).length == 0;
if (val instanceof Collection) {
return ((Collection<?>)val).size() == 0;
}

if (AtomNode.isEmpty(b) && (a instanceof Map)) {
return ((Map)a).size() == 0;
if (val instanceof Map) {
return ((Map<?, ?>)val).size() == 0;
}

return a.equals(b);
if (val.getClass().isArray()) {
return ((Object[])val).length == 0;
}
return false;
}

/**
Expand Down
Loading