embed java code inside a template

2019-06-03 22:55发布

Is it possible to embed executable java code inside a ST4 template? eg if I want to pass a string to my template, which sometimes prints the string as-is, and sometimes prints it in caps, so I want a java code to do the necessary conversion. Without this feature, I see 3 ways to achieve the same functionality:

(1) pre-compute the alternative values in java, and pass them all to the template at one shot (but this may result in too many arguments):

// in the below code, if the template can compute DESCRIPTION_CAPS from DESCRIPTION, using embedded java code, that reduces one argument
test(DESCRIPTION, DESCRIPTION_CAPS) ::= <<
this is original <DESCRIPTION>
this is caps <DESCRIPTION_CAPS>
>>

(2) If there become too many such arguments, the other option is to break up the temlpate into smaller parts, but that makes the code ugly and unreadable:

test1(DESCRIPTION) ::= <<
this is original <DESCRIPTION>
>>

test2(DESCRIPTION_CAPS) ::= <<
this is caps <DESCRIPTION_CAPS>
>>

(3) Pre-compute all relevant values inside a class, and let the template call the getter functions (without arguments) to simply get the relevant values from the class.

test() ::= <<
this is original <values.description>
this is caps <values.description_caps>
>>

As of now (if the embedding java class is not available) the 3rd option looks like the best solution. Please advise if a better solution exists.

Note: in the above example, I have used CAPS as only as an example, there could be more complex java functions also needed.

2条回答
女痞
2楼-- · 2019-06-03 23:23

As @Hartmut said, no you can't embed java code inside a template, but you can create a custom StringRenderer that you could use to format the strings in the way you want.

You could then pass your custom format string to the renderer like this:

test(description) ::= <<
    this is original <description>
    this is caps <description; format="upper">
    this is custom format <description; format="my-format-string">
>>

P.S if you're just interested in changing the text case you might not need to roll your own, just add a reference to the StringRenderer that comes bundled with StringTemplate using:

templateGroup.registerRenderer(String.class, new StringRenderer());

and pass "upper", "lower", or "cap" as the format string

See my answer here for more info

查看更多
Deceive 欺骗
3楼-- · 2019-06-03 23:41

No, java code embedding into a Template is not intended / not provided. That makes it easier to prevent a mess / mixture of view and model/logic.

In Your case, You can easily put the calculated things into java property getter function, which can be referenced and evaluated by StringTemplate as a kind of bean property.

e.g.

Put in Your template group file MyTemplate.stg:

myTemplate(f) ::= <<
...
Blabla  <f.message>  blabla
...
>>

Put in Your Java source code:

class MyClass() {
  ...
  private String internal_message;
  public getMessage() { 
    return internal_message; 
  }
  ...
}

Invoke the template:

STGroupFile stg = new STGroupFile("MyTemplate.stg");
ST templ = stg.getInstanceOf("myTemplate");
templ.add("f", new MyClass());

With this, the template logic <f.message> invokes getMessage() of Your java object instance f.

查看更多
登录 后发表回答