We offer true flexibility, so you can tailor our business services as required.

You can customize these two ways, using declarative languages (e.g. business rules to configure and adjust functionality) and Avaloq script, our own imperative programming language, to implement your own business logic.

Almost 100% of Avaloq data and business logic is accessible through Avaloq’s APIs via our data dictionaries. 

Avaloq also provides state-of-the-art business process, case management and business rule engines that allow the flexible customization of your business logic through BPMN 2.0/CMMN 1.0 and DMN 1.1.

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>