-
Type:
Bug
-
Status: Closed
-
Resolution: Fixed
-
Affects Version/s: 7.0.6 CE GA7, 7.0.0 DXP SP8, 7.0.0 DXP FP55, 7.0.X, 7.1.X, Master
-
Fix Version/s: 7.0.0 DXP FP59, 7.0.0 DXP SP9, 7.0.X, 7.1.10 DXP FP2, 7.1.1 CE GA2, 7.1.10.1 SP1, 7.1.X, Master
-
Component/s: Themes Infrastructure > Layout Templates
-
Branch Version/s:7.1.x, 7.0.x
-
Backported to Branch:Committed
-
Story Points:2
-
Fix Priority:5
-
Git Pull Request:
-------- has introduced the ability to define layout templates with Freemarker by using the "ftl" extension instead of the "tpl" extension for these files. But the layout templates are not only evaluated during page rendering, they are rendered during startup and page customization as well (using a dummy writer). Now two problems arise:LPS-75190
- The page rendering provides more variables than the two other renderings. For example the "layout" variable is not available during startup and page customization. This was no problem with Velocity, because it silently ignores missing variables. But as Freemarker does abort template processing when accessing missing variables, the dummy rendering breaks.
- The page customization rendering is still bound to Velocity and ignores the new FTL option:
RuntimePageImpl.java
public void processCustomizationSettings( HttpServletRequest request, HttpServletResponse response, TemplateResource templateResource) throws Exception { doDispatch( request, response, null, templateResource, TemplateConstants.LANG_TYPE_VM, false); }
Steps to reproduce
Create a layout template with a "ftl" file suffix and this content:
<#if layout.rootLayout> <#assign cssClass = "root" /> <#else> <#assign cssClass = "" /> </#if> <div class="columns-1" id="main-content" role="main"> <div class="portlet-layout row"> <div class="col-md-12 portlet-column portlet-column-only ${cssClass}" id="column-1"> ${processor.processColumn("column-1", "portlet-column-content portlet-column-content-only")} </div> </div> </div>
Deploy that layout template and configure a page with it.
Expected behavior
There is no exception in the log during deployment and page configuration and I can save the page configuration.
Current behavior
I have two errors in the log.
The first during deployment because of the missing variable:
[LayoutTemplateLocalServiceImpl:520] Unable to get layout template columns com.liferay.portal.kernel.template.TemplateException: Unable to process template wktheme_WAR_wktheme_CUSTOM_Component at com.liferay.portal.template.AbstractSingleResourceTemplate.processTemplate(AbstractSingleResourceTemplate.java:85) at com.liferay.portal.service.impl.LayoutTemplateLocalServiceImpl._getColumns(LayoutTemplateLocalServiceImpl.java:515) at com.liferay.portal.service.impl.LayoutTemplateLocalServiceImpl.readLayoutTemplate(LayoutTemplateLocalServiceImpl.java:388) at com.liferay.portal.service.impl.ThemeLocalServiceImpl._readThemes(ThemeLocalServiceImpl.java:842) at com.liferay.portal.service.impl.ThemeLocalServiceImpl.init(ThemeLocalServiceImpl.java:327) ... Caused by: freemarker.core.InvalidReferenceException: The following has evaluated to null or missing: ==> layout [in template "mytheme_WAR_mytheme_CUSTOM_MyLayout" at line 1, column 6]
The second during page configuration because of the hard coded velocity mapping in RuntimePageImpl:
Suppressed: org.apache.velocity.runtime.parser.TemplateParseException: Encountered "layout" at mytheme_WAR_mytheme_CUSTOM_MyLayout[line 1, column 6] Was expecting: "(" ... at org.apache.velocity.runtime.parser.Parser.parse(Parser.java:119) at org.apache.velocity.runtime.RuntimeInstance.parse(RuntimeInstance.java:1131) at org.apache.velocity.runtime.RuntimeInstance.parse(RuntimeInstance.java:1086) at com.liferay.portal.template.velocity.internal.LiferayResourceManager$LiferayTemplate.process(LiferayResourceManager.java:209) at com.liferay.portal.template.velocity.internal.LiferayResourceManager._createTemplate(LiferayResourceManager.java:146) at com.liferay.portal.template.velocity.internal.LiferayResourceManager._getResource(LiferayResourceManager.java:184) at com.liferay.portal.template.velocity.internal.LiferayResourceManager.getResource(LiferayResourceManager.java:106) at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1400) at org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:422) at com.liferay.portal.template.velocity.internal.VelocityTemplate.processTemplate(VelocityTemplate.java:107) at com.liferay.portal.template.AbstractSingleResourceTemplate.processTemplate(AbstractSingleResourceTemplate.java:78) at com.liferay.portal.layoutconfiguration.util.RuntimePageImpl.doProcessCustomizationSettings(RuntimePageImpl.java:377) at com.liferay.portal.layoutconfiguration.util.RuntimePageImpl.doDispatch(RuntimePageImpl.java:336) at com.liferay.portal.layoutconfiguration.util.RuntimePageImpl.processCustomizationSettings(RuntimePageImpl.java:121) at com.liferay.portal.kernel.layoutconfiguration.util.RuntimePageUtil.processCustomizationSettings(RuntimePageUtil.java:52) at org.apache.jsp.layout.customization_005fsettings_jsp._jspService(customization_005fsettings_jsp:465) ...
And I can't save the page settings due to that error (no save button available).
Workaround
I patched my customization_settings.jsp to use the correct language depending on the selected template and I'm using always conditionals (<#if layout??>) when accessing any variables in my layout templates, but that makes them harder to read.