Our developer portal encourages banks and fintechs of all sizes to swap ideas and innovate with us.

It’s a treasure house of useful resources, crammed with development packages, documentation, example code and specialist user forums.
So, whether you're working on a UI component to sit on top of our existing APIs, building new data APIs or integrating third-party functionality, you’ll find the developer portal is a mine of practical information and advice.

Sign up to access our developer portal for all the latest on our open platform.

An error occurred while processing the template.
The following has evaluated to null or missing:
==> articleId  [in template "20116#20152#THREE-COLUMNS-MODULE" at line 289, column 33]

----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: ${articleId}  [in template "20116#20152#THREE-COLUMNS-MODULE" at line 289, column 31]
----
1<#--The top-level if condition is a work-around to avoid the need of updating --> 
2<#--all current contents using the Content with Picture Structure.--> 
3<#--Remove this after the old template version is not necessary anymore.--> 
4<#if Content1.Media1??> 
5<#-------------------------------------------------------------------------------------------------> 
6<#--CURRENT TEMPLATE FOR THE NEW STRUCTURE--> 
7<#-------------------------------------------------------------------------------------------------> 
8<#assign isDarkBg = BackgroundColor.getData() == "bg-dark"> 
9<#assign additionalTextClass = isDarkBg?string(" white", "")> 
10<#assign additionalBtnClass = isDarkBg?string(" btn-hover-white", "")> 
11<#assign dLFileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService")> 
12<#assign articleId = .vars['reserved-article-id'].getData() /> 
13 
14 
15  <div class="row three-columns"> 
16  <div class="bg-container-fullwidth ${BackgroundColor.getData()}"></div> 
17  <div class="col-xs-12 ${PaddingTop.getData()} ${PaddingBottom.getData()}"> 
18    <div class="row"> 
19      <#if Headline.getData()?has_content> 
20        <div id="headline-element-${articleId}" class="col-sm-12"> 
21          <h2 class="three-columns-headline${additionalTextClass}">${Headline.getData()}</h2> 
22        </div> 
23      </#if> 
24      <#if ThreeColumnsContent.getData()?has_content> 
25        <div id="description-element-${articleId}" class="col-xs-12 three-columns-description${additionalTextClass}"> 
26          ${ThreeColumnsContent.getData()} 
27        </div> 
28      </#if> 
29      <@contentSectionWithMedia "1"/> 
30      <@contentSectionWithMedia "2"/> 
31      <@contentSectionWithMedia "3"/> 
32    </div> 
33  </div> 
34</div> 
35 
36<#macro contentSectionWithMedia index> 
37  <#assign content = .vars["Content" + index]> 
38  <#assign media = content["Media" + index]> 
39  <#--The following usages of ?remove_* are necessary due to Liferay being bugged--> 
40  <#assign mediaType = media.getData()?remove_beginning("[\"")?remove_ending("\"]")> 
41  <#assign mediaCaption = content["MediaCaption" + index]> 
42  <#assign headline = content["HeadlineColumn" + index]> 
43  <#assign image = content["Image" + index]> 
44  <#assign internalLink = content["InternalLink" + index]> 
45  <#if internalLink.getData()?has_content> 
46    <#assign internalLinkName = internalLink["InternalLink" + index + "Name"]> 
47  </#if> 
48  <#assign externalLink = content["ExternalLink" + index]> 
49  <#if externalLink.getData()?has_content> 
50    <#assign externalLinkName = externalLink["ExternalLink" + index + "Name"]> 
51  </#if> 
52 
53  <#assign internalLinkFallbackLabel = languageUtil.get(locale, "avaloq-language.go-to-page")> 
54  <#assign externalLinkFallbackLabel = languageUtil.get(locale, "avaloq-language.visit-website")> 
55 
56  <#if content.getData()?has_content || headline.getData()?has_content || image.getData()?has_content> 
57    <div  class="col-xs-12 col-md-4 three-columns-section content-element-${articleId}"> 
58      <@header headline mediaType index mediaCaption/> 
59      <#if content.getData()?has_content> 
60        <div class="three-columns-section-text ${additionalTextClass}">${content.getData()}</div> 
61      </#if> 
62      <#if internalLink.getData()?has_content> 
63        <div class="three-column-section-link"> 
64          <a class="btn btn-link btn-icon-link-internal${additionalBtnClass}" href="${internalLink.friendlyUrl}"> 
65            ${internalLinkName.getData()?has_content?string(internalLinkName.getData(), internalLinkFallbackLabel)} 
66          </a> 
67        </div> 
68      </#if> 
69      <#if externalLink.getData()?has_content> 
70        <div class="three-column-section-link"> 
71          <a class="btn btn-link btn-icon-link-external${additionalBtnClass}" href="${externalLink.getData()}" target="_blank"> 
72            ${externalLinkName.getData()?has_content?string(externalLinkName.getData(), externalLinkFallbackLabel)} 
73          </a> 
74        </div> 
75      </#if> 
76    </div> 
77  </#if> 
78</#macro> 
79 
80<#macro header headline mediaType index mediaCaption> 
81  <#if headline?? && headline?has_content && mediaType?? && mediaType?has_content> 
82    <#assign mediaField = .vars["Content" + index][mediaType + index]> 
83    <#switch mediaType> 
84      <#case "Image"> 
85        <@imageElement mediaField/> 
86        <@headlineElement headline/> 
87        <#break> 
88      <#case "Video"> 
89        <#assign imageField = .vars["Content" + index]["Image" + index]/> 
90        <@headlineElement headline/> 
91        <@Html5Video mediaField imageField/> 
92        <@mediaCaptionElement mediaCaption/> 
93        <#break> 
94      <#case "YouTubeVideo"> 
95        <@headlineElement headline/> 
96        <@iframeVideo mediaField.getData()/> 
97        <@mediaCaptionElement mediaCaption/> 
98        <#break> 
99      <#case "BrightcoveVideo"> 
100        <@headlineElement headline/> 
101        <@iframeVideo mediaField.getData()/> 
102        <@mediaCaptionElement mediaCaption/> 
103        <#break> 
104    </#switch> 
105  <#-- Use Image as fallback --> 
106  <#else> 
107    <#attempt> 
108      <#assign mediaField = .vars["Content" + index]["Image" + index]> 
109      <@imageElement mediaField/> 
110      <@headlineElement headline/> 
111    <#recover> 
112    </#attempt> 
113  </#if> 
114</#macro> 
115 
116<#macro headlineElement headline> 
117  <#if headline.getData()?has_content> 
118    <#if HeadlineColumnSize.getData()=="bigHeadline"> 
119      <h2 class="three-columns-section-headline${additionalTextClass}">${headline.getData()}</h2> 
120    <#else> 
121      <h3 class="three-columns-section-headline${additionalTextClass}">${headline.getData()}</h3> 
122    </#if> 
123  </#if> 
124</#macro> 
125 
126<#macro imageElement imageField> 
127  <#if imageField.getData()?has_content> 
128 
129    <#-- Get media description (which is used as alt text for images) --> 
130    <#assign mediaDescription = "" /> 
131    <#if imageField?? && imageField.getData()?has_content > 
132      <#attempt> 
133        <#assign mediaParams = imageField.getData()?split("/") /> 
134        <#assign mediaGroupId = mediaParams[2] /> 
135        <#assign mediaUuid = mediaParams[5]?split("?")[0] /> 
136        <#assign mediaFileEntry = dLFileEntryLocalService.getFileEntryByUuidAndGroupId(mediaUuid, mediaGroupId?number) /> 
137        <#assign mediaDescription = mediaFileEntry.getDescription() /> 
138        <#recover> 
139      </#attempt> 
140    </#if> 
141 
142    <div class="three-columns-section-image"> 
143      <img src="${imageField.getData()}" alt="${mediaDescription}"/> 
144    </div> 
145  </#if> 
146</#macro> 
147 
148<#macro Html5Video videoField imageField> 
149  <video preload="none" controls poster="${imageField.getData()}"> 
150    <source src="${videoField.getData()}" type="video/mp4"> 
151  </video> 
152</#macro> 
153 
154<#macro iframeVideo iframeAsString> 
155  <#assign matchWidthOrHeight = "\\s((width=(\"|')\\d*(\"|'))|(height=(\"|')\\d*(\"|')))"/> 
156  <#assign matchAutoplay = "autoplay; "/> 
157  <#assign normalizedIframe = iframeAsString?replace("(" + matchWidthOrHeight + ")|(" + matchAutoplay + ")", "", "rs")/> 
158  ${normalizedIframe} 
159</#macro> 
160 
161<#macro mediaCaptionElement mediaCaption> 
162  <#if mediaCaption.getData()?has_content> 
163    <div class="avlq-media-caption caption">${mediaCaption.getData()}</div> 
164  </#if> 
165</#macro> 
166 
167<#else> 
168<#-------------------------------------------------------------------------------------------------> 
169<#--DEPRECATED TEMPLATE FOR DEPRECATED CONTENT TO STILL WORK--> 
170<#-------------------------------------------------------------------------------------------------> 
171  <#assign isDarkBg = BackgroundColor.getData() == "bg-dark"> 
172  <#assign additionalTextClass = isDarkBg?string(" white", "")> 
173  <#assign additionalBtnClass = isDarkBg?string(" btn-hover-white", "")> 
174  <#assign dLFileEntryLocalService = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService")> 
175<div class="row three-columns"> 
176  <div class="bg-container-fullwidth ${BackgroundColor.getData()}"></div> 
177  <div class="col-xs-12 ${PaddingTop.getData()} ${PaddingBottom.getData()}"> 
178    <div class="row"> 
179      <#if Headline.getData()?has_content> 
180        <div class="col-xs-12"> 
181          <h2 class="three-columns-headline${additionalTextClass}">${Headline.getData()}</h2> 
182        </div> 
183      </#if> 
184      <#if ThreeColumnsContent.getData()?has_content> 
185        <div class="col-xs-12 three-columns-description${additionalTextClass}"> 
186        ${ThreeColumnsContent.getData()} 
187        </div> 
188      </#if> 
189      <@contentSection "1"/> 
190      <@contentSection "2"/> 
191      <@contentSection "3"/> 
192    </div> 
193  </div> 
194</div> 
195 
196  <#function getFilePath fileField> 
197    <#assign imageURL = "#"> 
198    <#attempt> 
199      <#assign imageData = fileField?eval> 
200      <#assign imageData = processFileData(imageData)> 
201      <#assign image = dLFileEntryLocalService.fetchDLFileEntryByUuidAndGroupId(imageData["uuid"],imageData["groupId"]?eval) > 
202 
203      <#if themeDisplay.getCDNHost()?? && themeDisplay.getCDNHost()?has_content> 
204        <#assign imageURL = themeDisplay.getCDNHost() + "/documents/" + imageData["groupId"] + "/" + image.getFolder().getFolderId() + "/" +  imageData["title"] + "/" + imageData["uuid"] /> 
205      <#else> 
206        <#assign imageURL = "/documents/" + imageData["groupId"] + "/" + image.getFolder().getFolderId() + "/" +  imageData["title"] + "/" + imageData["uuid"] /> 
207      </#if> 
208      <#recover> 
209        <#assign imageURL = fileField> 
210    </#attempt> 
211 
212    <#return imageURL> 
213  </#function> 
214 
215  <#function processFileData fileData> 
216    <#if fileData["data"]??> 
217      <#return processFileData(fileData["data"]?eval)> 
218    </#if> 
219    <#return fileData> 
220  </#function> 
221 
222  <#macro contentSection index> 
223    <#assign content = .vars["Content" + index]> 
224    <#assign image = content["Image" + index]> 
225    <#assign headline = content["HeadlineColumn" + index]> 
226    <#assign internalLink = content["InternalLink" + index]> 
227    <#if internalLink.getData()?has_content> 
228      <#assign internalLinkName = internalLink["InternalLink" + index + "Name"]> 
229    </#if> 
230    <#assign externalLink = content["ExternalLink" + index]> 
231    <#if externalLink.getData()?has_content> 
232      <#assign externalLinkName = externalLink["ExternalLink" + index + "Name"]> 
233    </#if> 
234 
235    <#if content.getData()?has_content || headline.getData()?has_content || image.getData()?has_content> 
236    <div class="col-xs-12 col-md-4 three-columns-section"> 
237      <#if image.getData()?? && image.getData() != ""> 
238 
239        <#-- Get media description (which is used as alt text for images) --> 
240        <#assign mediaDescription = "" /> 
241        <#if image?? && image.getData()?has_content > 
242          <#attempt> 
243            <#assign mediaParams = image.getData()?split("/") /> 
244            <#assign mediaGroupId = mediaParams[2] /> 
245            <#assign mediaUuid = mediaParams[5]?split("?")[0] /> 
246            <#assign mediaFileEntry = dLFileEntryLocalService.getFileEntryByUuidAndGroupId(mediaUuid, mediaGroupId?number) /> 
247            <#assign mediaDescription = mediaFileEntry.getDescription() /> 
248            <#recover> 
249          </#attempt> 
250        </#if> 
251 
252        <div class="three-columns-section-image"> 
253          <img src="${getFilePath(image.getData())}" alt="${mediaDescription}"/> 
254        </div> 
255      </#if> 
256 
257      <#if headline.getData()?has_content> 
258        <#if HeadlineColumnSize.getData()=="bigHeadline"> 
259          <h2 class="three-columns-section-headline${additionalTextClass}">${headline.getData()}</h2> 
260        <#else> 
261          <h3 class="three-columns-section-headline${additionalTextClass}">${headline.getData()}</h3> 
262        </#if> 
263      </#if> 
264      <#if content.getData()?has_content> 
265        <div class="three-columns-section-text ${additionalTextClass}">${content.getData()}</div> 
266      </#if> 
267      <#if internalLink.getData()?has_content> 
268        <div class="three-column-section-link"> 
269          <a class="btn btn-link btn-icon-link-internal${additionalBtnClass}" href="${internalLink.friendlyUrl}"> 
270          ${internalLinkName.getData()!"Go to page"} 
271          </a> 
272        </div> 
273      </#if> 
274      <#if externalLink.getData()?has_content> 
275        <div class="three-column-section-link"> 
276          <a class="btn btn-link btn-icon-link-external${additionalBtnClass}" href="${externalLink.getData()}" target="_blank"> 
277          ${externalLinkName.getData()!"Visit website"} 
278          </a> 
279        </div> 
280      </#if> 
281    </div> 
282    </#if> 
283  </#macro> 
284</#if> 
285<script> 
286 
287  if ("true" === "${(Animation?? && Animation.getData() == "true")?c}" && !Liferay.Browser.isIe()) { 
288    $(document).ready(function() { 
289      if($('#headline-element-${articleId}').length){ 
290        ($('#headline-element-${articleId}')).css('opacity', '0'); 
291
292      if($('#description-element-${articleId}').length){ 
293        ($('#description-element-${articleId}')).css('opacity', '0'); 
294
295      if($('.content-element-${articleId}').length){ 
296        ($('.content-element-${articleId}')).css('opacity', '0'); 
297
298    }); 
299    // Register animation 
300    Liferay.Loader.require('avaloq-animator', function (avaloqAnimator) { 
301      avaloqAnimator.fadeIn("#headline-element-${articleId}"); 
302      avaloqAnimator.fadeIn("#description-element-${articleId}"); 
303      avaloqAnimator.fadeIn(".content-element-${articleId}"); 
304 
305    }); 
306
307</script>