问题
I would like to know how to create a custom format function for string template. Let say I have the following code:
render(attributes) :: <<
<html>
$atributes: {
<div> $customformat(atribute.name)$</div>
}
</html>
>>
customformat(name) ::= <<
$name; format="upper"$
>>
Currently the behaviour of the function customformat is:
Input: "hello world" -> Output: "HELLO WORLD"
And I would like to modify the customformat function so the output is something like the following:
Input: "hello world" -> Output: "HELLO_WORLD"
回答1:
As far as I'm aware this isn't possible, since StringTemplate is all about strict model-view separation.
Instead, I think you'd be better off having a getter in the controller that returned the formatted string.
You might find this question useful: embed java code inside a template
Actually, I found a simple way of doing this which avoids the need for the formatted string getters:
You need to create a new StringRenderer which can format the string in the way you want.
public class MyStringRenderer extends StringRenderer
{
@Override
public String toString(Object o, String formatString, Locale locale) {
if (!("upperAndUnder".equals(formatString)))
return super.toString(o, formatString, locale);
// we want upper case words with underscores instead of spaces
return ((String) o).replaceAll(" ", "_").toUpperCase(locale);
}
}
Then you'll need to let the template group know about the new renderer:
public static void main(String[] args) {
STGroup templates = new STGroupFile("test.stg");
templates.registerRenderer(String.class, new MyStringRenderer());
ST renderTemplate = templates.getInstanceOf("render");
renderTemplate.add("attributes", new String[]{"blahh blahh I'm a string", "I'm another string"});
System.out.println(renderTemplate.render());
}
Then you can call the format function like you did before, but pass "upperAndUnder" as the parameter:
group test;
delimiters "$","$"
render(attributes) ::= <<
<html>
$attributes:{ attribute | <div> $customFormat(attribute)$</div>}; separator="\n"$
</html>
>>
customFormat(name) ::= <<
$name; format="upperAndUnder"$
>>
which prints:
<html>
<div> BLAHH_BLAHH_I'M_A_STRING</div>
<div> I'M_ANOTHER_STRING</div>
</html>
FYI:
Here's the original StringRenderer code
More info on Renderers
回答2:
Try this one
Object rendering using AttributeRenderer
public class BasicFormatRenderer implements AttributeRenderer {
public String toString(Object o) {
return o.toString();
}
public String toString(Object o, String formatName) {
if (formatName.equals("toUpper")) {
return o.toString().toUpperCase();
} else if (formatName.equals("toLower")) {
return o.toString().toLowerCase();
} else {
throw new IllegalArgumentException("Unsupported format name");
}
}}
来源:https://stackoverflow.com/questions/26891383/custom-format-functions-for-stringtemplate4