常用的模板引擎:
基本能力是差不多的。只不过jinja是python实现,其他两个是java实现。
<#--普通变量替换 -->
package ${classPath};
public class ${className} {
public static void main(String[] args) {
System.out.println("${helloWorld}");
}
}
<#--函数 -->
第一个字母大写:${data?cap_first}
所有字母小写:${data?lower_case}
所有字母大写:${data?upper_case}
数值取整数:${floatData?int}
<#--列表操作 -->
获取集合的长度:${users?size}
<#if users??>
<#list users as user >
${user}
#list>
<#else>
${user!"变量为空则给一个默认值"}
#if>
<#--字典操作 -->
直接通过Key获取 Value值:${mapData.liping}
直接通过Key获取 Value值:${mapData['liping']}
通过Key遍历Map:
<#list mapData?keys as key>
${key} -> ${mapData[key]}
#list>
通过Value遍历Map:
<#list mapData?values as value>
${value}
#list>
注意几点:
处理上述模板的java代码如下:
static void testFreeMarker() throws IOException, TemplateException {
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
Template template = configuration.getTemplate("src/main/resources/hello.ftl");
Map dataMap = new HashMap();
dataMap.put("classPath", "com.freemark.hello");
dataMap.put("className", "AutoCodeDemo");
dataMap.put("helloWorld", "HelloWorld!");
dataMap.put("data", "abcd1234");
dataMap.put("floatData", 12.34);
List users = Arrays.asList("bob", "suzy");
dataMap.put("users", users);
Map m = new LinkedHashMap<>();
m.put("liping", 30);
m.put("xx1", 7);
m.put("xx2", 56);
dataMap.put("mapData", m);
try(Writer writer = new FileWriter("hello.res"))
{
template.process(dataMap, writer);
}
}
velocity语法参考:
https://www.ibm.com/developerworks/cn/java/j-lo-velocity1/
我们来写出与上述模板等价的velocity模板:
## 普通变量替换,与freemarker不同,大括号不是必须的
package ${classPath};
public class $className {
public static void main(String[] args) {
System.out.println("${helloWorld}");
}
}
## 函数
第一个字母大写:${Helper.capitalize($data)}
所有字母小写:${data.toLowerCase()}
所有字母大写:${data.toUpperCase()}
数值取整数:${Helper.toInt($floatData)}
## 列表操作
获取集合的长度:${users.size()}
#if($users)
#foreach($user in $users)
${user}
#end
#else
${users}
#end
## 字典操作
直接通过Key获取 Value值:${mapData.liping}
直接通过Key获取 Value值:${mapData['liping']}
通过Key遍历Map:
#foreach($item in ${mapData.entrySet()})
${item.key} -> ${item.value}
#end
通过Value遍历Map:
#foreach($value in $mapData)
${value}
#end
与freemarker的差异:
处理velocity模板的java代码如下:
static void testVelocity() throws IOException {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
//这里要指定utf8编码,否则中文输出乱码
org.apache.velocity.Template t = ve.getTemplate("hello.vtl", "utf-8");
VelocityContext dataMap = new VelocityContext();
dataMap.put("classPath", "com.freemark.hello");
dataMap.put("className", "AutoCodeDemo");
dataMap.put("helloWorld", "HelloWorld!");
dataMap.put("data", "abcd1234");
dataMap.put("floatData", 12.34);
dataMap.put("Helper", Helper.class);
List users = Arrays.asList("bob", "suzy");
dataMap.put("users", users);
Map m = new LinkedHashMap<>();
m.put("liping", 30);
m.put("xx1", 7);
m.put("xx2", 56);
dataMap.put("mapData", m);
try(Writer writer = new FileWriter("hello_v.res"))
{
t.merge(dataMap, writer);
}
}
我们还要提供Helper辅助类,才能确保模板输出正确:
public final class Helper
{
public static String capitalize(String s)
{
if (s == null || s.length() == 0)
{
return s;
}
char[] charArray = s.toCharArray();
charArray[0] -= 32;
return String.valueOf(charArray);
}
public static int toInt(double d)
{
return (int)d;
}
}
注意:Helper类必须要声明为public,否则模板里无法访问到。
jinja语法可参考:
http://docs.jinkan.org/docs/jinja2/templates.html#builtin-globals
上述模板等价的jinja模板为:
{# 普通变量替换 #}
package {{classPath}};
public class {{className}} {
public static void main(String[] args) {
System.out.println("{{helloWorld}}");
}
}
{# 函数 #}
第一个字母大写:{{data | capitalize}}
所有字母小写:{{data | lower}}
所有字母大写:{{data | upper}}
数值取整数:{{floatData | int}}
{# 列表操作 #}
获取集合的长度:{{users | length}}
{% if users %}
{% for user in users %}
{{user}}
{% endfor %}
{% else %}
{{users}}
{% endif %}
{# 字典操作 #}
直接通过Key获取 Value值:{{mapData.liping}}
直接通过Key获取 Value值:{{mapData['liping']}}
通过Key遍历Map:
{% for key in mapData.keys() %}
{{key}} -> {{mapData[key]}}
{% endfor %}
通过Value遍历Map:
{% for value in mapData.values() %}
{{value}}
{% endfor %}
与velocity、freemarker的差别:
处理模板的python代码:
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('./', encoding='utf-8'))
template = env.get_template('hello.jtl')
cont = template.render(classPath='com.freemark.hello', className='AutoCodeDemo',
helloWorld=u'HelloWorld!',
data='abcd1234',
floatData=12.34,
users=["bob", "suzy"],
mapData={"liping" :30, "xx1":7, "xx2" : 56})
# print cont
with open('hello_j.res', 'w') as writer:
writer.write(cont.encode('utf-8'))
freemarker、jinja更像DSL,比较简洁,而velocity则像在写java代码,有点啰嗦。