```xml
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-view-freemarker</artifactId>
</dependency>
```

#### 1、描述

视图扩展插件，为 Solon View 提供基于 freemarker 的框架适配。


#### 2、应用示例

DemoController.java

```java
//顺便，加个国际化在模板里的演法
@I18n
@Controller
public class DemoController{
    @Mapping("/test")
    public ModelAndView test() {
        ModelAndView model = new ModelAndView("freemarker.ftl");
        model.put("title", "dock");
        model.put("msg", "你好 world!");

        return model;
    }
}
```

resources/templates/freemarker.ftl

```html
<!DOCTYPE html>
<html>
<head>
    <title>${title}</title>
</head>
<body>
ftl::${msg}；i18n::${i18n.get("login.title")}
</body>
</html>
```

#### 3、支持扩展定制示例

```java
@Configuration
public class Config {
    @Bean
    public void configure(FreemarkerRender render){
        render.putVariable("demo_var", "1");
        render.putDirective("demo_tag", new DemoTag());
        
        render.getProvider(); //:Configuration
        render.getProviderOfDebug();
    }
}
```

#### 4、自定义标签示例

以插件自带的权限验证标签为例：

```html
<#authPermissions name="user:del">
我有user:del权限
</#authPermissions>
```

自定义标签和共享变量代码实现：

```java
@Component("view:authPermissions")
public class AuthPermissionsTag implements TemplateDirectiveModel {
    @Override
    public void execute(Environment env, Map map, TemplateModel[] templateModels, TemplateDirectiveBody body) throws TemplateException, IOException {
        NvMap mapExt = new NvMap(map);

        String nameStr = mapExt.get(AuthConstants.ATTR_name);
        String logicalStr = mapExt.get(AuthConstants.ATTR_logical);

        if (Utils.isEmpty(nameStr)) {
            return;
        }

        String[] names = nameStr.split(",");

        if (names.length == 0) {
            return;
        }

        if (AuthUtil.verifyPermissions(names, Logical.of(logicalStr))) {
            body.render(env.getOut());
        }
    }
}

@Component("share:demo1")
public class Demo {
    public String hello(){
        return "hello";
    }
}
```