首先,我是 Liferay 的新手。
这几天我一直在摸索这个问题,但找不到任何东西,即使乍一看似乎很容易。
我正在创建一个具有 Liferay 6.2 自己的首选项的 portlet,并且需要在我的 FreeTemplate 主题生成的 HTML 的
<head>
标记中设置这些首选项之一。
我想到的最符合逻辑的方法是从我的 portlet 创建一个变量,以便它可以显示在我的主题中,但我找不到任何方法来实现这一点。
我当前的 portlet 代码:
HttpServletRequest request = PortalUtil.getHttpServletRequest(portletRequest);
Map<String, Object> var = new HashMap<>();
var.put("test", "Hello World");
request.setAttribute(WebKeys.VM_VARIABLES, var);
我的主题代码:
<#if test??>
true: ${test}
<#else>
false
</#if>
我不断得到假。
我的做法错了吗?如果是,我该怎么办?如果不是,我该怎么办?
注意:我知道 FreeTemplate 的
<h:head>
,但令人惊讶的是,使用它会引发模板在我的 <head>
中生成第二个 <body>
标签,您会同意,这是绝对不可接受的。也许我没有正确使用它?
编辑
为了更多地了解我的背景,我目前正在开发一个社交共享 portlet,它必须允许 1) 共享当前页面,2) 配置链接在 Facebook/Twitter 上的显示方式(使用 OpenGraph
<meta />
标签) 。我的第一次尝试是将此配置放入主题中,但我的客户绝对希望将其放在 portlet 中。
是的,方法是错误的。您不能假设主题和 portlet 之间的求值顺序 - 两者在执行中都未定义(除了两者都被执行之外),并且虽然输出流给出了有关最可能的求值顺序的一些提示,但您不能依赖关于这一点。
此外,
PortalUtil.getHttpServletRequest(portletRequest)
将为您提供一个PortletRequest
包装到HttpServletRequest
的界面中,但不是底层的
HttpServletRequest
。还有另一种方法(根据记忆)PortalUtil.getOriginalServletRequest(request)
可以为您提供来自应用程序服务器的底层HttpServletRequest
(您需要链接两个调用)。然而,并不能保证该主题实际上使用了这个。
我告诉你这个是为了告诉你:你到底想实现什么目标?很多时候,有了这样的需求,就有一种更简单的方法来做你喜欢做的事。您正在寻求替代建议,但您没有向我们提供有关您的根本问题的提示。您只是概述了到目前为止您提出的解决方案(意图)。
编辑:页面
<head>
区域中的任何内容都属于主题(或者需要 javascript 将其添加到头部区域)。在你的情况下,这似乎只适用于当前页面 - 这是可能的。
恕我直言,提供用户交互的所有内容都属于 portlet - 并且您的客户似乎也以同样的方式看待它。您仍然可以向主题添加 portlet,以便它始终存在,但一般来说,您可以更轻松地开发具有共享功能的主题,同时通过主题添加所需的元数据。
主题模板可以/不应该访问可能放置在具有该主题的页面上的某些 portlet 的变量。 如果您想向主题模板添加新变量,您可以使用 ServicePreAction 并放置代码:
Map<String, Object> var = new HashMap<>();
var.put("test", "Hello World");
request.setAttribute(WebKeys.VM_VARIABLES, var);
到
run(final HttpServletRequest request, final HttpServletResponse response)
方法。您需要实现 com.liferay.portal.kernel.events.Action
并将您的类添加到: servlet.service.events.pre
在您的门户属性中
检查此链接,其中包含 liferay 主题支持的默认变量并创建 init_custom.ftl 文件中的自定义变量 https://www.javasavvy.com/liferay-default-theme-variables/