Freemarker - 如何获取自定义指令的未处理内容?

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

我需要创建一个 Freemarker 指令,将标签的“未处理”内容传递给 java 方法。目的是将默认模板片段加载到数据库中,以便可以通过另一个过程检查和编辑它们,然后输出编辑内容的结果(如果有)。我创建了一个宏,几乎可以做到这一点,问题是模板片段在传递给 java 方法之前已被处理。 这是我当前的代码: <#macro process name> <#local content><#nested/></#local> ${myjava.processContent(name, content)} </#macro> <@process 'this-content-name'><p>This is some content about ${companyName}</p></@process>

Java:

//Add and instance of this class to the Freemarker data model for use in templates.
public class MyJava {

    public String processContent(String name, String content) {
        log.debug("Data To Process: name = {}, content = {}", name, content);

        String contentToOutput = getFromDb(name);
        if(contentToOutput == null) {
            insertContentInDb(name, content);
            contentToOutput = content;
        }
        
        TemplateModel model = Environment.getCurrentEnvironment().getDataModel();
        Configuration config = Environment.getCurrentEnvironment().getConfiguration();
        Template template = new Template("template-from-content", contentToOutput, config);
        return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
    }
}

运行上述命令时,我需要看到以下记录:

Data To Process: name = this-content-name, content = <p>This is some content about ${companyName}</p>

不幸的是我看到了这个:

Data To Process: name = this-content-name, content = <p>This is some content about My Company Name</p>

问题很明显,

<#nested/>
标签在存储在我的宏中的局部变量中之前由模板引擎处理。

查看 Freemarker 源代码,我发现

Environment

invokeNestedContent()

似乎可以处理宏的内容,并且似乎有用于检索标签的原始内容的方法,即

<p>This is some content about ${companyName}</p>
。不幸的是,这些方法具有包私有访问权限,并且无法从我的代码中访问。
是否有另一种方法可以检索 Freemarker 中自定义指令的 RAW 未处理内容?
这对于构建内容管理系统来说似乎是非常有用的功能。

这确实是一种相当不寻常的使用方式。为了提供一些上下文,理论上

#nested
freemarker
1个回答
0
投票
Template

-s 实际上有一个

Template
方法(我宁愿将其视为历史文物,但无论如何它都会保留下来),所以即使它用于工具(和错误消息),信息也是如此在那里。
因此,由于上述原因,您所做的标准方法是使用 
getSource(col1, row1, col2, row2)
来阻止处理,尽管它有点过于冗长。但是,您还希望在以原始形式捕获嵌套内容后对其进行处理(执行),如果我看得很好的话(这很奇怪),这意味着您最好让 FreeMarker 将其与模板的其余部分一起解析。
所以,我认为,你可以从 

<@process 'foo'><#noparse>...</#noparse></@process>

开始(请参阅 JavaDoc-s;你可能需要使用

Environment.getCurrentDirectiveCallPlace
而不是

TemplateDirectiveModel

),这样你就有了源代码位置,然后使用

#macro
。我没试过,但我想这可以工作。
    

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