S'ha produït un error mentre es processava la plantilla.
The following has evaluated to null or missing:
==> resourcePageUrl.getSiblings()[i] [in template "74588389795879#20119#FULL-SERVICE" at line 94, column 79]
----
Tip: It's the final [] step 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 curPageUrl = resourcePageUrl... [in template "74588389795879#20119#FULL-SERVICE" in macro "renderTopicRow" at line 94, column 57]
- Reached through: @renderTopicRow iconFilename="certifi... [in template "74588389795879#20119#FULL-SERVICE" at line 272, column 17]
----
1<#assign dlFileEntry = serviceLocator.findService("com.liferay.document.library.kernel.service.DLFileEntryLocalService")>
2
3<#assign iconsThemePath = "/o/edetheme-theme/images/icons/" />
4
5<#function getFileEntryByUrl url>
6 <#assign urlParts = url?split("/")>
7 <#assign groupId = "">
8 <#assign uuId = "">
9
10 <#if (urlParts?size >= 6)>
11 <#assign groupId = urlParts[2]?number>
12 <#assign uuId = urlParts[5]?keep_before("?")>
13 </#if>
14
15 <#if groupId?has_content && uuId?has_content>
16 <#return dlFileEntry.getFileEntryByUuidAndGroupId(uuId, groupId)>
17 <#else>
18 <#return null>
19 </#if>
20</#function>
21
22<#macro renderSection id title siblings threshold showMoreText showLessText listCssClass="" serviceProcess=false isFaq=false>
23 <#if (siblings?size > 0) && (siblings[0].getData()?has_content) >
24 <div id="${id}">
25 <h2>${title}</h2>
26
27 <#if (serviceProcess)>
28 <h3 class="mt-4">${languageUtil.get(locale, "when-applying-through-the-website")}</h3>
29 </#if>
30
31 <ul class="${listCssClass} ${serviceProcess?then('mb-5 mt-3', 'my-5')}">
32 <#list 0..siblings?size-1 as i>
33 <#if siblings[i].getData()?? && siblings[i].getData() != "">
34 <#assign isAnswer = isFaq && ((i + 1) % 2 == 0)>
35
36 <#if (i > threshold)>
37 <li data-hidden-li class="d-none mb-3 ${isAnswer?then('font-weight-normal', '')}">${siblings[i].getData()}</li>
38 <#else>
39 <li class="mb-3 ${isAnswer?then('font-weight-normal', '')}">${siblings[i].getData()}</li>
40 </#if>
41 </#if>
42 </#list>
43 </ul>
44
45 <#if (siblings?size > threshold + 1)>
46 <a data-toggle-show href="javascript:void(0)" class="font-weight-bold text-brand-1">
47 <span>${showMoreText}</span>
48 <span class="d-none">${showLessText}</span>
49 </a>
50 </#if>
51 <hr class="my-5">
52 </div>
53 </#if>
54</#macro>
55
56<#macro renderTopicRow iconFilename title content isResources=false isServiceFees=false withoutHr=false listCssClass="">
57 <div class="d-flex align-items-start justify-content-start">
58 <img
59 class="mr-4"
60 src="${iconsThemePath + iconFilename}"
61 />
62 <div class="row w-100">
63 <div class="col-12 col-md-5">
64 <h4 class="mb-md-0">${title}</h4>
65 </div>
66
67 <div class="col-12 col-md-7 d-flex flex-column">
68 <#if content?is_string>
69 <p class="mb-0">${content}<p>
70 <#elseif (content?is_sequence) && (isResources == false)>
71 <ul class="${listCssClass}">
72 <#list content as item>
73 <#if item.getData() != "">
74 <li class="mb-2 ${(item?is_first && isServiceFees)?then('font-weight-normal', '')}"> ${item.getData()}</li>
75 </#if>
76 </#list>
77 </ul>
78 <#elseif isResources>
79 <ul class="list-unstyled">
80 <#list content as item>
81 <#if (item.getData()??) && (item.getData() != "")>
82 <#assign fileEntry = getFileEntryByUrl(item.getData()) />
83
84 <li>
85 <a href="${item.getData()}" class="text-dark" target="_blank">
86 ${fileEntry.getFileName()?replace(serviceTitle.getData() + " - " , "")} ${(fileEntry.getSize()/1024)?round}KB
87 </a>
88 </li>
89 </#if>
90 </#list>
91
92 <#list 0..resourcePageTitle.getSiblings()?size-1 as i>
93 <#assign curPageTitle = resourcePageTitle.getSiblings()[i].getData() />
94 <#assign curPageUrl = resourcePageUrl.getSiblings()[i].getData() />
95
96 <#if (curPageTitle?has_content) && (curPageUrl?has_content)>
97 <li>
98 <a href="${curPageUrl}" class="text-dark" target="_blank">
99 ${curPageTitle}
100 </a>
101 </li>
102 </#if>
103 </#list>
104 </ul>
105 </#if>
106 </div>
107 </div>
108 </div>
109
110 <#if (withoutHr == false)>
111 <hr class="my-5">
112 </#if>
113</#macro>
114
115<div class="full-service pt-7 d-flex flex-column">
116 <div class="full-service-header-wrapper">
117 <div class="full-service-header bg-brand-2 w-100">
118 <div class="container position-relative">
119 <#if (serviceTitle.getData())?? && (serviceTitle.getData()) != "">
120 <div class="py-4">
121 <h1 class="full-service-title text-brand-1">${serviceTitle.getData()}</h1>
122 </div>
123 </#if>
124 <#if (startServiceLink.getData())?? && (startServiceLink.getData()) != "">
125 <a
126 href="${startServiceLink.getData()}"
127 class="full-service-card-button start-service-btn-scrolled bg-white text-brand-1 p-3 mb-4 d-none"
128 target="_blank"
129 >
130 <h6 class="mb-0">${languageUtil.get(locale, "start-service")}</h6>
131 <img class="arrow-icon mx-3" src="${iconsThemePath}arrow-right-golden.svg" />
132 </a>
133 </#if>
134 <div class="full-service-card position-absolute w-100 px-3 py-4 p-md-6 row">
135 <div class="d-flex flex-column col-7 col-md-4">
136 <#if (startServiceLink.getData())?? && (startServiceLink.getData() != "")>
137 <a
138 href="${startServiceLink.getData()}"
139 class="full-service-card-button bg-white text-brand-1 p-3 mb-4"
140 target="_blank"
141 >
142 <h6 class="mb-0">${languageUtil.get(locale, "start-service")}</h6>
143 <img class="arrow-icon" src="${iconsThemePath}arrow-right-golden.svg" />
144 </a>
145 </#if>
146 <#if (serviceCardFile.getData())?? && (serviceCardFile.getData() != "")>
147 <a href="${serviceCardFile.getData()}" class="full-service-card-button border border-dark text-brand-1 p-3">
148 <h6 class="mb-0">${languageUtil.get(locale, "download-service-card")}</h6>
149 <img class="download-icon" src="${iconsThemePath}download.svg" />
150 </a>
151 </#if>
152 </div>
153 <div class="d-none d-md-block col-4"></div>
154 <div class="d-flex flex-column col-5 col-md-4 d-flex justify-content-start justify-content-md-center">
155 <div class="mb-1 mb-md-4">
156 <h6 class="text-brand-1">${languageUtil.get(locale, "service-completion-duration")}</h6>
157 <#if (serviceCompletionDuration.getData())?? && (serviceCompletionDuration.getData() != "")>
158 <p>${serviceCompletionDuration.getData()}</p>
159 </#if>
160 </div>
161 <div>
162 <h6 class="text-brand-1">${languageUtil.get(locale, "service-fees")}</h6>
163 <ul class="list-unstyled service-fees-list">
164 <#list serviceFeesInfo.getSiblings() as item>
165 <#if item_index < 2 && item.getData() != "">
166 <li>${item.getData()}</li>
167 </#if>
168 </#list>
169 </ul>
170 </div>
171 </div>
172 </div>
173 </div>
174 </div>
175 </div>
176
177 <div class="full-service-content container position-relative py-2 py-sm-4 py-md-6">
178 <#if (aboutService.getData())?? && (aboutService.getData()) != "">
179 <div id="about">
180 <h2 class="mb-4">${languageUtil.get(locale, "about-the-service")}</h2>
181 <p>${aboutService.getData()}</p>
182 </div>
183 <hr class="my-5" >
184 </#if>
185
186 <@renderSection
187 id="service-process"
188 title=languageUtil.get(locale, "service-process")
189 siblings=step.getSiblings()
190 threshold=3
191 showMoreText=languageUtil.get(locale, "show-more")
192 showLessText=languageUtil.get(locale, "show-less")
193 listCssClass="list-unstyled"
194 serviceProcess=true
195 />
196
197 <@renderSection
198 id="conditions-and-requirements"
199 title=languageUtil.get(locale, "conditions-and-requirements")
200 siblings=conditionOrRequirement.getSiblings()
201 threshold=0
202 showMoreText=languageUtil.get(locale, "show-all-conditions-and-requirements")
203 showLessText=languageUtil.get(locale, "show-less")
204 listCssClass="list-unstyled"
205 />
206
207 <@renderSection
208 id="required-documents"
209 title=languageUtil.get(locale, "required-documents")
210 siblings=requiredDocument.getSiblings()
211 threshold=6
212 showMoreText=languageUtil.get(locale, "show-all-required-documents")
213 showLessText=languageUtil.get(locale, "show-less")
214 />
215
216 <@renderSection
217 id="faqs"
218 title=languageUtil.get(locale, "faqs")
219 siblings=faq.getSiblings()
220 threshold=1
221 showMoreText=languageUtil.get(locale, "show-all-faqs")
222 showLessText=languageUtil.get(locale, "show-less")
223 listCssClass="list-unstyled"
224 isFaq=true
225 />
226
227 <@renderTopicRow
228 iconFilename="clock.svg"
229 title=languageUtil.get(locale, "service-completion-duration")
230 content=serviceCompletionDuration.getData()
231 />
232
233 <@renderTopicRow
234 iconFilename="coins.svg"
235 title=languageUtil.get(locale, "service-fees")
236 content=serviceFeesInfo.getSiblings()
237 listCssClass="list-unstyled"
238 isServiceFees=true
239 />
240
241 <@renderTopicRow
242 iconFilename="globe.svg"
243 title=languageUtil.get(locale, "service-channels")
244 content=serviceChannel.getSiblings()
245 />
246
247 <@renderTopicRow
248 iconFilename="pin.svg"
249 title=languageUtil.get(locale, "service-locations")
250 content=serviceLocation.getSiblings()
251 />
252
253 <@renderTopicRow
254 iconFilename="support.svg"
255 title=languageUtil.get(locale, "support")
256 content=support.getData()
257 />
258
259 <@renderTopicRow
260 iconFilename="target.svg"
261 title=languageUtil.get(locale, "target-audience")
262 content=targetAudience.getData()
263 />
264
265 <@renderTopicRow
266 iconFilename="card.svg"
267 title=languageUtil.get(locale, "payment-channels")
268 content=paymentChannel.getSiblings()
269 listCssClass="list-unstyled"
270 />
271
272 <@renderTopicRow
273 iconFilename="certificate.svg"
274 title=languageUtil.get(locale, "resources")
275 content=resource.getSiblings()
276 isResources=true
277 />
278
279 <@renderTopicRow
280 iconFilename="board.svg"
281 title=languageUtil.get(locale, "department-name")
282 content=departmentName.getData()
283 />
284
285 <@renderTopicRow
286 iconFilename="badge.svg"
287 title=languageUtil.get(locale, "sector-name")
288 content=sectorName.getData()
289 />
290
291 <@renderTopicRow
292 iconFilename="hand.svg"
293 title=languageUtil.get(locale, "main-service")
294 content=mainService.getData()
295 />
296
297 <@renderTopicRow
298 iconFilename="code.svg"
299 title=languageUtil.get(locale, "service-code")
300 content=serviceCode.getData()
301 />
302
303 <@renderTopicRow
304 iconFilename="gears.svg"
305 title=languageUtil.get(locale, "service-classification")
306 content=serviceClassification.getData()
307 />
308
309 <@renderTopicRow
310 iconFilename="menu.svg"
311 title=languageUtil.get(locale, "service-type")
312 content=serviceTypeDescription.getData()
313 />
314
315 <@renderTopicRow
316 iconFilename="flag.svg"
317 title=languageUtil.get(locale, "sub-service-type")
318 content=subServiceType.getData()
319 />
320
321 <@renderTopicRow
322 iconFilename="message.svg"
323 title=languageUtil.get(locale, "related-services")
324 content=relatedService.getData()
325 />
326
327 <@renderTopicRow
328 iconFilename="stack.svg"
329 title=languageUtil.get(locale, "service-bundle")
330 content=serviceBundle.getData()
331 />
332
333 <@renderTopicRow
334 iconFilename="user.svg"
335 title=languageUtil.get(locale, "number-of-users")
336 content=numberOfUsers.getData()
337 />
338
339 <@renderTopicRow
340 iconFilename="chart.svg"
341 title=languageUtil.get(locale, "number-of-transactions")
342 content=numberOfTransactions.getData()
343 />
344
345 <@renderTopicRow
346 iconFilename="info.svg"
347 title=languageUtil.get(locale, "notes")
348 content=notes.getData()
349 withoutHr=true
350 />
351 </div>
352</div>
353
354<script>
355 const fullServiceTemplate = document.querySelector(".full-service");
356 const fullServiceHeader = fullServiceTemplate.querySelector(".full-service-header");
357 const toggleListVisibilityAnchors = fullServiceTemplate.querySelectorAll("a[data-toggle-show]");
358
359 toggleListVisibilityAnchors.forEach(anchor => {
360 anchor.addEventListener("click", () => {
361 const sectionContainer = anchor.parentElement;
362 const listElement = sectionContainer.querySelector("ul");
363 const anchorLanguageKeys = sectionContainer.querySelectorAll("a span");
364 const hiddenList = listElement.querySelectorAll("li[data-hidden-li]");
365
366 hiddenList.forEach(li => li.classList.toggle("d-none"));
367 anchorLanguageKeys.forEach(lanugageKey => lanugageKey.classList.toggle("d-none"));
368 })
369 })
370
371 const handleScroll = () => {
372 const isLargeScreen = window.innerWidth >= 768;
373 const isScrolled = window.scrollY > 0;
374
375 if (isLargeScreen && isScrolled) {
376 fullServiceHeader.classList.add("scrolled");
377 fullServiceHeader.parentElement.style.height = "20rem";
378 }
379
380 if (isLargeScreen && !isScrolled){
381 fullServiceHeader.classList.remove("scrolled");
382 fullServiceHeader.parentElement.style.height = "40rem";
383 }
384 }
385
386 window.addEventListener("scroll", handleScroll);
387</script>
388
389<style>
390 .full-service {
391 --header-height-md: 40rem;
392 --header-height-sm: 25rem;
393 --header-height-xs: 30rem;
394 --card-border-radius-desktop: 5rem;
395 --card-border-radius-mobile: 2.5rem;
396 --button-border-radius: 1rem;
397 --button-border-width: 0.13rem;
398 }
399
400 .full-service p,
401 .full-service li {
402 font-weight: 300;
403 }
404
405 .full-service .full-service-header-wrapper {
406 height: var(--header-height-md);
407 transition: height 0.3s ease;
408 }
409
410 .full-service .full-service-header {
411 height: 22rem !important;
412 transition: all 0.3s ease;
413 z-index: 1 !important;
414 }
415
416 .full-service .full-service-card {
417 background-color: #F1F2F2;
418 border-radius: var(--card-border-radius-desktop);
419 transition: border-radius 0.3s ease;
420 }
421
422 .full-service .full-service-card-button {
423 border-radius: var(--button-border-radius);
424 cursor: pointer;
425 border-width: var(--button-border-width) !important;
426 display: flex;
427 justify-content: space-between;
428 align-items: center;
429 transition: all 0.2s ease;
430 }
431
432 .full-service .full-service-card-button:hover {
433 background-color: rgba(0, 0, 0, 0.05);
434 }
435
436 .full-service .full-service-card-button .arrow-icon:dir(rtl) {
437 transform: rotate(180deg);
438 }
439
440 .full-service .full-service-header.scrolled {
441 height: auto !important;
442 }
443
444 .full-service .full-service-header.scrolled {
445 position: fixed !important;
446 height: auto !important;
447 z-index: 10;
448 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
449 }
450
451 .full-service .full-service-header.scrolled .container {
452 display: flex;
453 justify-content: space-between;
454 align-items: center;
455 }
456
457 .full-service .full-service-header.scrolled .full-service-card {
458 display: none;
459 }
460
461 .full-service .full-service-header.scrolled .start-service-btn-scrolled {
462 display: flex !important;
463 justify-content: space-between;
464 align-items: center;
465 text-wrap: nowrap;
466 margin-bottom: 0 !important;
467 width: 19rem;
468 transition: all 0.2s ease;
469 }
470
471 .full-service .full-service-header.scrolled .start-service-btn-scrolled:hover {
472 background-color: rgba(0, 0, 0, 0.05);
473 }
474
475 .full-service .full-service-title {
476 display: -webkit-box;
477 -webkit-line-clamp: 2;
478 -webkit-box-orient: vertical;
479 overflow: hidden;
480 text-overflow: ellipsis;
481 }
482
483 @media screen and (max-width: 767px) {
484 .full-service .full-service-header-wrapper {
485 height: var(--header-height-sm) !important;
486 }
487
488 .full-service .full-service-card {
489 border-radius: var(--card-border-radius-mobile);
490 }
491
492 .full-service .full-service-card h6 {
493 font-size: 0.875rem !important;
494 }
495
496 .full-service .full-service-card p {
497 font-size: 0.75rem !important;
498 }
499
500 .full-service .arrow-icon {
501 width: 0.6rem !important;
502 }
503
504 .full-service .full-service-card .download-icon {
505 width: 1rem !important;
506 }
507
508 .full-service .full-service-card .full-service-card-button {
509 border-width: 0.1rem !important;
510 }
511
512 .full-service .service-fees-list {
513 display: -webkit-box;
514 -webkit-line-clamp: 3;
515 -webkit-box-orient: vertical;
516 overflow: hidden;
517 text-overflow: ellipsis;
518 }
519 }
520
521 @media screen and (max-width: 575px) {
522 .full-service .full-service-header-wrapper {
523 height: var(--header-height-xs) !important;
524 }
525 }
526
527 @media screen and (max-width: 376px) {
528 .full-service .full-service-header-wrapper {
529 height: 35rem !important;
530 }
531 }
532</style>