freemarker 自定义标签

以下是常用的标签,以<#开头

<#include
<#list
<#if
${base}指的是resouces目录

当这些标签不满足需求时,可以自定标签  使用的时候以<@开头

编写后台标签解析类。

@Component
public class ControlsDirective implements TemplateDirectiveModel {
    @Override
    public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
        DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);

        Object object = SecurityUtils.getSubject().getPrincipal();
        String userName = object != null ? object.toString() : "";

        environment.setVariable("user",
                builder.build().wrap(userName));

        //遇到一个坑,如果页面是这样写的<@blogTag  method="recentBlog"  pageSize="3" ></@blogTag>
        //中间没有任何内容,这里会一直报空指针异常
        templateDirectiveBody.render(environment.getOut());
    }
}

记得要把注册标签,不然无法识别标签

@Configuration
public class FreeMarkerConfig {

    @Autowired
    protected freemarker.template.Configuration configuration;
    @Autowired
    protected MenusDirective customTags;
    @Autowired
    protected ControlsDirective controlsDirective;

    /**
     * 添加自定义标签
     */
    @PostConstruct
    public void setSharedVariable() {
        /*
         * 向freemarker配置中添加共享变量;
         * 它使用Configurable.getObjectWrapper()来包装值,因此在此之前设置对象包装器是很重要的。(即上一步的builder.build().wrap操作)
         * 这种方法不是线程安全个线程运行模板,那么附加的的;使用它的限制与那些修改设置值的限制相同。
         * 如果使用这种配置从多值应该是线程安全的。
         */
        configuration.setSharedVariable("menus", customTags);
        configuration.setSharedVariable("controls", controlsDirective);
    }
}

前台标签的使用

//使用标签            
<@contents channelId=channel.id pageNo=pageNo order=order>
                <div class="posts">
                    <ul class="posts-list">
                        <#include "/classic/inc/posts_item.ftl"/>
                        //得到后台返回的数据
                        <#list results.content as row>
                            <@posts_item row/>
                        </#list>
                        <#if  results.content?size == 0>
                        <li class="content">
                            <div class="content-box posts-aside">
                                <div class="posts-item">该目录下还没有内容!</div>
                            </div>
                        </li>
                        </#if>
                    </ul>
                </div>
            </@contents>

注意事项:

list标签返回的实体必须是public的,否则获取不到实体的属性。

 

freemarker 联动下拉框

                        <select class="form-control"  required onchange="cg1()" id="select1">
                            <option value="">请选择一级栏目</option>
                            <#list channels2 as row >
                                <option value="${row.id}" <#if (parentId == row.id)> selected </#if>>${row.name}</option>
                            </#list>
                        </select>
                        <select class="form-control" name="channelId" required id="select2">
                            <option value="">请选择二级栏目</option>
                            <#list channels3  as row>
                                <option value="${row.id}" <#if (view.channelId == row.id)> selected </#if>>${row.name}</option>
                            </#list>
                        </select>

关键在于这个onchange函数

        var s1 = document.getElementById("select1");
        var s2 = document.getElementById("select2");


        function cg1() {
            var channelId=${view.channelId}
            //清除选项框中的值
            clearSelectbox(s2);
            var index1 = s1.value;
            //获取一级下拉框中选中的值,再根据这个值获取到二级下拉框的中的选项。
            $.get("/channel/getChildren/" + index1, function (ret) {
                var b = JSON.parse(JSON.parse(ret))
                for (var i = 0, l = b.length; i < l; i++) {
                    if (b[i].id==channelId){
                        //给下拉框添加选项,当后台传值的时候选中值。
                        s2.add(new Option(b[i].name, b[i].id,true));
                    }else {
                        s2.add(new Option(b[i].name, b[i].id));
                    }

                }

            })

        }
        //清除下拉框中的选项,如果不清楚地话,会直接叠加在下边
        function clearSelectbox(selectbox) {
            for (var i = 0, len = selectbox.options.length; i < len; i++) {
                selectbox.remove(0);
            }
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 Spring Boot 中使用 Freemarker 自定义标签,可以通过以下步骤实现: 1. 创建一个自定义标签类,继承 `freemarker.template.TemplateDirectiveModel` 接口,并实现其中的 `execute` 方法,该方法用于处理自定义标签的逻辑。 ```java @Component public class CustomTagDirective implements TemplateDirectiveModel { @Autowired private UserService userService; // 举例注入一个服务类 @Override public void execute(Environment environment, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { // 处理自定义标签逻辑,可以使用 environment、params、body 等参数 String userId = params.get("userId").toString(); User user = userService.getUserById(userId); environment.getOut().write(user.getName()); } } ``` 2. 在 Spring Boot 的配置文件中注册自定义标签类。 ```java @Configuration public class FreemarkerConfig { @Autowired private CustomTagDirective customTagDirective; @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("classpath:/templates"); Map<String, Object> variables = new HashMap<>(); variables.put("customTag", customTagDirective); configurer.setFreemarkerVariables(variables); return configurer; } } ``` 3. 在 Freemarker 模板中使用自定义标签。 ```html <#assign userId = "1" /> <@customTag userId=userId /> ``` 在以上代码中,我们首先通过 `<#assign>` 定义了一个变量 `userId`,然后通过 `<@customTag>` 调用自定义标签,并将 `userId` 作为参数传入。 这样就可以在 Spring Boot 中使用自定义Freemarker 标签了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rorschach01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值