【问题标题】:How can I concatenate two things within a FreeMarker template?如何在 FreeMarker 模板中连接两件事?
【发布时间】:2014-10-28 14:07:40
【问题描述】:

我是 Java 的初学者,但我一直面临着修改现有软件的问题。如有任何帮助,我将不胜感激。

我的 FreeMarker 模板向一个 RESTful API 发出请求,并返回一些代表论坛上最近 20 条回复的 XML。然后它遍历它们,一个接一个地显示。

  <#assign recent = rest(restContext + "/boards/id/352/replies/recent").messages />

有一个单独的 API 端点来获取最近发布的 20 个线程。两个调用都返回格式相同的 XML。

我想做的是将这两件事合二为一,这样我就可以显示“最近的帖子和线程”。我会按response.messages.post_time 对组合项目进行排序。

我的问题是:我将如何在模板中执行此操作,这是我可以访问的唯一一段代码? rest 是 FreeMarker 内置的吗?我已经超出了我的深度,希望能得到一些帮助,Java 对我来说还是个新手。

【问题讨论】:

  • rest 未内置在 FreeMarker 中。那么recent 是什么?消息列表?如果是这样,您是否尝试过使用+ 将该列表与另一个列表连接起来?

标签: java freemarker


【解决方案1】:

这看起来很眼熟...Lithium REST API v1 请求,不是吗?

您可以做的基本上是在正确的位置合并两个响应对象(v1 的响应结构往往不是很直观......)但是正常的 rest() 上下文对象响应不能简单地在 FreeMarker 中合并(使用+ 在相同的数据类型上,例如哈希或序列),所以你需要的是 Lithium v​​14.12 或更高版本以及 restd() 上下文对象......你的代码应该看起来像这样:

<#assign replies = restd("/replies/recent", "json")?replace("\\/", "/")?replace(':null', ':"null"')?eval />
<#assign threads = restd("/topics/recent", "json")?replace("\\/", "/")?replace(':null', ':"null"')?eval />
<#assign merged = replies.response.messages.message + threads.response.messages.message />
<#assign objects = [] />

<#list merged as obj>
    <#-- to sort we have to create our own object with a more simple structure (right now the post_time is deeply nested and not accessible with ?sort_by) -->
    <#assign object = {
        "subject": obj.subject.$,
        "href": obj.href,
        "post_time": obj.post_time.$,
        "author": obj.author.login.$
    } />

    <#assign objects = objects + [object] />
</#list>

<#-- now we can sort the objects we created above, you probably want the newest objects on top, right? if not, just remove the ?reverse -->
<#assign objects = objects?sort_by("post_time")?reverse />

<ul>
    <#-- now we list again (yes...) over the sorted objects and output them -->
    <#list objects as obj>
    <li><a href="${obj.href}">${obj.subject}</a> on ${obj.post_time} from ${obj.author}</li>
    </#list>
</ul>

上面代码的解释基本上是我们需要来自 Lithium 的 REST API 的东西,可以转换为“普通”的 FreeMarker 对象/数据类型,JSON 恰好或多或少类似于 FreeMarker 哈希/序列,具有很少有例外(比如空值......),这就是为什么我们需要这些 ?replace 内置插件来“清理”传入的 JSON 字符串然后调用 ?eval (是的,这是邪恶的,但有时我们需要邪恶来对抗邪恶 =D ) 在该字符串上创建 FreeMarker 对象。

之后,我们可以简单地将对象合并到正确的位置(在您的情况下为 response.messages.message 节点)并从中创建一个新对象,然后我们可以使用它来模板化我们的组件。

排序部分使得有必要对我们刚刚合并的对象进行基本的“重组”,因为 FreeMarker 内置的 ?sort_by() 无法处理我们现在拥有的深度嵌套的对象......所以我们循环(列表)通过合并的对象并创建一个具有我们需要的属性的新对象序列,之后我们可以在该新对象序列上使用 ?sort_by 以按所需字段对其进行排序。然后对序列进行排序并准备在另一个循环中进行模板化。

【讨论】:

    猜你喜欢
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2012-04-12
    相关资源
    最近更新 更多