`
Mydwr
  • 浏览: 28286 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

freemarker中实现自定义标签

阅读更多
  1. import  java.io.IOException;   
  2.   import  java.io.Writer;   
  3.   import  java.util.Iterator;   
  4.   import  java.util.Map;   
  5.   
  6.   import  freemarker .core.Environment;   
  7. import  freemarker .template.SimpleNumber;   
  8. import  freemarker .template.TemplateBooleanModel;   
  9. import  freemarker .template.TemplateDirectiveBody;   
  10. import  freemarker .template.TemplateDirectiveModel ;   
  11. import  freemarker .template.TemplateException;   
  12. import  freemarker .template.TemplateModel;   
  13. import  freemarker .template.TemplateModelException;   
  14. import  freemarker .template.TemplateNumberModel;   
  15.   
  16. /**  
  17.  * FreeMarker  自定义标签实现重复输出内容体。  
  18.  *   
  19.  *   
  20.  * 参数:  
  21.  * count: 重复的次数,必须的且非负整数。  
  22.  * hr: 设置是否输出HTML标签 "hr" 元素. Boolean. 可选的默认为fals.  
  23.  *   
  24.  *   
  25.  * 循环变量: 只有一个,可选的. 从1开始。  
  26.  *   
  27.  *   
  28.  */   
  29. public   class  RepeatDirective  implements  TemplateDirectiveModel  {   
  30.   
  31.      private   static   final  String PARAM_NAME_COUNT =  "count" ;   
  32.      private   static   final  String PARAM_NAME_HR =  "hr" ;   
  33.   
  34.      public   void  execute(Environment env, Map params, TemplateModel[] loopVars,   
  35.             TemplateDirectiveBody body)  throws  TemplateException, IOException {   
  36.   
  37.          // ---------------------------------------------------------------------   
  38.          // 处理参数   
  39.   
  40.          int  countParam =  0 ;   
  41.          boolean  countParamSet =  false ;   
  42.          boolean  hrParam =  false ;   
  43.   
  44.         Iterator paramIter = params.entrySet().iterator();   
  45.          while  (paramIter.hasNext()) {   
  46.             Map.Entry ent = (Map.Entry) paramIter.next();   
  47.   
  48.             String paramName = (String) ent.getKey();   
  49.             TemplateModel paramValue = (TemplateModel) ent.getValue();   
  50.   
  51.              if  (paramName.equals(PARAM_NAME_COUNT)) {   
  52.                  if  (!(paramValue  instanceof  TemplateNumberModel)) {   
  53.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  54.                             +  "\" parameter "  +  "must be a number." );   
  55.                 }   
  56.                 countParam = ((TemplateNumberModel) paramValue).getAsNumber()   
  57.                         .intValue();   
  58.                 countParamSet =  true ;   
  59.                  if  (countParam <  0 ) {   
  60.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  61.                             +  "\" parameter "  +  "can't be negative." );   
  62.                 }   
  63.             }  else   if  (paramName.equals(PARAM_NAME_HR)) {   
  64.                  if  (!(paramValue  instanceof  TemplateBooleanModel)) {   
  65.                      throw   new  TemplateModelException( "The \""  + PARAM_NAME_HR   
  66.                             +  "\" parameter "  +  "must be a boolean." );   
  67.                 }   
  68.                 hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean();   
  69.             }  else  {   
  70.                  throw   new  TemplateModelException( "Unsupported parameter: "   
  71.                         + paramName);   
  72.             }   
  73.         }   
  74.          if  (!countParamSet) {   
  75.              throw   new  TemplateModelException( "The required \""   
  76.                     + PARAM_NAME_COUNT +  "\" paramter"  +  "is missing." );   
  77.         }   
  78.   
  79.          if  (loopVars.length >  1 ) {   
  80.              throw   new  TemplateModelException(   
  81.                      "At most one loop variable is allowed." );   
  82.         }   
  83.   
  84.          // Yeah, it was long and boring...   
  85.   
  86.          // ---------------------------------------------------------------------   
  87.          // 真正开始处理输出内容   
  88.   
  89.         Writer out = env.getOut();   
  90.          if  (body !=  null ) {   
  91.              for  ( int  i =  0 ; i < countParam; i++) {   
  92.                  // 输出  <hr> 如果 参数hr 设置为true   
  93.                  if  (hrParam && i !=  0 ) {   
  94.                     out.write( "<hr>" );   
  95.                 }   
  96.   
  97.                  // 设置循环变量   
  98.                  if  (loopVars.length >  0 ) {   
  99.                     loopVars[ 0 ] =  new  SimpleNumber(i +  1 );   
  100.                 }   
  101.   
  102.                  // 执行标签内容(same as <#nested> in FTL).    
  103.                 body.render(env.getOut());   
  104.             }   
  105.         }   
  106.     }   
  107.   
  108. }  
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;

 

import freemarker .core.Environment; import freemarker .template.SimpleNumber; import freemarker .template.TemplateBooleanModel; import freemarker .template.TemplateDirectiveBody; import freemarker .template.TemplateDirectiveModel ; import freemarker .template.TemplateException; import freemarker .template.TemplateModel; import freemarker .template.TemplateModelException; import freemarker .template.TemplateNumberModel;

/** * FreeMarker 自定义标签实现重复输出内容体。 * * * 参数: * count: 重复的次数,必须的且非负整数。 * hr: 设置是否输出HTML标签 "hr" 元素. Boolean. 可选的默认为fals. * * * 循环变量: 只有一个,可选的. 从1开始。 * * */ public class RepeatDirective implements TemplateDirectiveModel {

private static final String PARAM_NAME_COUNT = "count"; private static final String PARAM_NAME_HR = "hr";

public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {

// --------------------------------------------------------------------- // 处理参数

int countParam = 0; boolean countParamSet = false; boolean hrParam = false;

Iterator paramIter = params.entrySet().iterator(); while (paramIter.hasNext()) { Map.Entry ent = (Map.Entry) paramIter.next();

String paramName = (String) ent.getKey(); TemplateModel paramValue = (TemplateModel) ent.getValue();

if (paramName.equals(PARAM_NAME_COUNT)) { if (!(paramValue instanceof TemplateNumberModel)) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "must be a number."); } countParam = ((TemplateNumberModel) paramValue).getAsNumber() .intValue(); countParamSet = true; if (countParam < 0) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "can't be negative."); } } else if (paramName.equals(PARAM_NAME_HR)) { if (!(paramValue instanceof TemplateBooleanModel)) { throw new TemplateModelException("The \"" + PARAM_NAME_HR + "\" parameter " + "must be a boolean."); } hrParam = ((TemplateBooleanModel) paramValue).getAsBoolean(); } else { throw new TemplateModelException("Unsupported parameter: " + paramName); } } if (!countParamSet) { throw new TemplateModelException("The required \"" + PARAM_NAME_COUNT + "\" paramter" + "is missing."); }

if (loopVars.length > 1) { throw new TemplateModelException( "At most one loop variable is allowed."); }

// Yeah, it was long and boring...

// --------------------------------------------------------------------- // 真正开始处理输出内容

Writer out = env.getOut(); if (body != null) { for (int i = 0; i < countParam; i++) { // 输出  <hr> 如果 参数hr 设置为true if (hrParam && i != 0) { out.write("<hr>"); }

// 设置循环变量 if (loopVars.length > 0) { loopVars[0] = new SimpleNumber(i + 1); }

// 执行标签内容(same as <#nested> in FTL). body.render(env.getOut()); } } }

}

 

Java代码
  1. import  java.io.File;   
  2. import  java.io.IOException;   
  3. import  java.io.Writer;   
  4. import  java.util.Map;   
  5.   
  6. import  freemarker .template.Configuration;   
  7. import  freemarker .template.DefaultObjectWrapper;   
  8. import  freemarker .template.Template;   
  9. import  freemarker .template.TemplateException;   
  10.   
  11. /**  
  12.  *   
  13.  * 模板工具类  
  14.  */   
  15. public   class  FreeMarkertUtil {   
  16.      /**  
  17.      * @param templatePath 模板文件存放目录   
  18.      * @param templateName 模板文件名称   
  19.      * @param root 数据模型根对象  
  20.      * @param templateEncoding 模板文件的编码方式  
  21.      * @param out 输出流  
  22.      */   
  23.      public   static   void  processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){   
  24.          try  {   
  25.             Configuration config= new  Configuration();   
  26.             File file= new  File(templatePath);   
  27.              //设置要解析的模板所在的目录,并加载模板文件   
  28.             config.setDirectoryForTemplateLoading(file);   
  29.              //设置包装器,并将对象包装为数据模型   
  30.             config.setObjectWrapper( new  DefaultObjectWrapper());   
  31.                
  32.              //获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致   
  33.             Template template=config.getTemplate(templateName,templateEncoding);   
  34.              //合并数据模型与模板   
  35.                
  36.             template.process(root, out);   
  37.             out.flush();   
  38.             out.close();   
  39.         }  catch  (IOException e) {   
  40.             e.printStackTrace();   
  41.         } catch  (TemplateException e) {   
  42.             e.printStackTrace();   
  43.         }   
  44.            
  45.     }    
  46. }  
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;

 

import freemarker .template.Configuration; import freemarker .template.DefaultObjectWrapper; import freemarker .template.Template; import freemarker .template.TemplateException;

/** * * 模板工具类 */ public class FreeMarkertUtil { /** * @param templatePath 模板文件存放目录 * @param templateName 模板文件名称 * @param root 数据模型根对象 * @param templateEncoding 模板文件的编码方式 * @param out 输出流 */ public static void processTemplate(String templatePath, String templateName, String templateEncoding, Map<?,?> root, Writer out){ try { Configuration config=new Configuration(); File file=new File(templatePath); //设置要解析的模板所在的目录,并加载模板文件 config.setDirectoryForTemplateLoading(file); //设置包装器,并将对象包装为数据模型 config.setObjectWrapper(new DefaultObjectWrapper());

//获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致 Template template=config.getTemplate(templateName,templateEncoding); //合并数据模型与模板

    template.process(root, out);     out.flush();     out.close(); } catch (IOException e) { e.printStackTrace(); }catch (TemplateException e) { e.printStackTrace(); }

} }

 

 

Java代码
  1. import  java.io.OutputStreamWriter;   
  2. import  java.util.HashMap;   
  3. import  java.util.Map;   
  4.   
  5. /**  
  6.  *   
  7.  * 客户端测试模板输入类  
  8.  */   
  9. public   class  RepeatTest {   
  10.      public   static   void  main(String[] args) {   
  11.         Map<String,Object> root= new  HashMap<String, Object>();   
  12.   
  13.         root.put( "repeat" new  RepeatDirective());   
  14.            
  15.         FreeMarkertUtil.processTemplate( "src/templates" , "repeat.ftl" "UTF-8" , root,  new  OutputStreamWriter(System.out));   
  16.            
  17.     }   
  18. }  
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

 

/** * * 客户端测试模板输入类 */ public class RepeatTest { public static void main(String[] args) { Map<String,Object> root=new HashMap<String, Object>();

root.put("repeat", new RepeatDirective());

FreeMarkertUtil.processTemplate("src/templates","repeat.ftl", "UTF-8", root, new OutputStreamWriter(System.out));

} }

 

 模板文件repeat.ftl如下:

 

Java代码
  1. <#assign x =  1 >   
  2.   
  3. 一个参数:   
  4. < @repeat  count= 4 >   
  5.   Test ${x}   
  6.   <#assign x = x +  1 >   
  7. </ @repeat >   
  8.   
  9. 二个参数:   
  10. < @repeat  count= 3  hr= true >   
  11.   Test   
  12. </ @repeat >   
  13.   
  14. 循环变量:   
  15. < @repeat  count= 3 ; cnt>   
  16.   ${cnt}. Test   
  17. </ @repeat >    
<#assign x = 1>

 

一个参数: <@repeat count=4>   Test ${x}   <#assign x = x + 1> </@repeat>

二个参数: <@repeat count=3 hr=true>   Test </@repeat>

循环变量: <@repeat count=3; cnt>   ${cnt}. Test </@repeat>  

 

 输出结果:

Java代码
  1. 一个参数:   
  2.   Test  1   
  3.   Test  2   
  4.   Test  3   
  5.   Test  4   
  6.   
  7. 二个参数:   
  8.   Test   
  9. <hr>  Test   
  10. <hr>  Test   
  11.   
  12. 循环变量:   
  13.    1 . Test   
  14.    2 . Test   
  15.    3 . Test
分享到:
评论

相关推荐

    freemarker 自定义freeMarker标签

    最后,关于标签的性能考虑,应避免在自定义标签中执行耗时操作,因为这会影响模板的渲染速度。尽可能地将计算和逻辑操作交给后端处理,只在标签中处理简单的数据转换和呈现。 总的来说,自定义FreeMarker标签是提高...

    Freemarker 自定义标签 简单案例

    在提供的"TestFreemarkerDiy"示例中,可能包含了一个简单的自定义标签实现以及一个演示如何使用该标签的Freemarker模板文件。通过分析这个示例,我们可以学习如何在实际项目中应用自定义标签,以提高模板的可维护性...

    spring mvc freemarker 自定义标签

    // 在这里实现自定义标签的逻辑 env.getOut().write("Hello, World!"); } } ``` 然后,你需要在Spring配置中注册这个自定义标签。在`WebMvcConfigurer`的实现中,添加`freemarkerConfiguration` bean,并使用`...

    实现通过jfinal框架自动扫描freemarker的自定义标签.zip

    要实现自定义标签的自动扫描和注册,你需要做以下几步: 1. **创建自定义标签库**:定义一个Java类作为自定义标签的处理器,继承自`freemarker.template.TemplateDirectiveModel`接口,并实现其方法。在这个类中,...

    freemark 自定义标签 总结

    自定义标签在Freemarker中被称为`Custom Tags`,它们通过`&lt;@...&gt;`语法来调用。这些标签通常是由Java代码实现的,它们可以处理复杂的逻辑,如数据库查询、业务处理等,然后返回一个可渲染的字符串给Freemarker模板。...

    freemarker自定义分页标签宏

    在FreeMarker中,我们可以利用宏(Macro)这一功能来实现自定义的分页逻辑。宏是可重用的模板片段,可以作为函数来调用,具有参数,可以封装复杂的模板代码。 1. **宏定义**: 在`pager.html`模板文件中,我们可以...

    Struts2、Spring、Freemarker自定义标签

    在Struts2中,可以通过实现`com.opensymphony.xwork2.util.ValueStackAware`接口创建自定义标签,让标签能够访问值栈中的数据。Spring框架也有自己的标签库,如Spring Taglib,可以简化JSP页面中的Spring Bean引用。...

    jsp自定义标签

    除了自定义标签外,JSP还提供了JSTL (JavaServer Pages Standard Tag Library) 和Freemarker等其他模板引擎作为选择。 **1. JSTL** - **优点:** - 标准化的标签集,便于学习和使用。 - 提供了丰富的功能,如...

    使用freemarker扩展struts标签

    2. **实现标签类**: 创建一个Java类来实现自定义标签,例如`AmHtml`,并继承自Struts2的标签基类。 3. **定义标签行为**: 在标签类中,你需要覆盖`doStartTag()`和`doEndTag()`方法,以及其他可能需要的方法,来定义...

    非常好用的自定义分页标签

    4. **兼容性**:作为一个好用的自定义标签,它应该与各种视图技术(如JSP、FreeMarker、Thymeleaf等)兼容,并且适应不同的前端样式。 5. **易用性**:使用简单是这个组件的一大优点,意味着只需将`kevinb.jar`引入...

    freemarker及jeecms标签使用学习文档

    - **自定义函数和标签**:通过`TemplateMethodModelEx`接口实现自定义方法,`TemplateDirectiveModel`接口实现自定义标签。 - **模板缓存**:提高性能,减少不必要的模板编译。 3. **Jeecms标签使用** - **...

    freemarker的shiro标签

    8. **自定义标签**:除了内置的Shiro标签,开发者还可以根据项目需求自定义FreeMarker标签,扩展Shiro的功能,实现更具体的权限控制逻辑。 9. **错误处理**:在模板中使用Shiro标签时,要注意异常处理。当用户权限...

    spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐

    在这个示例中,我们将介绍如何将 Shiro 集成到 Spring Boot 项目中,并实现自定义密码验证和 Freemarker 标签根据权限渲染不同页面。 首先,需要在 pom.xml 文件中添加 Shiro 的依赖项: ```xml &lt;groupId&gt;org....

    自定义分页标签源代码

    自定义标签是JSP中的一种特性,允许开发者创建自己的标签库,以提高代码的可读性和复用性。这里提到的分页标签可能是基于JSTL (JavaServer Pages Standard Tag Library) 或 Struts1 的自定义标签实现。开发者可以...

    Struts2_自定义标签的方法

    本文将深入探讨如何在Struts2中创建自定义标签,特别是基于`UITag`的实现方法,以及其背后的原理和步骤。 #### 二、Struts2自定义标签的构成 Struts2的自定义`UITag`由三部分组成: 1. **UIBean**:用于定义标签...

    在struts2的freemarker模板中扩展struts标签

    众所周知,struts2宣称freemarker模板中不再支持自定义标签,但如果工程UI仅用freemarker模板可以通过扩展struts标签简单实现,不是采用官方不推荐的配置JspSupportServlet实现的!内付详细说明及范例,此方法仅为团队...

    freemarker实现自动补齐字符串

    freemarker实现自动补齐字符串。通过ftl模版文件(ftl文件为freemarker模版文件)的自定义标签实现自动补齐字符串。代码稍作修改便可左补齐右补齐左右补齐,可自定义设置补齐的字符串。测试通过java文件调用ftl文件...

    非常好的Freemarker中文教程

    6. **自定义标签(Custom Tags)**:扩展Freemarker功能的一种方式,允许开发者创建自己的模板语言元素。 7. **缓存机制**:了解如何配置和利用Freemarker的缓存,提高生成静态页面的效率。 8. **模板配置**:如...

    freemarker中文学习资料

    - **数据模型**:Freemarker模板与应用程序的数据模型进行绑定,模型中的数据可以在模板中被引用和展示。 - **分离关注点**:Freemarker遵循MVC设计模式,负责视图部分,将业务逻辑和表现层分开,使代码更易于维护...

    freemarker中文手册.rar

    2. 自定义指令:可以扩展Freemarker的功能,实现自定义的逻辑。 3. 数组和集合处理:Freemarker支持对数组和集合进行遍历、索引等操作。 4. 日期和数字格式化:通过`?date`、`?number`等后缀进行格式化。 5. I18N...

Global site tag (gtag.js) - Google Analytics