zoukankan      html  css  js  c++  java
  • Handlebars块级Helpers

    1.Handlebars简单介绍:

         Handlebars是JavaScript一个语义模板库,通过对view和data的分离来快速构建Web模板。它采用"Logic-less template"(无逻辑模版)的思路,在加载时被预编译,而不是到了客户端执行到代码时再去编译, 这样可以保证模板加载和运行的速度。Handlebars兼容Mustache,你可以在Handlebars中导入Mustache模板。

    2.参考文章:

        Handlebars官网:http://handlebarsjs.com/

        Handlebars中文介绍(王赛):http://www.ghostchina.com/introducing-the-handlebars-js-templating-engine/

        Handlebars中文文档 - 块级helpers(译自官方版):https://segmentfault.com/a/1190000000347965

        Handlebars.js 中文文档:http://keenwon.com/992.html

        js模版引擎handlebars.js实用教程:http://www.cnblogs.com/iyangyuan/p/3471227.html

        handlebars玩家指南:http://cnodejs.org/topic/56a2e8b1cd415452622eed2d

        com.github.jknack.handlebars.Helper:http://www.programcreek.com/java-api-examples/index.php?api=com.github.jknack.handlebars.Helper

    3.块级Helpers使用技巧:

       Handlebars内置了with,eachif,unless,log这5种基本的Helpers。

       if标签只能判断true或false,不能执行一些复杂的运算逻辑。

       这些基本的Helpers并不能满足我们所有的需求,因此需要自定义一些辅助Helpers。

       ① 基本Helpers—each使用示例:orderList.hbs

    <h1>订单列表</h1>
        <div class="record">
            <table class="order>
                <thead>
                <tr class="centerTr" >
                    <th >采购凭证号</th>
                    <th >公司</th>
                    <th >供应商编号</th>
                    <th >项目交货日期</th>
                    <th >产地</th>
                </tr>
                </thead>
                <tbody>
                {{#each _DATA_.orderList}}
                    <tr>
                        <td>{{purproofno}}</td>
                        <td>{{company}}</td>
                        <td>{{supplierno}}</td>
                        <td>{{projectdate}}</td>
                        <td>{{proplace}}</td>
                    </tr>
                {{/each}}
                </tbody>
            </table>
        </div>

       ② 自定义Helpers使用示例:handlebars.coffee

    Handlebars.registerHelper 'jsonToStr', (json, options) ->
      JSON.stringify(json)
    
    Handlebars.registerHelper 'add', (a,b, options) ->
      a + b
    
    Handlebars.registerHelper "formatPrice", (price, type, options) ->
      return if not price?
      if type is 1
        formatedPrice = (price / 100)
        roundedPrice = parseInt(price / 100)
      else
        formatedPrice = (price / 100).toFixed(2)
        roundedPrice = parseInt(price / 100).toFixed(2)
      if `formatePrice == roundedPrice` then roundedPrice else formatedPrice
    
    Handlebars.registerHelper "formatDate", (date, type, options) ->
      return unless date
      switch type
        when "gmt" then moment(date).format("EEE MMM dd HH:mm:ss Z yyyy")
        when "day" then moment(date).format("YYYY-MM-DD")
        when "minute" then moment(date).format("YYYY-MM-DD HH:mm")
        else moment(date).format("YYYY-MM-DD HH:mm:ss")
    
    Handlebars.registerHelper "lt", (a, b, options) ->
      if a < b
        options.fn(this)
      else
        options.inverse(this)
    
    Handlebars.registerHelper "gt", (a, b, options) ->
      if a > b
        options.fn(this)
      else
        options.inverse(this)
    
    Handlebars.registerHelper 'of', (a, b, options) ->
      values = if _.isArray b then b else b.split(",")
      if _.contains(values, a.toString()) or _.contains values, a
        options.fn(this)
      else
        options.inverse(this)
    
    Handlebars.registerHelper 'length', (a, options) ->
      length = a.length
    
    Handlebars.registerHelper "isArray", (a, options) ->
      if _.isArray a
        options.fn(this)
      else
        options.inverse(this)
    
    Handlebars.registerHelper "between", (a, b, c, options) ->
      if a >= b and a <= c
        options.fn(this)
      else
        options.inverse(this)
    
    Handlebars.registerHelper "multiple", (a, b, c, options) ->
      if c isnt 0 then a * b / c else 0
    
    Handlebars.registerHelper "contain", (a, b, options) ->
      return options.inverse @ if a is undefined or b is undefined
      array = if _.isArray a then a else a.toString().split(",")
      if _.contains a, b then options.fn @ else options.inverse @
    
    Handlebars.registerHelper "match", (a, b, options) ->
      return options.inverse @ if a is undefined or b is undefined
      if new RegExp(a).exec(b) is null then options.inverse @ else options.fn @
    
    Handlebars.registerHelper "isOdd", (a, b, options) ->
      if a % b == 1
        options.fn(this)
      else
        options.inverse(this)

       handlebars.coffee编译成handlebarsApp.js的结果:

      Handlebars.registerHelper('jsonToStr', function(json, options) {
        return JSON.stringify(json);
      });
    
      Handlebars.registerHelper('add', function(a, b, options) {
        return a + b;
      });
    
      Handlebars.registerHelper("formatPrice", function(price, type, options) {
        var formatedPrice, roundedPrice;
        if (price == null) {
          return;
        }
        if (type === 1) {
          formatedPrice = price / 100;
          roundedPrice = parseInt(price / 100);
        } else {
          formatedPrice = (price / 100).toFixed(2);
          roundedPrice = parseInt(price / 100).toFixed(2);
        }
        if (formatedPrice == roundedPrice) {
          return roundedPrice;
        } else {
          return formatedPrice;
        }
      });
    
      Handlebars.registerHelper("formatDate", function(date, type, options) {
        if (!date) {
          return;
        }
        switch (type) {
          case "gmt":
            return moment(date).format("EEE MMM dd HH:mm:ss Z yyyy");
          case "day":
            return moment(date).format("YYYY-MM-DD");
          case "minute":
            return moment(date).format("YYYY-MM-DD HH:mm");
          default:
            return moment(date).format("YYYY-MM-DD HH:mm:ss");
        }
      });
    
      Handlebars.registerHelper("lt", function(a, b, options) {
        if (a < b) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper("gt", function(a, b, options) {
        if (a > b) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper('of', function(a, b, options) {
        var values;
        values = _.isArray(b) ? b : b.split(",");
        if (_.contains(values, a.toString()) || _.contains(values, a)) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper('length', function(a, options) {
        var length;
        return length = a.length;
      });
    
      Handlebars.registerHelper("isArray", function(a, options) {
        if (_.isArray(a)) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper("between", function(a, b, c, options) {
        if (a >= b && a <= c) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper("multiple", function(a, b, c, options) {
        if (c !== 0) {
          return a * b / c;
        } else {
          return 0;
        }
      });
    
      Handlebars.registerHelper("contain", function(a, b, options) {
        var array;
        if (a === void 0 || b === void 0) {
          return options.inverse(this);
        }
        array = _.isArray(a) ? a : a.toString().split(",");
        if (_.contains(a, b)) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    
      Handlebars.registerHelper("match", function(a, b, options) {
        if (a === void 0 || b === void 0) {
          return options.inverse(this);
        }
        if (new RegExp(a).exec(b) === null) {
          return options.inverse(this);
        } else {
          return options.fn(this);
        }
      });
    
      Handlebars.registerHelper("isOdd", function(a, b, options) {
        if (a % b === 1) {
          return options.fn(this);
        } else {
          return options.inverse(this);
        }
      });
    View Code

     Spring MVC框架中引入handlebars插件:

      Maven配置:handlebars和handlebars-springmvc。

    <dependency>
        <groupId>com.github.jknack</groupId>
        <artifactId>handlebars</artifactId>
        <version>4.0.5</version>
    </dependency>
    <dependency>
        <groupId>com.github.jknack</groupId>
        <artifactId>handlebars-springmvc</artifactId>
        <version>4.0.5</version>
    </dependency>

       在Spring MVC配置文件servlet-context.xml中添加handlebars视图解析器配置:

    <bean id="handlebarsViewResolver" class="com.github.jknack.handlebars.springmvc.HandlebarsViewResolver">
       <property name="prefix" value="/page/" />
       <property name="suffix" value=".html" />
       <property name="contentType" value="text/html;charset=utf-8" />
       <property name="failOnMissingFile" value="false" />
       <property name="cache" value="false" />
    </bean>

        Controller中实现代码:

    package com.ouc.handlebars.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class HandlebarsController {
    
        @RequestMapping(value = "/testHandlebars", method = RequestMethod.GET)
        public ModelAndView helloWorld() {  
            Map<String, Object> map = new HashMap<String, Object>();  
            map.put("helloWorld", "Hello World!");  
            return new ModelAndView("helloWorld",  map);
        }
            
    }

       前端helloWorld.html文件:

    <!DOCTYPE >
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Hello World</title>
        <script type="text/javascript" src="js/jquery/jquery.min.js"></script>    
        <script type="text/javascript" src="js/handlebars/handlebars-4.0.5.js"></script>
    </head>
    <body>
        <div>
            {{helloWorld}}
        </div>    
    </body>
    </html>

     ④ 自定义Helpers后台实现:OucHandlebarHelpers.java

    package ouc.handlebars.web.helpers;
    
    import com.github.jknack.handlebars.Helper;
    import com.github.jknack.handlebars.Options;
    import com.google.common.base.MoreObjects;
    import com.google.common.base.Objects;
    import ouc.handlebars.common.utils.MapBuilder;
    import ouc.handlebars.common.utils.NumberUtils;
    import ouc.handlebars.common.utils.Splitters;
    import ouc.handlebars.pampas.engine.handlebars.HandlebarsEngine;
    import org.joda.time.DateTime;
    import org.joda.time.Days;
    import org.joda.time.Hours;
    import org.joda.time.Minutes;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import java.io.IOException;
    import java.text.DecimalFormat;
    import java.util.Collection;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    
    @Component
    public class OucHandlebarHelpers {
        @Autowired
        private HandlebarsEngine handlebarEngine;
    
        @PostConstruct
        public void init() {
            handlebarEngine.registerHelper("isEmpty", new Helper<Object>() {
                @Override
                public CharSequence apply(Object obj, Options options) throws IOException {
                    if (obj == null || obj.equals("")) {
                        return options.fn();
                    } else {
                        return options.inverse();
                    }
                }
            });
    
            //此标签相当于 and 连接的if判断
            handlebarEngine.registerHelper("multipleEquals", new Helper<Object>() {
                @Override
                public CharSequence apply(Object source, Options options) throws IOException {
                    CharSequence ch=options.fn();
                    CharSequence ch2=options.inverse();
    
                    String obj1=String.valueOf(source);
                    Object[] other=options.params;
                    if(!Objects.equal(obj1,String.valueOf(other[0]))){
                        return ch2;
                    }
    
                    for (int i = 1; i < other.length; i+=2) {
                        if(!Objects.equal(String.valueOf(other[i]),String.valueOf(other[i+1]))){
                            return ch2;
                        }
                    }
                    return ch;
                }
            });
    
            handlebarEngine.registerHelper("get", new Helper<Object>() {
                @Override
                public CharSequence apply(Object context, Options options) throws IOException {
                    Object collections;
                    Object param = options.param(0);
                    if (context instanceof List || context instanceof Map) {
                        collections = context;
                    }
                    else {
                        collections = Splitters.COMMA.splitToList(String.valueOf(context));
                    }
    
                    if (param == null) {
                        return null;
                    }
    
                    if(collections instanceof List){
                        return ((List)collections).get(Integer.valueOf(param.toString())).toString();
                    }
                    else{
                        return ((Map)collections).get(param).toString();
                    }
                }
            });
    
            handlebarEngine.registerHelper("contain", new Helper<Object>() {
                @Override
                public CharSequence apply(Object context, Options options) throws IOException {
                    Object collections;
                    Object param = options.param(0);
                    if (context instanceof Collection || context instanceof Map ) {
                        collections = context;
                    }
                    else{
                        collections = Splitters.COMMA.splitToList(String.valueOf(context));
                    }
    
                    if (param == null) {
                        return options.fn();
                    }
    
                    if(collections instanceof Collection){
                        if(((Collection)collections).contains(param)){
                            return options.fn();
                        }
                        else{
                            return options.inverse();
                        }
                    }
                    else {
                        Map map = (Map)collections;
                        String check = options.param(1, "ALL");
                        if("key".equalsIgnoreCase(check)){
                            if(map.keySet().contains(param)){
                                return options.fn();
                            }
                            else{
                                return options.inverse();
                            }
                        }
                        else if("value".equalsIgnoreCase(check)){
                            if(map.values().contains(param)){
                                return options.fn();
                            }
                            else{
                                return options.inverse();
                            }
                        }
                        else{
                            if(map.keySet().contains(param) || map.values().contains(param)){
                                return options.fn();
                            }
                            else{
                                return options.inverse();
                            }
                        }
                    }
                }
            });
    
            handlebarEngine.registerHelper("containAny", new Helper<Object>() {
                @Override
                public CharSequence apply(Object context, Options options) throws IOException {
                    Object collections;
                    if (context instanceof Collection || context instanceof Map) {
                        collections = context;
                    } else {
                        collections = Splitters.COMMA.splitToList(String.valueOf(context));
                    }
    
                    if (options.params == null || options.params.length == 0) {
                        return options.fn();
                    }
    
                    if(collections instanceof Collection){
                        for (Object param : options.params) {
                            for (String p : Splitters.COMMA.splitToList((String)param)) {
                                if (((Collection)collections).contains(p)) {
                                    return options.fn();
                                }
                            }
                        }
                        return options.inverse();
                    } else {
                        Map map = (Map)collections;
                        for (Object param : options.params) {
                            for (String p : Splitters.COMMA.splitToList((String) param)) {
                                if (map.keySet().contains(p) || map.values().contains(p)) {
                                    return options.fn();
                                }
                            }
                        }
                        return options.inverse();
                    }
                }
            });
    
            /**
             *
             * 传参 a, b, c
             * 然后a是一个"2015-08-12"或者''2015-08-12 12:00:00"
             * b的值可以是"dayStart",''now","dayEnd","2015-08-15",''2015-08-15 12:00:00"中的一个
             * 如果b是dayStart, a就和当天的0点0分比较
             * 如果b是now, a就和现在时间比较
             * 如果b是dayEnd, a就和第二天的0点0分比较
             * 如果b是一个date,a就和b比较
             * 第三个参数:
             * 设置时间的比较级别:s:秒,m:分,h:小时,d:天
             */
            handlebarEngine.registerHelper("comDate", new Helper<Object>() {
                @Override
                public CharSequence apply(Object context, Options options) throws IOException {
                    //获取参数
                    Object param2 = options.param(0);
    
                    //默认按照秒比较时间
                    String comType = MoreObjects.firstNonNull((String) options.param(1), "s");
    
                    if(context == null || param2 == null){
                        return options.fn();
                    }else{
                        Date comTime1 = new DateTime(context).toDate();//Date)param1;
    
                        String param = (String)param2;
                        Date comTime2;
                        if(Objects.equal(param , "dayStart")){
                            //compare1与当天的0点0分比较
    
                            comTime2 = DateTime.now().withTime(0 , 0, 0, 0).toDate();
                        }else if(Objects.equal(param , "now")){
                            //compare1就和现在时间比较
    
                            comTime2 = DateTime.now().toDate();
                        }else if(Objects.equal(param , "dayEnd")){
                            //compare1就和第二天的0点0分比较
    
                            comTime2 = DateTime.now().plusDays(1).withTime(0 , 0, 0, 0).toDate();
                        }else{
                            //compare1就和compare2比较
    
                            comTime2 = DateTime.parse(param).toDate();
                        }
    
                        if(compareTime(comTime1 , comTime2 , comType)){
                            return options.inverse();
                        }else{
                            return options.fn();
                        }
                    }
                }
            });
    
            /**
             * 格式化金钱 第一个参数格式化到得金额,第二个是保留小数的位数,第三个是传值为空时返回
             * 什么数据,E-empty string(默认),Z-zero
             * {{formatPrice 变量名 "W" 2 E}}
             */
            handlebarEngine.registerHelper("formatPrice", new Helper<Number>() {
                Map<String, Integer> sdfMap = MapBuilder.<String, Integer>of().put(
                        "W", 1000000,
                        "Q", 100000,
                        "B", 10000,
                        "Y", 100
                ).map();
                @Override
                public CharSequence apply(Number price, Options options) throws IOException {
                    String defaultValue = "E";
                    if (options.params != null && options.params.length ==3) {
                        defaultValue = options.param(2).toString();
                    }
                    if (price == null) return defValue(defaultValue);
    
                    if (options.params == null || options.params.length == 0){
                        return NumberUtils.formatPrice(price);
                    }
                    else if( options.params.length == 1){
                        Object param1 = options.param(0);
                        int divisor = sdfMap.get(param1.toString().toUpperCase()) == null?1:sdfMap.get(param1.toString().toUpperCase());
                        return getDecimalFormat(2).format(price.doubleValue()/divisor);
                    }
                    else if (options.params.length == 2 || options.params.length ==3 ){
                        Object param1 = options.param(0);
                        Object param2 = options.param(1);
                        int divisor = sdfMap.get(param1.toString().toUpperCase()) == null?1:sdfMap.get(param1.toString().toUpperCase());
                        return getDecimalFormat(Integer.valueOf(param2.toString())).format(price.doubleValue() / divisor);
                    }
                    return "";
                }
            });
    
            /**
             * Usage: <span>{{formatDecimal 10101.2 2}}</span> ->
             *        <span> 10,101.20 </span>
             * 第一个参数是传入的数,第二是保留小数位
             * 默认不保留小数位
             */
            handlebarEngine.registerHelper("formatDecimal", new Helper<Number>() {
    
                @Override
                public CharSequence apply(Number number, Options options) throws IOException {
                    if (number == null) {
                        return "0";
                    }
                    DecimalFormat df;
                    if (options.params == null || options.params.length == 0) {
                        df = getDecimalFormat(0);
                    } else {
                        df = getDecimalFormat(Integer.valueOf(options.params[0].toString()));
                    }
                    return df.format(number.doubleValue());
                }
            });
        }
    
        private String defValue(String defaultValue) {
            if (defaultValue.toUpperCase().equals("E")) {
                return "";
            }
            if (defaultValue.toUpperCase().equals("Z")) {
                return "0";
            }
            return "";
        }
    
        private DecimalFormat getDecimalFormat(Integer digits){
            DecimalFormat decimalFormat = new DecimalFormat();
            Integer fractionDigits = digits == null? 2:digits;
            decimalFormat.setMaximumFractionDigits(fractionDigits);
            decimalFormat.setMinimumFractionDigits(fractionDigits);
            return decimalFormat;
        }
    
        /**
         * 比较开始时间以及结束时间之间的大小(按照比较级别)
         * @param startTime 开始时间
         * @param endTime   结束时间
         * @param comType   比较级别
         * @return  Boolean
         * 返回是否大于(true:大于, false:小于)
         */
        private Boolean compareTime(Date startTime , Date endTime, String comType){
            Boolean result = false;
            if(Objects.equal(comType , "s")){
                //按照秒比较
                result = startTime.after(endTime);
            }else if(Objects.equal(comType , "m")){
                //按照分钟比较
                result = Minutes.minutesBetween(new DateTime(startTime), new DateTime(endTime)).getMinutes() > 0;
            }else if(Objects.equal(comType , "h")){
                //按照小时比较
                result = Hours.hoursBetween(new DateTime(startTime), new DateTime(endTime)).getHours() > 0;
            }else if(Objects.equal(comType , "d")){
                //按照天比较
                result = Days.daysBetween(new DateTime(startTime), new DateTime(endTime)).getDays() > 0;
            }
    
            return result;
        }
    
    }
    View Code

      ⑤ HandlebarsEngine.java

    package ouc.handlebars.pampas.engine.handlebars;  
       
    import com.github.jknack.handlebars.Handlebars;  
    import com.github.jknack.handlebars.HandlebarsException;  
    import com.github.jknack.handlebars.Helper;  
    import com.github.jknack.handlebars.Template;  
    import com.github.jknack.handlebars.io.TemplateLoader;  
    import com.google.common.base.Optional;  
    import com.google.common.base.Strings;  
    import com.google.common.base.Throwables;  
    import com.google.common.cache.CacheBuilder;  
    import com.google.common.cache.CacheLoader;  
    import com.google.common.cache.LoadingCache;  
    import com.google.common.collect.Maps;  
    import ouc.handlebars.pampas.common.UserNotLoginException;  
    import ouc.handlebars.pampas.common.UserUtil;  
    import ouc.handlebars.pampas.engine.RenderConstants;  
    import ouc.handlebars.pampas.engine.Setting;  
    import ouc.handlebars.pampas.engine.config.ConfigManager;  
    import ouc.handlebars.pampas.engine.config.model.Component;  
    import ouc.handlebars.pampas.engine.mapping.Invoker;  
    import lombok.extern.slf4j.Slf4j;  
    import org.springframework.beans.factory.annotation.Autowired;  
       
    import javax.servlet.ServletContext;  
    import java.io.FileNotFoundException;  
    import java.util.Map;  
    import java.util.concurrent.TimeUnit;  
       
    /**  
     * Author: Wu Ping  
     */ 
    @org.springframework.stereotype.Component  
    @Slf4j 
    public class HandlebarsEngine {  
       
        private Handlebars handlebars;  
       
        private Invoker invoker;  
       
        private final LoadingCache<String, Optional<Template>> caches;  
       
        private ConfigManager configManager;  
       
        @Autowired 
        public HandlebarsEngine(Invoker invoker,  
                                Setting setting,  
                                ConfigManager configManager,  
                                ServletContext servletContext) {  
            this.invoker = invoker;  
            TemplateLoader templateLoader = new GreatTemplateLoader(servletContext, 
    
    "/views", ".hbs");  
            this.handlebars = new Handlebars(templateLoader);  
            this.caches = initCache(!setting.isDevMode());  
            this.configManager = configManager;  
        }  
       
        private LoadingCache<String, Optional<Template>> initCache(boolean buildCache) {  
            if (buildCache) {  
                return CacheBuilder.newBuilder().expireAfterWrite(5, 
    
    TimeUnit.MINUTES).build(new CacheLoader<String, Optional<Template>>() {  
                    @Override 
                    public Optional<Template> load(String path) throws Exception {  
                        Template t = null;  
                        try {  
                            t = handlebars.compile(path);  
                        } catch (Exception e) {  
                            log.error("failed to compile template(path={}), cause:
    
    {}",path, e.getMessage());  
                        }  
                        return Optional.fromNullable(t);  
                    }  
                });  
            }  
            return null;  
        }  
       
        public <T> void registerHelper(String name, Helper<T> helper) {  
            handlebars.registerHelper(name, helper);  
        }  
       
        public String execInline(String templateStr, Map<String, Object> params) {  
            return execInline(templateStr, params, null);  
        }  
       
        public String execInline(String templateStr, Map<String, Object> params, String 
    
    cacheKey) {  
            try {  
                if (params == null) {  
                    params = Maps.newHashMap();  
                }  
                Template template;  
                if (caches == null || cacheKey == null) {  
                    template = handlebars.compileInline(templateStr);  
                } else {  
                    template = caches.getUnchecked("inline/" + cacheKey).orNull();  
                }  
                if(template == null){  
                    log.error("failed to exec handlebars' template:{}", templateStr);  
                    return "";  
                }  
                return template.apply(params);  
            } catch (Exception e) {  
                log.error("exec handlebars' template failed: {},cause:{}", templateStr, 
    
    Throwables.getStackTraceAsString(e));  
                return "";  
            }  
       
        }  
       
        @SuppressWarnings("unchecked")  
        public String execPath(String path, Map<String, Object> params, boolean 
    
    isComponent) throws FileNotFoundException {  
            try {  
                if (params == null) {  
                    params = Maps.newHashMap();  
                }  
       
                Template template;  
                if (isComponent) {  
                    if (caches == null) {  
                        template = handlebars.compile("component:" + path);  
                    } else {  
                        template = caches.getUnchecked("component:" + path).orNull();  
                    }  
                    params.put(RenderConstants.COMPONENT_PATH, path);  
                } else {  
                    if (caches == null) {  
                        template = handlebars.compile(path);  
                    } else {  
                        template = caches.getUnchecked(path).orNull();  
                    }  
                }  
       
                params.put(RenderConstants.USER, UserUtil.getCurrentUser()); //user  
                params.put(RenderConstants.HREF, configManager.getFrontConfig
    
    ().getCurrentHrefs(Setting.getCurrentHost()));  
                if(template == null){  
                    log.error("failed to exec handlebars' template:path={}", path);  
                    return "";  
                }  
                return template.apply(params);  
       
            } catch (Exception e) {  
                Throwables.propagateIfInstanceOf(e, FileNotFoundException.class);  
                if (e instanceof HandlebarsException) {  
                    Throwables.propagateIfInstanceOf(e.getCause(), 
    
    UserNotLoginException.class);  
                }  
                log.error("failed to execute handlebars' template(path={}),cause:{} ",  
                        path, Throwables.getStackTraceAsString(e));  
            }  
       
            return "";  
        }  
       
        public String execComponent(final Component component, final Map<String, Object> 
    
    context) {  
            if (!Strings.isNullOrEmpty(component.getService())) {  
                Object object = null;  
                try {  
                    object = invoker.invoke(component.getService(), context);  
                } catch (UserNotLoginException e) {  
                    log.error("user doesn't login.");  
                    if (context.get(RenderConstants.DESIGN_MODE) == null) {  
                        throw e; // 非 DESIGN_MODE 时未登录需要抛出  
                    }  
                } catch (Exception e) {  
                    log.error("error when invoke component, component: {}", component, e); 
    
     
                    context.put(RenderConstants.ERROR, e.getMessage());  
                }  
                context.put(RenderConstants.DATA, object);  
            }  
            try {  
                return execPath(component.getPath(), context, true);  
            } catch (Exception e) {  
                log.error("failed to execute handlebars' template(path={}),cause:{} ",  
                        component.getPath(), Throwables.getStackTraceAsString(e));  
            }  
            return "";  
        }  
       
    } 
    View Code

       整个块级Helpers的介绍基本就到这里了,前面介绍handlebars的文章都不错。

       李白准备在黄鹤楼上题诗的时候看了崔颢写的诗,他认为崔颢的诗可以称为是千古绝唱,觉着自己写不出可以超越崔颢的作品,所以慨叹:“眼前有景道不得,崔颢题诗在上头”。

  • 相关阅读:
    转 sql 时间转换格式 convert(varchar(10),字段名,转换格式)
    C#页面添加提交数据后跳出小弹窗的功能
    解决粘包问题
    粘包问题
    模拟ssh远程执行命令
    基于TCP协议的socket套接字编程
    Linux和git使用
    osi七层协议
    TCP协议的三次握手和四次挥手
    C/S 和 B/S架构
  • 原文地址:https://www.cnblogs.com/wp5719/p/5707895.html
Copyright © 2011-2022 走看看