Skip to content

Commit

Permalink
Add a variable function to map from a variable to a value at runtime.
Browse files Browse the repository at this point in the history
  • Loading branch information
GregDThomas committed Dec 21, 2020
1 parent 6f5d531 commit d7b83aa
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/hubspot/jinjava/Jinjava.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ private Context copyGlobalContext() {
globalContext.getAllFilters().forEach(context::registerFilter);
globalContext.getAllFunctions().forEach(context::registerFunction);
globalContext.getAllTags().forEach(context::registerTag);
context.setVariableFunction(globalContext.getVariableFunction());
return context;
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/hubspot/jinjava/interpret/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Context extends ScopeMap<String, Object> {
Expand Down Expand Up @@ -102,6 +103,7 @@ public enum Library {
private boolean validationMode = false;
private boolean deferredExecutionMode = false;
private boolean hideInterpreterErrors = false;
private Function<String, Object> variableFunction = null;

public Context() {
this(null, null, null);
Expand Down Expand Up @@ -172,6 +174,7 @@ public Context(
new FunctionLibrary(parent == null, disabled.get(Library.FUNCTION));
if (parent != null) {
this.expressionStrategy = parent.expressionStrategy;
this.variableFunction = parent.variableFunction;
}
}

Expand Down Expand Up @@ -499,6 +502,14 @@ public void registerTag(Tag t) {
tagLibrary.addTag(t);
}

public Function<String, Object> getVariableFunction() {
return variableFunction;
}

public void setVariableFunction(final Function<String, Object> variableFunction) {
this.variableFunction = variableFunction;
}

public ExpressionStrategy getExpressionStrategy() {
return expressionStrategy;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ public Object retraceVariable(String variable, int lineNumber, int startPosition
Variable var = new Variable(this, variable);
String varName = var.getName();
Object obj = context.get(varName);
if (obj == null && context.getVariableFunction() != null) {
obj = context.getVariableFunction().apply(varName);
}
if (obj != null) {
if (obj instanceof DeferredValue) {
throw new DeferredValueException(variable, lineNumber, startPosition);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.hubspot.jinjava.interpret;

import static org.assertj.core.api.Assertions.assertThat;

import com.hubspot.jinjava.Jinjava;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.junit.Test;

public class VariableFunctionTest {
private static final Function<String, Object> VARIABLE_FUNCTION = s -> {
switch (s) {
case "name":
return "Jared";
case "title":
return "Mr.";
case "surname":
return "Stehler";
default:
return null;
}
};

@Test
public void willUseTheFunctionToPopulateVariables() {
final Jinjava jinjava = new Jinjava();
jinjava.getGlobalContext().setVariableFunction(VARIABLE_FUNCTION);
final Map<String, Object> context = new HashMap<>();

final String template = "<div>Hello, {{ title }} {{ name }} {{ surname }}!</div>";

final String renderedTemplate = jinjava.render(template, context);

assertThat(renderedTemplate).isEqualTo("<div>Hello, Mr. Jared Stehler!</div>");
}

@Test
public void willPreferTheContextOverTheFunctionToPopulateVariables() {
final Jinjava jinjava = new Jinjava();
jinjava.getGlobalContext().setVariableFunction(VARIABLE_FUNCTION);
final Map<String, Object> context = new HashMap<>();
context.put("name", "Greg");

final String template = "<div>Hello, {{ title }} {{ name }} {{ surname }}!</div>";

final String renderedTemplate = jinjava.render(template, context);

assertThat(renderedTemplate).isEqualTo("<div>Hello, Mr. Greg Stehler!</div>");
}
}

0 comments on commit d7b83aa

Please sign in to comment.