freemarker自定義標簽(與java合用)


自定義類繼承FreemarkerManager類,重寫protected Configuration createConfiguration(ServletContext servletContext)throws TemplateException方法定義有哪些TemplateDirectiveModel類與它的別名[自定義標簽名稱],通過Spring來取:

import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import freemarker.template.Configuration;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
/**
 * 從spring取得所有的TemplateDirectiveModel類的對象,全部取出來,交給struts管理
 * @author Administrator
 *
 */
public class DirectiveFreemarkerManager extends FreemarkerManager{
    @Override
    protected Configuration createConfiguration(ServletContext servletContext)
            throws TemplateException {
        //調用你父類操作
        Configuration  configuration=super.createConfiguration(servletContext);
        //設定在頁面使用的標簽的類型 (([]、<>),[]這種標記解析要快些)      [] SQUARE_BRACKET_TAG_SYNTAX  ,  <>ANGLE_BRACKET_TAG_SYNTAX
        configuration.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
        //取得spring所管理所有的對象 ClassPathXmlApplication,  WebAplicationContext
        ApplicationContext  appContext=WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
        // 獲取實現TemplateDirectiveModel的bean
        Map<String, TemplateDirectiveModel>  beans= appContext.getBeansOfType(TemplateDirectiveModel.class);
        //再把這些類,全部交給struts的freemarker來管理
        //Component("upper") public class UpperDirective implements TemplateDirectiveModel
        for(String key : beans.keySet()){
            Object obj=beans.get(key);  //TemplateDirectiveModel
            if(obj!=null && obj instanceof  TemplateDirectiveModel){
                configuration.setSharedVariable(key, obj);
            } 
        }
        return configuration;
    }
}

在struts.xml中添加:

 <!-- 讓struts來管理freemarker自定義標簽類 struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager -->
    <constant name="struts.freemarker.manager.classname" value="com.xxxx.struts.DirectiveFreemarkerManager"></constant>

編寫TemplateDirectiveModel,並交給Spring管理:

import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import org.springframework.stereotype.Component;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * 自定義指定,作用,把嵌套的內容中的小寫全部轉換為大寫字母
 * 
 * @author Administrator
 *
 */
@Component("upper")
public class UpperDirective implements TemplateDirectiveModel {
    //evn  環境輸出
    //params 參數
    //loopVars 循環
    //body   內容
    @Override
    public void execute(Environment env, Map params,
            TemplateModel[] loopVars, TemplateDirectiveBody body)
            throws TemplateException, IOException {
        //如果有參數 應該不支持參數
        if(!params.isEmpty()){
            throw new TemplateModelException(
                    "這個指令不允許使用參數.");
        }
        if(loopVars.length!=0){
              throw new TemplateModelException(
                        "這個指令不允許使用循環參數.");
        }
         // 如果嵌套內容不為空的
        if(body!=null){
            //如果有內容,自己去重寫輸出流
            body.render( new UpperCaseFilterWriter(env.getOut()));
        
        }else{
            throw new RuntimeException("無內容異常");
        }
    }
    //內部類
    private static class UpperCaseFilterWriter extends Writer{
         private final Writer out;  //接收網頁中的輸出 流對象
         public UpperCaseFilterWriter(Writer out){
             this.out=out;
         }
          //cbuf 文字內容, off位移,len 文字長度
        @Override
        public void write(char[] cbuf, int off, int len) throws IOException {
            char[] transformedChar=new char[len];
            for(int i=0;i<len;i++){
                transformedChar[i]=Character.toUpperCase(cbuf[i+off]);
            }
            out.write(transformedChar); 
        }
        @Override
        public void flush() throws IOException {
          out.flush();
        }
        @Override
        public void close() throws IOException {
             out.close();
        } 
    }
}

編寫action,result—>字符串,type=”freemarker”:

<!-- 約定大於配置   /admin/Flinktype_list.action  --> 
   <package name="freemarkerPackage" namespace="/admin" extends="commonPackage" >
       <action name="*_*" class="{1}Action" method="{2}">
           <result name="{2}" type="freemarker">/admin/template/{1}/{2}.ftl</result> 
       </action>
   </package>

模板/template/upper.ftl:

<!DOCTYPE html>
<html lang="ch-ZN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>freemarker自定義標簽</title>
</head>
<body>  

    <@upper>
          bar
          <#-- All kind of FTL is allowed here -->
          <#list ["red", "green", "blue"] as color>
            ${color}
          </#list>
          baaz
     </@upper>
     
    
    <hr/>
    
    <@cms_linktype    limit="0,10" >
         請選擇分類: <select>
               <#list  arrTypes as x>
                  <option value="${x.id}">${x.typeName}</option>
               </#list> 
         </select>
    </@cms_linktype>
</body>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM