无法在我的 .ftl 文件中导入 .ftl 文件 - freemarker

问题描述 投票:0回答:1

我正在尝试使用 freemarker 来模板化我的 java 类。

我的配置bean是:

  @Bean
  public FreeMarkerConfigurer freeMarkerConfigurer() {
    FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        String[] paths = Stream.of(
                "classpath:/templates",
            "classpath:/templates/dao/",
            "classpath:/templates/pom/",
            "classpath:/common/")
        .map(path -> path.replace("/", File.separator).replace("\\", File.separator))
        .toArray(String[]::new);
    configurer.setTemplateLoaderPaths(paths);
    configurer.setDefaultEncoding("UTF-8");
    configurer.setPostTemplateLoaders();
    return configurer;
  }

我的模板文件 Type.ftl :

<#import "/common/functions.ftl" as function>
<#assign className = "${data.className}">
<#assign typeName = "${function.camelToSnakeCase(data.className)}">
<#assign packagePath = structure.packagePathPrefix + "." + structure.module?replace("-", ".") + ".core.dao.udt">

package ${packagePath};



@Data
@AllArgsConstructor
@NoArgsConstructor(force = true)
@Builder(toBuilder = true)
@UserDefinedType("${typeName}")
public class ${className} {

<#list data.columns as column>
  @Column("${column.name}")
  private ${column.dataType} ${column.name?uncap_first};

</#list>
}

如果我从当前目录引用我的 function.ftl ,它会起作用,但当我从 commons/functions.ftl 引用它时,它会失败。我必须使用 /common/functions.ftl 中的常用函数,以便所有模板都可以使用常用函数。但我的模板给出了以下错误:

2024-02-27T14:44:54.793-06:00 ERROR 58803 --- [nio-8090-exec-1] freemarker.runtime                       : Error executing FreeMarker template

freemarker.core._MiscTemplateException: Template importing failed (for parameter value "/common/functions.ftl"):
Template not found for name "common/functions.ftl".
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = org.springframework.ui.freemarker.SpringTemplateLoader@4f1fb188, loader2 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #import "/common/functions.ftl" as fu...  [in template "dao/udt/Type.ftl" at line 3, column 1]
----
    at freemarker.core.LibraryLoad.accept(LibraryLoad.java:67) ~[freemarker-2.3.32.jar:2.3.32]
    at freemarker.core.Environment.visit(Environment.java:335) ~[freemarker-2.3.32.jar:2.3.32]
    at freemarker.core.Environment.visit(Environment.java:341) ~[freemarker-2.3.32.jar:2.3.32]
    at freemarker.core.Environment.process(Environment.java:314) ~[freemarker-2.3.32.jar:2.3.32]
    at freemarker.template.Template.process(Template.java:383) ~[freemarker-2.3.32.jar:2.3.32]
    at org.springframework.ui.freemarker.FreeMarkerTemplateUtils.processTemplateIntoString(FreeMarkerTemplateUtils.java:50) ~[spring-context-support-6.1.3.jar:6.1.3]

我尝试了相对路径:

<#import "../../../common/functions.ftl" as function>

但是你又遇到错误了:

2024-02-27T14:55:44.552-06:00 ERROR 60233 --- [nio-8090-exec-1] freemarker.runtime                       : Error executing FreeMarker template

freemarker.core._MiscTemplateException: Template importing failed (for parameter value "../../../common/functions.ftl"):
Template not found for name "dao/udt/../../../common/functions.ftl".
Reason given: Backing out from the root directory is not allowed.
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/"), loader2 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/dao", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/dao/"), loader3 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/pom", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/templates/pom/"), loader4 = FileTemplateLoader(baseDir="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/common", canonicalBasePath="/Users/rahulverma/git/by-rahul/one-click-code/template-services-code-core/target/classes/common/"), loader5 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).

了解有关如何解决此问题的任何想法吗?

编辑:

我有这个最终的多模块项目(青色线),其中我收集每个模块的模板路径作为bean(粉红色线),最后将其注入配置中。 (粉色线)

我期待在 EntityTemplate.ftl 中导入具有函数/宏的 function.ftl 模板。 (黄线)请注意,function.ftl 与 EntityTemplate.ftl 完全位于不同的包中。我可以在 freeMarker 中实现此功能吗?我可以在其他模块中导入常用功能吗? 如果是的话我怎样才能实现这个目标?我尝试在类路径中提供模板 /common ,以便模板引擎可以搜索它,但它不能搜索并抛出模板未找到异常。关于如何实现这一目标有什么想法吗?目前我必须将functions.ftl 添加到每个目录,因为它只能在本地发现.ftl 文件。

spring-boot freemarker
1个回答
0
投票

使用

"classpath:/templates", "classpath:/templates/dao/", "classpath:/templates/pom/", "classpath:/common/"
,您可以指定模板 root 目录。这就是所有文件inside“dao”将出现在 FreeMarker 模板看到的顶层。

所以你应该简单地拥有

"classpath:/templates"
,然后将
commons
放入其中。当然,您也可以将
commons
放在其他地方,但是您必须在模板加载器路径中给出其父目录。

提示:您可以使用

${current_template_name}
了解当前模板名称(路径)是什么。

© www.soinside.com 2019 - 2024. All rights reserved.