2

我想知道如何为字符串模板创建自定义格式函数。假设我有以下代码:

render(attributes) :: <<
<html>
    $atributes: {
        <div> $customformat(atribute.name)$</div>
    }


</html>
>>

customformat(name) ::= <<
    $name; format="upper"$
>>

目前,函数 customformat 的行为是:

输入:“hello world”-> 输出:“HELLO WORLD”

我想修改 customformat 函数,使输出如下所示:

输入:“hello world”-> 输出:“HELLO_WORLD”

4

2 回答 2

4

据我所知,这是不可能的,因为 StringTemplate 完全是关于严格的模型视图分离。

相反,我认为你最好在控制器中有一个返回格式化字符串的getter。

您可能会发现这个问题很有用:embed java code inside a template


实际上,我找到了一种简单的方法来避免对格式化字符串 getter 的需要:

您需要创建一个新的 StringRenderer,它可以按照您想要的方式格式化字符串。

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);
    }
}

然后你需要让模板组知道新的渲染器:

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());
}

然后你可以像以前一样调用格式函数,但传递“upperAndUnder”作为参数:

group test;

delimiters "$","$"

render(attributes) ::= <<
<html>
    $attributes:{ attribute | <div> $customFormat(attribute)$</div>}; separator="\n"$


</html>
>>

customFormat(name) ::= <<
    $name; format="upperAndUnder"$
>>

打印:

<html>
    <div> BLAHH_BLAHH_I'M_A_STRING</div>
    <div> I'M_ANOTHER_STRING</div>


</html>

供参考:

这是原始的 StringRenderer 代码

有关渲染器的更多信息

于 2014-11-24T11:53:05.380 回答
0

试试这个

使用 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");
    }
}}
于 2017-05-09T05:16:49.237 回答