An error occurred while processing the template.
The following has evaluated to null or missing:
==> cur_CardContent.addons [in template "20115#20151#CARD" at line 227, column 55]
----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to 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: #assign addons = cur_CardContent.addo... [in template "20115#20151#CARD" at line 227, column 37]
----
1<#assign serviceContext = staticUtil["com.liferay.portal.kernel.service.ServiceContextThreadLocal"].getServiceContext()>
2<#if serviceContext.getThemeDisplay().getThemeSetting("v2-look-and-feel")?has_content && serviceContext.getThemeDisplay().getThemeSetting("v2-look-and-feel")!="">
3 <#assign v2_enabled = serviceContext.getThemeDisplay().getThemeSetting("v2-look-and-feel")?boolean />
4<#else>
5 <#assign v2_enabled = false />
6</#if>
7<#if v2_enabled>
8<#assign cardCount = CardContent.getSiblings()?size />
9<script>
10 window.addEventListener('DOMContentLoaded', function() {
11 function equalizeHeights() {
12 const headers = document.querySelectorAll('.card-v2__content__header');
13 let maxHeight = 0;
14 if(headers && headers.length > 1) {
15 headers.forEach(function(header) {
16 const height = header.offsetHeight;
17 if (height > maxHeight) {
18 maxHeight = height;
19 }
20 });
21
22 headers.forEach(function(header) {
23 header.style.height = maxHeight - 48 + 'px';
24 });
25 }
26 }
27 equalizeHeights();
28
29 // ===== CAROUSEL LOGIC =====
30 var wrapper = document.querySelector('.card-v2__carousel-wrapper');
31 if (wrapper) {
32 var track = wrapper.querySelector('.card-v2__carousel-track');
33 var btnPrev = wrapper.querySelector('.card-v2__carousel-btn--prev');
34 var btnNext = wrapper.querySelector('.card-v2__carousel-btn--next');
35 var currentIndex = 0;
36 var totalCards = track ? track.children.length : 0;
37
38 function isNotDesktop() {
39 return window.innerWidth <= 1024;
40 }
41
42 function updateCarousel() {
43 if (isNotDesktop()) {
44 track.style.transform = 'none';
45 return;
46 }
47 var visible = 3;
48 var cardWidthPercent = 100 / visible;
49 track.style.transform = 'translateX(-' + (currentIndex * cardWidthPercent) + '%)';
50 btnPrev.disabled = currentIndex === 0;
51 btnNext.disabled = currentIndex >= totalCards - visible;
52 }
53
54 if (btnPrev && btnNext && track) {
55 btnPrev.addEventListener('click', function() {
56 if (!isNotDesktop() && currentIndex > 0) {
57 currentIndex--;
58 updateCarousel();
59 }
60 });
61
62 btnNext.addEventListener('click', function() {
63 if (!isNotDesktop() && currentIndex < totalCards - 3) {
64 currentIndex++;
65 updateCarousel();
66 }
67 });
68
69 window.addEventListener('resize', function() {
70 currentIndex = 0;
71 updateCarousel();
72 });
73
74 updateCarousel();
75 }
76 }
77 });
78</script>
79 <#if cardCount gt 3>
80 <!-- CAROUSEL: more than 3 cards -->
81 <div class="card-v2__carousel-wrapper mt-5">
82 <button class="card-v2__carousel-btn card-v2__carousel-btn--prev" disabled aria-label="Previous">
83 <i class="icons icons--navigate_before"></i>
84 </button>
85 <div class="card-v2__carousel-track-container">
86 <div class="card-v2__carousel-track">
87 <#if CardContent.getSiblings()?has_content>
88 <#assign count = 0>
89 <#list CardContent.getSiblings() as cur_CardContent>
90 <!-- Card -->
91 <section class="card-v2 ${getterUtil.getBoolean((cur_CardContent.HighlightedProduct.isHighlighted.getData())?? && getterUtil.getBoolean(cur_CardContent.HighlightedProduct.isHighlighted.getData()))?string("card-v2--highlighted", "")}">
92 <!-- Content -->
93 <div class="card-v2__content">
94 <#if (cur_CardContent.HighlightedProduct.isHighlighted.getData())?? && getterUtil.getBoolean(cur_CardContent.HighlightedProduct.isHighlighted.getData())>
95 <div class="card-v2__content__highlight">
96 <span>${htmlUtil.unescape(cur_CardContent.HighlightedProduct.displayName.getData())}</span>
97 </div>
98 </#if>
99 <#if (cur_CardContent.Headline.getData())??>
100 <div class="card-v2__content__header">
101 <div class="card-v2__content__header__headline">
102 <h2>${htmlUtil.unescape(cur_CardContent.Headline.getData())}</h2>
103 </div>
104 <div class="card-v2__content__header__info">
105 <#if (cur_CardContent.SubHeadline.getData())??>
106 <div class="card-v2__content__header__sub-headline">
107 <p>${htmlUtil.unescape(cur_CardContent.SubHeadline.getData())}</p>
108 </div>
109 </#if>
110 <#if (cur_CardContent.Price.getData())??>
111 <div class="card-v2__content__header__price">
112 <p>${htmlUtil.unescape(cur_CardContent.Price.getData())}</p>
113 </div>
114 </#if>
115 </div>
116 </div>
117 </#if>
118
119 <#if cur_CardContent.Coverages.getSiblings()?has_content>
120 <div class="card-v2__content__body">
121 <ul class="card-v2__content__body__list">
122 <#list cur_CardContent.Coverages.getSiblings() as cur_CardContent_Coverages>
123 <#if (cur_CardContent_Coverages.getData())??>
124 <li class="card-v2__content__body__list__item">
125 <i class="icon-check_circle color-success-lighter"></i>
126 <span>${htmlUtil.unescape(cur_CardContent_Coverages.getData())}</span>
127 </li>
128 </#if>
129 </#list>
130 <#assign addons = cur_CardContent.addons.getSiblings() />
131 <#if addons?has_content && addons?first.getData() != ''>
132 <#list addons as cur_CardContent_Addons>
133 <#if (cur_CardContent_Addons.getData())??>
134 <li class="card-v2__content__body__list__item">
135 <div class="card-v2__content__body__list__item__icon" >
136 <i class="icon-east color-white"></i>
137 </div>
138 <span>${htmlUtil.unescape(cur_CardContent_Addons.getData())}</span>
139 <#if (cur_CardContent_Addons.tooltip.getData())??>
140 <div class="tooltip__tooltip--top" data-tooltip="${htmlUtil.unescape(cur_CardContent_Addons.tooltip.getData())}">
141 <i class="icon-info card-v2__content__body__list__item__tooltip-icon" ></i>
142 </div>
143 </#if>
144 </li>
145 </#if>
146 </#list>
147 </#if>
148 </ul>
149 </div>
150 </#if>
151
152 <div class="card-v2__content__footer">
153 <#if (cur_CardContent.CALink.CALinkValue.getData())??>
154 <div class="card-v2__content__footer__link">
155 <a href="${cur_CardContent.CALink.CALinkValue.getData()}" onclick="pushDataLayerCardNavigation('${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}', '${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}', themeDisplay.getPlid(), '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '', '${htmlUtil.unescape(cur_CardContent.Price.getData())}', '${count}')">
156 <span>${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}</span>
157 <i class="icon-east"></i>
158 </a>
159 </div>
160 </#if>
161 <#if (cur_CardContent.CAButton.CAButtonValue.getData())??>
162 <div class="card-v2__content__footer__button">
163 <a href="${cur_CardContent.CAButton.CAButtonValue.getData()}" onclick="pushDataLayerCardNavigation('${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}', '${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}', themeDisplay.getPlid(), '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '', '${htmlUtil.unescape(cur_CardContent.Price.getData())}', '${count}')">${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}</a>
164 </div>
165 </#if>
166 </div>
167 </div>
168 <!-- /Content -->
169 </section>
170 <!-- /Card -->
171 <#assign count = count + 1>
172 </#list>
173 </#if>
174 </div>
175 </div>
176 <button class="card-v2__carousel-btn card-v2__carousel-btn--next" aria-label="Next">
177 <i class="icons icons--navigate_next"></i>
178 </button>
179 </div>
180 <#else>
181 <!-- STATIC: 3 or fewer cards -->
182 <div class="card-v2__list mt-5">
183 <#if CardContent.getSiblings()?has_content>
184 <#assign count = 0>
185 <#list CardContent.getSiblings() as cur_CardContent>
186 <!-- Card -->
187 <section class="card-v2 ${getterUtil.getBoolean((cur_CardContent.HighlightedProduct.isHighlighted.getData())?? && getterUtil.getBoolean(cur_CardContent.HighlightedProduct.isHighlighted.getData()))?string("card-v2--highlighted", "")}">
188 <!-- Content -->
189 <div class="card-v2__content">
190 <#if (cur_CardContent.HighlightedProduct.isHighlighted.getData())?? && getterUtil.getBoolean(cur_CardContent.HighlightedProduct.isHighlighted.getData())>
191 <div class="card-v2__content__highlight">
192 <span>${htmlUtil.unescape(cur_CardContent.HighlightedProduct.displayName.getData())}</span>
193 </div>
194 </#if>
195 <#if (cur_CardContent.Headline.getData())??>
196 <div class="card-v2__content__header">
197 <div class="card-v2__content__header__headline">
198 <h2>${htmlUtil.unescape(cur_CardContent.Headline.getData())}</h2>
199 </div>
200 <div class="card-v2__content__header__info">
201 <#if (cur_CardContent.SubHeadline.getData())??>
202 <div class="card-v2__content__header__sub-headline">
203 <p>${htmlUtil.unescape(cur_CardContent.SubHeadline.getData())}</p>
204 </div>
205 </#if>
206 <#if (cur_CardContent.Price.getData())??>
207 <div class="card-v2__content__header__price">
208 <p>${htmlUtil.unescape(cur_CardContent.Price.getData())}</p>
209 </div>
210 </#if>
211 </div>
212 </div>
213 </#if>
214
215 <#if cur_CardContent.Coverages.getSiblings()?has_content>
216 <div class="card-v2__content__body">
217 <ul class="card-v2__content__body__list">
218 <#list cur_CardContent.Coverages.getSiblings() as cur_CardContent_Coverages>
219 <#if (cur_CardContent_Coverages.getData())??>
220 <li class="card-v2__content__body__list__item">
221 <i class="icon-check_circle color-success-lighter"></i>
222 <span>${htmlUtil.unescape(cur_CardContent_Coverages.getData())}</span>
223 </li>
224
225 </#if>
226 </#list>
227 <#assign addons = cur_CardContent.addons.getSiblings() />
228 <#if addons?has_content && addons?first.getData() != ''>
229 <#list addons as cur_CardContent_Addons>
230 <#if (cur_CardContent_Addons.getData())??>
231 <li class="card-v2__content__body__list__item">
232 <div class="card-v2__content__body__list__item__icon" >
233 <i class="icon-east color-white"></i>
234 </div>
235 <span>${htmlUtil.unescape(cur_CardContent_Addons.getData())}</span>
236 <#if (cur_CardContent_Addons.tooltip.getData())??>
237 <div class="tooltip__tooltip--top" data-tooltip="${htmlUtil.unescape(cur_CardContent_Addons.tooltip.getData())}">
238 <i class="icon-info card-v2__content__body__list__item__tooltip-icon" ></i>
239 </div>
240 </#if>
241 </li>
242 </#if>
243 </#list>
244 </#if>
245 </ul>
246 </div>
247 </#if>
248
249 <div class="card-v2__content__footer">
250 <#if (cur_CardContent.CALink.CALinkValue.getData())??>
251 <div class="card-v2__content__footer__link">
252 <a href="${cur_CardContent.CALink.CALinkValue.getData()}" onclick="pushDataLayerCardNavigation('${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}', '${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}', themeDisplay.getPlid(), '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '', '${htmlUtil.unescape(cur_CardContent.Price.getData())}', '${count}')">
253 <span>${htmlUtil.unescape(cur_CardContent.CALink.CALinkName.getData())}</span>
254 <i class="icon-east"></i>
255 </a>
256 </div>
257 </#if>
258 <#if (cur_CardContent.CAButton.CAButtonValue.getData())??>
259 <div class="card-v2__content__footer__button">
260 <a href="${cur_CardContent.CAButton.CAButtonValue.getData()}" onclick="pushDataLayerCardNavigation('${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}', '${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}', themeDisplay.getPlid(), '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '${htmlUtil.unescape(cur_CardContent.Headline.getData())}', '', '${htmlUtil.unescape(cur_CardContent.Price.getData())}', '${count}')">${htmlUtil.unescape(cur_CardContent.CAButton.CAButtonName.getData())}</a>
261 </div>
262 </#if>
263 </div>
264 </div>
265 <!-- /Content -->
266 </section>
267 <!-- /Card -->
268 <#assign count = count + 1>
269 </#list>
270 </#if>
271 <!-- /Card -->
272 </div>
273 </#if>
274</#if>