和jsp的自定义tag一样,freemarker也可以自定义指令。
比如,我们需要用一个指令,实现两个数字相加。
我们需要实现一个freemarker的模板指令模型(TemplateDirectiveModel ):
Java代码
- 1. public class TempDireModelStub implements TemplateDirectiveModel {
- 2.
- 3. public void execute(Environment env, Map params, TemplateModel[] loopVars,
- 4. TemplateDirectiveBody body) throws TemplateException, IOException {
- 5. int v1 = Integer.parseInt(params.get("v1").toString());//①
- 6. int v2 = Integer.parseInt(params.get("v2").toString());
- 7.
- 8. env.getOut().write(String.valueOf(v1+v2));
- 9. }
- 10.
- 11. }
- public class TempDireModelStub implements TemplateDirectiveModel {
- public void execute(Environment env, Map params, TemplateModel[] loopVars,
- TemplateDirectiveBody body) throws TemplateException, IOException {
- int v1 = Integer.parseInt(params.get("v1").toString());//①
- int v2 = Integer.parseInt(params.get("v2").toString());
- env.getOut().write(String.valueOf(v1+v2));
- }
- }
与jsp tag一样,我们需要给这个指令起一个名字,这样,我们就能在各个模板里用这个名字调用这个指令了。假设我们命名这个指令为vTest,在模板里我们这样使用:
Java代码
1.
- <@vTest v1="1" v2="2"/>
- <@vTest v1="1" v2="2"/>
指令里的两个attribute会被加入到一个Map中,并传入到指令处理方法里,就是叫做params的参数。
最后一个问题,怎样把vTest这个名字和我们写的指令处理类对应起来,并且象jsp的tag一样可以在每一个模板文件里使用呢?在jsp中,需要写 tld文件,然后在jsp文件头声明一下引用的tld文件;在freemarker里,我们应该把它作为一个公共的模型来使用:
Java代码
1. Configuration config = ... ...;
2. TempDireModelStub tdms = new TempDireModelStub();
3.
- config.setSharedVariable("vTest", tdms);
- Configuration config = ... ...;
- TempDireModelStub tdms = new TempDireModelStub();
- config.setSharedVariable("vTest", tdms);
需要注意的是Map params这个参数,它的key就是attribute的名字,而值是你所写的值的freemarker的封装类型。
如①标记的那段代码,
Java代码
- params.get("v1").toString();
- arams.get("v1").toString();
修改为
Java代码
- (String)params.get("v1");
- (String)params.get("v1");
就会出现造型错误。如果是其他类型,应该使用freemarker的那些封装类型。