Si è verificato un errore nell'elaborarazione del modello.
The following has evaluated to null or missing:
==> thisCardData  [in template "20098#20124#1784553" at line 572, column 10]

----
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: #if thisCardData?contains("journal-te...  [in template "20098#20124#1784553" in macro "printCard" at line 572, column 5]
	- Reached through: @printCard curEntry, curEntry?index  [in template "20098#20124#1784553" in function "generateHtmlData" at line 406, column 37]
----
1<!-- Tours listing UNI FTL --> 
2<#assign counter = 0> 
3<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") /> 
4<#assign assetCategoryService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryService") /> 
5<#assign thisFilterScope = "${randomNamespace}filter"> 
6 
7<#-- instanceId with id parent layout to allow emebed differrent widget on different pages --> 
8<#assign cur_time = .now> 
9<#assign urlHelper = vtaLibrary.getUrlHelper()> 
10<#assign cacheSufix = urlHelper + "_" + locale> 
11<#assign cur_instanceId = "html_data_" + themeDisplay.getLayout().uuid + cacheSufix> 
12 
13<#-- tours common filters array: --> 
14<#assign filter_tourType = []> 
15<#assign filter_month = []> 
16<#assign filter_destination = []> 
17<#assign filter_price_from = []> 
18<#assign filter_destinationCountry = []> 
19<#assign filter_interests= []> 
20<#assign filter_duration= []> 
21<#assign filter_recommended= []> 
22<#-- excursions specific filters array: --> 
23<#assign filter_estartingpoint= []> 
24<#assign filter_eduration= []> 
25<#assign departureDates= []><#-- currently used only to count dates...--> 
26 
27<#assign data_set=[]> 
28<#assign curYearYY = .now?string('yy')?number> 
29<#assign curMonthMM = .now?string('MM')?number> 
30 
31<#assign envSettings = vtaLibrary.getEnvSettings()> 
32<#assign vocDestTypenId = envSettings.vocDestTypenId?number> 
33<#assign vocPopularityId = envSettings.vocPopularityId?number> 
34<#assign embedTourCardUniId = envSettings.embedTourCardUniId> 
35<#assign structureGuidedTourId = 975893> 
36<#assign currency = "err"> 
37<#if vtaUtil??> 
38    <#assign currency = vtaUtil.getCurrencySymbol(request)> 
39</#if> 
40 
41<#-- clear all cache by URL param (use ...url..."?cacheUpdate" ) --> 
42<#assign curUrl = themeDisplay.getURLCurrent()?string> 
43<#if curUrl?contains("?cacheUpdate")> 
44    <#assign temp = freemarkerFilterCache.clearFreemarkerCache()> 
45    <script> 
46        console.log("Force cache update."); 
47    </script> 
48</#if> 
49 
50<#assign showFilerPanel = entries?size gte 5> 
51 
52<#-- check if are only Guided tours in list --> 
53<#assign isGuidedListingOnly = false> 
54<#if entries?has_content> 
55    <#assign cur_guidesTypeCounter = 0> 
56    <#list entries as curEntry> 
57        <#assign cur_renderer=curEntry.getAssetRenderer() /> 
58        <#assign cur_journalArticle=cur_renderer.getArticle() /> 
59        <#assign cur_structureId = cur_journalArticle.getDDMStructureId()?string> 
60        <#if vtaLibrary.getTemplateForStructure(cur_structureId?string,"name") = "guided"> 
61             <#assign cur_guidesTypeCounter = cur_guidesTypeCounter + 1>    
62        </#if> 
63    </#list> 
64    <#assign isGuidedListingOnly = (cur_guidesTypeCounter == entries?size)> 
65</#if> 
66<!-- GUIDED ONLY: ${isGuidedListingOnly?string} --> 
67<#if isGuidedListingOnly> 
68    <#assign sortString = "gu_rec"> 
69<#else> 
70    <#assign sortString = "rec"> 
71</#if> 
72 
73<#-- ################## -->  
74<script src="${themeDisplay.getPathThemeJavaScript()}/vta-filter.js?t=${themeDisplay.getTheme().getTimestamp()}" type="text/javascript" data-senna-track="permanent"></script> 
75 
76 
77<@generateData/> 
78<#assign htmlData = generateHtmlData()> 
79 
80<!-- print html --> 
81${htmlData} 
82 
83<#-- ******** generate data ********* --> 
84<#macro generateData> 
85    <#if entries?has_content> 
86        <#list entries as curEntry> 
87            <@generateCardData curEntry curEntry?index/> 
88        </#list> 
89    </#if> 
90</#macro> 
91 
92 
93<#function generateHtmlData> 
94    <#-- HTML cachable data --> 
95    <#local htmlData> 
96 
97        <#compress> 
98        <style> 
99            .d-tour.hidden, 
100            .results-line .result, 
101            #zeroBanner.hidden, 
102            .results-line[data-results="1"] .results { 
103                display:none; 
104
105 
106            .results-line[data-results="1"] .result { 
107                display:inline; 
108
109 
110            /* default thumbs css */ 
111            .-Tour-swiperThumbs .swiper-slide { 
112                width: 110px; 
113                margin-right: 2px; 
114
115        </style> 
116 
117        <div id="${thisFilterScope}" class="-sidebarLayout -Section -Section--verticalIndentLarge" data-sidewidth="3" data-space="2"   <#--data-direction="row-reverse" data-sideright="true"--> data-switchxsmd="true" data-overflowvisible="true"> 
118            <div> 
119 
120                <#-- filter col --> 
121                <div id="${thisFilterScope}-filter" class="-formElements js-f-col-filter" style="${showFilerPanel?then('','display:none;')}"> 
122                    <div class="-Collapse -Collapse--xsmdTypeDropdown -Collapse--xsmdExpandFullScreen -formElements"> 
123                        <div class="-Collapse-contents"> 
124                            <div class="-Collapse-content"> 
125                                <div id="collapseFilters" class="-Collapse-collapse collapse" aria-labelledby="collapseFiltersToggle" data-expanded-md="true"> 
126                                    <div class="-Panel -Panel--xsmdTypeModalFlyout -Collapse-panel -Collapse-panel--typeModalFlyout"> 
127                                        <div class="-Panel-inner"> 
128                                            <div class="-Panel-head"> 
129                                                <div class="-clusterLayout" data-space="05" data-align="center" data-justify="space-between"> 
130                                                    <div> 
131                                                        <div> 
132                                                            <strong class="-clusterLayout" data-space="02" data-align="center" data-nowrap="true"> 
133                                                                <span> 
134                                                                    <i class="-Icon -Icon--filter"></i><span>${translationsUtils.getMessage(locale,'vta.webcontent.filterBy')}</span> 
135                                                                </span> 
136                                                            </strong> 
137                                                        </div> 
138                                                        <div> 
139                                                            <button id="clearAllButton" type="button" class="-Button -Button--typeLinkSecondary">${translationsUtils.getMessage(locale,'vta.webcontent.clearAll')}</button> 
140                                                        </div> 
141                                                    </div> 
142                                                </div> 
143                                            </div> 
144                                            <div class="-Panel-body"> 
145                                                <div class="-stackLayout" data-space="03"> 
146                                                    <div></div> 
147                                                    <div class="-stackLayout" data-space="3" data-space-xsmd="0"> 
148 
149 
150                                                        <#-- tour type --> 
151                                                        <#if getAllUniqueArray(filter_tourType)?size gt 1> 
152                                                        <div class="-stackLayout" data-space="01"> 
153                                                            <div class="-stackLayout" data-space="04"> 
154                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.common.labels.tourType')}</strong> 
155                                                                <hr class="-Hr"> 
156                                                            </div> 
157                                                            <@printFilterCheckBoxes filter_tourType "ttype"/> 
158                                                        </div> 
159                                                        </#if> 
160 
161                                                        <#-- months --> 
162                                                        <#if filter_month?size gt 0> 
163                                                        <div class="-stackLayout" data-space="01"> 
164                                                            <div class="-stackLayout" data-space="04"> 
165                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.departureMonth')}</strong> 
166                                                                <hr class="-Hr"> 
167                                                            </div> 
168 
169                                                            <div class="-stackLayout" data-space="01"> 
170 
171                                                                <div class="-stackLayout" data-space="03"> 
172                                                                    <strong>20${curYearYY}</strong> 
173                                                                    <div> 
174                                                                        <@printFilterDates filter_month "${curYearYY}"/> 
175                                                                    </div> 
176                                                                </div> 
177 
178                                                                <div class="-stackLayout" data-space="03"> 
179                                                                    <strong>20${curYearYY+1}</strong> 
180                                                                    <div> 
181                                                                        <@printFilterDates filter_month "${curYearYY+1}"/> 
182                                                                    </div> 
183                                                                </div> 
184 
185                                                            </div> 
186                                                        </div> 
187                                                        </#if> 
188 
189                                                        <#-- ex starting points --> 
190                                                        <#if filter_estartingpoint?size gt 0> 
191                                                        <div class="-stackLayout" data-space="01"> 
192                                                            <div class="-stackLayout" data-space="04"> 
193                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.starting.point')}</strong> 
194                                                                <hr class="-Hr"> 
195                                                            </div> 
196                                                            <@printFilterCheckBoxes filter_estartingpoint "estartingp"/> 
197                                                        </div> 
198                                                        </#if> 
199 
200                                                        <#-- ex duration --> 
201                                                        <#if filter_eduration?size gt 0> 
202                                                        <div class="-stackLayout" data-space="01"> 
203                                                            <div class="-stackLayout" data-space="04"> 
204                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.duration')}</strong> 
205                                                                <hr class="-Hr"> 
206                                                            </div> 
207                                                            <@printFilterCheckBoxes filter_eduration "eduration"/> 
208                                                        </div> 
209                                                        </#if> 
210 
211 
212                                                        <#-- prices --> 
213                                                        <#if filter_price_from?size gt 0> 
214                                                        <div class="-stackLayout" data-space="01" style="${(isRangePrintable(filter_price_from))?then('','display:none;')}"> 
215                                                            <div class="-stackLayout" data-space="04"> 
216                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp"> 
217                                                                    ${translationsUtils.getMessage(locale,'vta.webcontent.pricePerPerson')} 
218                                                                </strong> 
219                                                                <hr class="-Hr"> 
220                                                            </div> 
221                                                            <div id="rangePrices" class="-Range -stackLayout js-frange" data-space="01"> 
222                                                                <@printRangeCombo filter_price_from currency "Prices"/> 
223                                                            </div> 
224                                                        </div> 
225                                                        </#if> 
226 
227                                                        <#-- destinations --> 
228                                                        <#if filter_destination?size gt 0> 
229                                                        <div class="-stackLayout" data-space="01"> 
230                                                            <div class="-stackLayout" data-space="04"> 
231                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.destinations')}</strong> 
232                                                                <hr class="-Hr"> 
233                                                            </div> 
234 
235                                                            <div class="-CollapseGroup -stackLayout" data-space="03"> 
236                                                                <#-- country --> 
237                                                                <div> 
238                                                                    <div class="-Collapse -Collapse--typeChevron"> 
239                                                                        <div class="-Collapse-contents"> 
240                                                                            <div class="-Collapse-content"> 
241                                                                                <div class="-Collapse-head" id="destCollapseHead1"> 
242                                                                                    <a class="-Collapse-toggle" data-toggle="collapse" href="#destCollapseItem1" role="button" aria-expanded="true" aria-controls="destCollapseItem1"> 
243                                                                                        <strong class="-Collapse-toggleContents"> 
244                                                                                            <span class="-Collapse-toggleContent">${translationsUtils.getMessage(locale,'vta.common.labels.country')}</span> 
245                                                                                            <span class="-Collapse-toggleIndicator"></span> 
246                                                                                        </strong> 
247                                                                                    </a> 
248                                                                                </div> 
249                                                                                <div id="destCollapseItem1" class="-Collapse-collapse collapse show" aria-labelledby="destCollapseHead1"> 
250                                                                                    <div class="-Collapse-body"> 
251                                                                                        <@printFilterCheckBoxes filter_destinationCountry "tcountry"/> 
252                                                                                    </div> 
253                                                                                </div> 
254                                                                            </div> 
255                                                                        </div> 
256                                                                    </div> 
257                                                                </div> 
258 
259                                                                <#-- tem destinations --> 
260                                                                <@printDestinationsFilter filter_destination "tdest"/> 
261 
262                                                            </div> 
263                                                        </div> 
264                                                        </#if> 
265 
266                                                        <#-- interest --> 
267                                                        <#if filter_interests?size gt 0> 
268                                                        <div class="-stackLayout" data-space="01"> 
269                                                            <div class="-stackLayout" data-space="04"> 
270                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.interest')}</strong> 
271                                                                <hr class="-Hr"> 
272                                                            </div> 
273                                                            <@printFilterCheckBoxes filter_interests "tinterests"/> 
274                                                        </div> 
275                                                        </#if> 
276 
277 
278                                                        <#-- days --> 
279                                                        <#if filter_duration?size gt 0> 
280                                                        <div class="-stackLayout" data-space="01" style="${(isRangePrintable(filter_duration))?then('','display:none;')}"> 
281                                                            <div class="-stackLayout" data-space="04"> 
282                                                                <strong class="-Heading -Heading--typeH5Immutable -Heading--skinSharp">${translationsUtils.getMessage(locale,'vta.webcontent.tourLength')}</strong> 
283                                                                <hr class="-Hr"> 
284                                                            </div> 
285                                                            <div id="rangeDurations" class="-Range -stackLayout js-frange" data-space="01"> 
286                                                                <@printRangeCombo filter_duration "${translationsUtils.getMessage(locale,'vta.webcontent.days')}" "Durations"/> 
287                                                            </div> 
288                                                        </div> 
289                                                        </#if> 
290 
291 
292                                                    </div> 
293                                                </div> 
294                                            </div> 
295                                            <div class="-Panel-foot -mdHidden"> 
296                                                <div class="-clusterLayout" data-align="center" data-justify="space-between" data-nowrap="true"> 
297                                                    <div> 
298                                                        <div> 
299                                                            <button type="button" data-toggle="collapse" data-target="#collapseFilters" aria-expanded="false" aria-controls="collapseFilters" class="-Button -Button--sizeMediumLarge -Button--typePrimary"> 
300                                                                ${translationsUtils.getMessage(locale,'vta.common.labels.apply')}</button> 
301                                                        </div> 
302                                                        <div> 
303                                                            <button type="button" data-toggle="collapse" data-target="#collapseFilters" aria-expanded="false" aria-controls="collapseFilters" class="-Button -Button--sizeMediumLarge -Button--typeLinkSecondary"> 
304                                                                ${translationsUtils.getMessage(locale,'vta.common.labels.cancel')}</button> 
305                                                        </div> 
306                                                    </div> 
307                                                </div> 
308                                            </div> 
309                                        </div> 
310                                    </div> 
311                                </div> 
312                            </div> 
313                        </div> 
314                    </div> 
315                </div> 
316 
317                <#-- list col --> 
318                <div> 
319                    <div class="-stackLayout" data-space="05"> 
320                        <div class="-clusterLayout" data-space="05" data-align="center" data-justify="space-between"> 
321                            <div> 
322                                <div> 
323                                    <strong class="results-line" data-results="${entries?size}"> 
324                                        <span class="js-f-results">${entries?size}</span> 
325                                        <span class="results">${translationsUtils.getMessage(locale,'vta.webcontent.results')}</span> 
326                                        <span class="result">${translationsUtils.getMessage(locale,'vta.webcontent.result')}</span> 
327                                    </strong> 
328                                </div> 
329                                <div> 
330                                    <div class="-clusterLayout" data-space="1" data-align="center" data-justify="space-between" data-nowrap="true"> 
331                                        <div> 
332 
333                                            <#if showFilerPanel> 
334                                                <div> 
335                                                    <button type="button" class="-Button -Button--typeBare -mdHidden" id="collapseFiltersToggle" data-toggle="collapse" data-target="#collapseFilters" aria-expanded="false" aria-controls="collapseFilters"> 
336                                                        <span class="-clusterLayout" data-space="02" data-align="center" data-nowrap="true"> 
337                                                            <span> 
338                                                                <i class="-Icon -Icon--filter"></i><span> ${translationsUtils.getMessage(locale,'vta.webcontent.filters')} </span> 
339                                                            </span> 
340                                                        </span> 
341                                                    </button> 
342                                                </div> 
343                                            </#if> 
344 
345                                            <div> 
346                                                <div class="-Collapse -Collapse--typeDropdown -Collapse--dropdownJustifyEnd"> 
347                                                    <div class="-Collapse-contents"> 
348                                                        <div class="-Collapse-content"> 
349                                                            <div class="-Collapse-head"> 
350                                                                <button id="collapseSortToggle" type="button" class="-Button -Button--typeBare collapsed" data-toggle="collapse" data-target="#collapseSort" aria-expanded="false" aria-controls="collapseSort" data-collapse-dropdown="true"> 
351                                                                    <span class="-clusterLayout" data-space="02" data-align="center" data-nowrap="true"> 
352                                                                        <span> 
353                                                                            <i class="-Icon -Icon--sort"></i><span> ${translationsUtils.getMessage(locale,'vta.webcontent.sortBy')} </span> 
354                                                                        </span> 
355                                                                    </span> 
356                                                                </button> 
357                                                            </div> 
358                                                            <div id="collapseSort" class="-Collapse-collapse collapse" aria-labelledby="collapseSortToggle" data-dropdown-justify="end" style=""> 
359                                                                <div class="-Panel -Panel--typeFlyout -Collapse-panel -Collapse-panel--typeFlyout"> 
360                                                                    <div class="-Panel-inner"> 
361                                                                        <div class="-Panel-body -formElements"> 
362                                                                            <div class="-stackLayout js-sset" data-space="02"> 
363 
364                                                                            <#assign sortListArray = [ 
365                                                                                {"id":"Recommended", "datasort":"${sortString}", "value":"Recommended", "checked":true, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.recommended')}"}, 
366                                                                                {"id":"PriceLowToHigh", "datasort":"pr_lo", "value":"Price (low to high)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.priceLowToHigh')}"}, 
367                                                                                {"id":"PriceHighToLow", "datasort":"pr_hi", "value":"Price (high to low)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.priceHighToLow')}"}, 
368                                                                                {"id":"DepartureEarliestToLatest", "datasort":"de_er", "value":"Departure (earliest to latest)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.departureEarliestToLatest')}"}, 
369                                                                                {"id":"DepartureLatestToEarliest", "datasort":"de_lt", "value":"Departure (latest to earliest)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.departureLatestToEarliest')}"}, 
370                                                                                {"id":"DurationShortest", "datasort":"du_sh", "value":"Duration (shortest)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.durationShortest')}"}, 
371                                                                                {"id":"DurationLongest", "datasort":"du_ln", "value":"Duration (longest)", "checked":false, "label":"${translationsUtils.getMessage(locale,'vta.webcontent.durationLongest')}"} 
372                                                                            ]> 
373                                                                            <#list sortListArray as item> 
374                                                                                <div class="-CustomControl -CustomControl--typeCheckMark js-sitem --focus-w"> 
375                                                                                    <div class="custom-control custom-radio"> 
376                                                                                        <label> 
377                                                                                            <input name="sortBy" data-sort="${item.datasort}" id="${item.id}" type="radio" class="-CustomControlInput custom-control-input js-sitem-input" 
378                                                                                                role="radio" value="${item.value}" ${item.checked?then('checked=""','')}> 
379                                                                                            <span class="custom-control-label"> 
380                                                                                                <span class="custom-control-label-text">${item.label}</span> 
381                                                                                            </span> 
382                                                                                        </label> 
383                                                                                    </div> 
384                                                                                </div> 
385                                                                            </#list> 
386 
387                                                                            </div> 
388                                                                        </div> 
389                                                                    </div> 
390                                                                </div> 
391                                                            </div> 
392                                                        </div> 
393                                                    </div> 
394                                                </div> 
395                                            </div> 
396 
397                                        </div> 
398                                    </div> 
399                                </div> 
400                            </div> 
401                        </div> 
402 
403                        <div id="${thisFilterScope}-list" class="-stackLayout js-f-col-list" data-space="1"> 
404                            <#if entries?has_content> 
405                                <#list entries as curEntry> 
406                                    <@printCard curEntry curEntry?index/> 
407                                </#list> 
408                            </#if> 
409                             
410                            <#-- ********* don't remove - using for service prints --> 
411                            <#-- tourtype: ${filter_tourType?size} --> 
412                            <#-- month: ${filter_month?size} --> 
413                            <#-- destinations: ${filter_destination?size} --> 
414                            <#-- price: ${filter_price_from?size} --> 
415                            <#-- country: ${filter_destinationCountry?size} --> 
416                            <#-- interest: ${filter_interests?size} --> 
417                            <#-- duration: ${filter_duration?size} --> 
418                            <#-- recomended: ${filter_recommended?size} --> 
419                            <#-- ex starting point: ${filter_estartingpoint?size} --> 
420                            <#-- ex duration: ${filter_eduration?size} --> 
421 
422                            <#-- loader --> 
423                            <#--  <div class="-LoaderContainer -LoaderContainer--variantSpinner -LoaderContainer--sizeMedium" data-state="active"></div>  --> 
424                             
425                            <div id="banner" style="display:none;"> 
426                            <#-- marketingBanner_${themeDisplay.getSiteGroupId()} --> 
427                            <#assign thisPrefs = freeMarkerPortletPreferences.getPreferences("portletSetupPortletDecoratorId", "barebone") /> 
428                            <@liferay_portlet["runtime"] 
429                                defaultPreferences="${thisPrefs}" 
430                                portletProviderAction=portletProviderAction.VIEW 
431                                instanceId="marketingBanner_${themeDisplay.getSiteGroupId()}" 
432                                portletName="com_liferay_journal_content_web_portlet_JournalContentPortlet" 
433                                /> 
434                            </div> 
435 
436                            <div id="zeroBanner" class="hidden"> 
437                            <#-- zeroBanner_${themeDisplay.getSiteGroupId()} --> 
438                            <#assign thisPrefs = freeMarkerPortletPreferences.getPreferences("portletSetupPortletDecoratorId", "barebone") /> 
439                            <@liferay_portlet["runtime"] 
440                                defaultPreferences="${thisPrefs}" 
441                                portletProviderAction=portletProviderAction.VIEW 
442                                instanceId="zeroBanner_${themeDisplay.getSiteGroupId()}" 
443                                portletName="com_liferay_journal_content_web_portlet_JournalContentPortlet" 
444                                /> 
445                            </div>  
446 
447                        </div> 
448 
449                    </div> 
450                </div> 
451 
452 
453            </div> 
454        </div> 
455         
456        </#compress> 
457        <@scripts/> 
458    </#local> 
459    <#-- /HTML cachable data -->  
460 
461<#return htmlData> 
462</#function> 
463 
464 
465<#-- ************************************** --> 
466 
467<#-- get last modification date by structure type --> 
468<#function getModDateForArticle article> 
469    <#local ret = "00000"> 
470    <#if article.DDMStructureId?string = structureGuidedTourId?string> 
471        <#-- get GuidedTour last modification datetime from BE --> 
472        <#if !guidedToursModDatesMap??> 
473            <#local guidedToursModDatesMap = guidedUtil.getLastModifiedMap(request)> 
474        </#if> 
475        <#if guidedToursModDatesMap[article.articleId]??> 
476            <#local ret = guidedToursModDatesMap[article.articleId]> 
477        <#else> 
478            <#-- no data on BE --> 
479            <#local ret = article.modifiedDate?datetime?string> 
480        </#if> 
481    <#else> 
482        <#-- all tours except GuidedTours --> 
483        <#local ret = article.modifiedDate?datetime?string> 
484    </#if> 
485    <#return ret> 
486</#function> 
487 
488 
489<#-- generate data and update/create cache --> 
490<#macro generateCardData curEntry index> 
491    <#local renderer=curEntry.getAssetRenderer() /> 
492    <#local cur_journalArticle=renderer.getArticle() /> 
493    <#local cur_journalArticle_Uuid = cur_journalArticle.uuid?string> 
494    <#local cur_journalArticle_ModDate = getModDateForArticle(cur_journalArticle)> 
495    <!-- articleID: ${cur_journalArticle.getArticleId()} --> 
496    <#local card_id = "${randomNamespace}tc_${index}"> 
497    <#-- cache logic --> 
498        <#if freemarkerFilterCache??> 
499            <#local thisCacheItem = freemarkerFilterCache.getArticleItem(cur_journalArticle_Uuid + cacheSufix)!"null"><#-- read cache date modification date --> 
500 
501            <#if thisCacheItem = "null"> 
502                <#local cur_cacheMessage = "No cache record ...created"> 
503                <#local thisCardData = renderCardData(cur_journalArticle)> 
504            <#elseif cur_journalArticle_ModDate == thisCacheItem.changeDate> 
505                <#local thisCardData = thisCacheItem.content!"null"><#-- read cache data --> 
506                <#if thisCardData != "null"> 
507                    <#--  <#local cur_cacheMessage = "HIT actual">  --> 
508                <#else> 
509                    <#local cur_cacheMessage = "HIT - record empty ...created"> 
510                    <#local thisCardData = renderCardData(cur_journalArticle)> 
511                </#if> 
512            <#else> 
513                <#local cur_cacheMessage = "HIT modified: ${thisCacheItem.changeDate} : ${cur_journalArticle_ModDate}<br>...updated"> 
514                <#local thisCardData = renderCardData(cur_journalArticle)> 
515            </#if> 
516        <#else> 
517            <#local thisCardData = renderCardData(cur_journalArticle)> 
518            <#local cur_cacheMessage = "Cache not installed"> 
519        </#if> 
520    <#-- end cache logic --> 
521 
522    <#local  thisCode = thisCardData> 
523    <#assign data_map = thisCode?split("<-DATA-SPLIT->")> 
524 
525    <#if !thisCode?contains("journal-template-error") && data_map?size gt 1> 
526        <#local currnetDataArray = data_map[1]?eval> 
527        <#local dataString> 
528            <@collectData currnetDataArray card_id/> 
529        </#local> 
530        <#list currnetDataArray as cur_dataArry> 
531            <#local thisJsStringRecord = '{ "id":"${card_id}","inRanges":true,"inScope":true,"sort-date":"",${collectJsString(cur_dataArry)}}'> 
532            <#assign data_set = data_set + [thisJsStringRecord]> 
533        </#list> 
534    </#if> 
535    <#if cur_cacheMessage??> 
536        <#-- cache: ${cur_cacheMessage} --> 
537        <script>console.log("cache: ${card_id} ${cur_journalArticle.getTitle(locale)}, (${cur_journalArticle_ModDate}) : ${cur_cacheMessage}");</script> 
538    </#if> 
539</#macro> 
540 
541 
542 
543<#-- print a tour card from cache ONLY--> 
544<#macro printCard curEntry index> 
545    <#local renderer=curEntry.getAssetRenderer() /> 
546    <#local cur_journalArticle=renderer.getArticle() /> 
547    <#local cur_journalArticle_Uuid = cur_journalArticle.uuid?string> 
548    <#local cur_journalArticle_ModDate = getModDateForArticle(cur_journalArticle)>    
549    <#local card_id = "${randomNamespace}tc_${index}"> 
550 
551    <#-- cache logic --> 
552        <#if freemarkerFilterCache??> 
553            <#local thisCacheItem = freemarkerFilterCache.getArticleItem(cur_journalArticle_Uuid + cacheSufix)!"null"><#-- read cache date modification date --> 
554 
555            <#if thisCacheItem = "null"> 
556                <#local cur_cacheMessage = "No cache record ...created"> 
557            <#elseif cur_journalArticle_ModDate == thisCacheItem.changeDate> 
558                <#local thisCardData = thisCacheItem.content!"null"><#-- read cache data --> 
559                <#if thisCardData != "null"> 
560                    <#--  <#local cur_cacheMessage = "HIT actual">  --> 
561                <#else> 
562                    <#local cur_cacheMessage = "HIT - record empty ERRRRRRRR!"> 
563                </#if> 
564            <#else> 
565                <#local cur_cacheMessage = "HIT modified: ${thisCacheItem.changeDate} : ${cur_journalArticle_ModDate}<br>...ERRRRRRRRRR!"> 
566            </#if> 
567        <#else> 
568            <#local cur_cacheMessage = "Cache not installed"> 
569        </#if> 
570    <#-- end cache logic --> 
571 
572    <#if thisCardData?contains("journal-template-error")> 
573        <div id="${card_id}" class="d-tour" > 
574            <div style="background-color:black; color:white; padding:1em;"> 
575                <h2>*** card error ***</h2> 
576                <h4>${cur_journalArticle.getTitle()}</h4> 
577                <a href="${urlHelper}/w/${cur_journalArticle.getUrlTitle()}" target="_blank">OPEN TOUR</a> 
578                <!-- ${cur_journalArticle} --> 
579            </div> 
580            <!-- ${thisCardData} --> 
581        </div> 
582    <#elseif thisCardData?contains("PAST TOUR")> 
583        <!-- PAST TOUR: ${cur_journalArticle.getTitle()} --> 
584        <#--  <div id="${card_id}" class="d-tour" > 
585            <div style="background-color:lightskyblue; color:white; padding:1em;"> 
586                <h2>*** PAST TOUR ***</h2> 
587                <h4>${cur_journalArticle.getTitle()}</h4> 
588                <a href="${urlHelper}/w/${cur_journalArticle.getUrlTitle()}" target="_blank">OPEN TOUR</a> 
589            </div> 
590        </div>  --> 
591    <#elseif !thisCardData?contains("<-DATA-SPLIT->")> 
592        <div id="${card_id}" class="d-tour" > 
593            <div style="background-color:black; color:white; padding:1em;"> 
594                <h2>*** wrong template or webcontent ***</h2> 
595                <h4>${cur_journalArticle.getTitle()}</h4> 
596                <!-- ${cur_journalArticle} --> 
597            </div> 
598        </div> 
599    <#else> 
600        <#local data_map = thisCardData?split("<-DATA-SPLIT->")> 
601        <#--  <p style="font-size: 0.6em;">${thisJsStringRecord?replace(":",": ")?replace(",",", ")} </p>  --> 
602        <div id="${card_id}" class="d-tour js-f-tour-card hidden"><#--${(index gte 2)?then('hidden','')}--> 
603            <#if cur_cacheMessage??> 
604                <script>console.log("*cache: ${card_id} ${cur_journalArticle.getTitle(locale)} : ${cur_cacheMessage}");</script> 
605            </#if> 
606            <#--  style="font-size: 0.6em;">${thisJsStringRecord?replace(":",": ")?replace(",",", ")} --> 
607            <#--  ${thisCardData}  --> 
608            ${data_map[0]}${data_map[3]} 
609        </div> 
610         
611 
612 
613    </#if> 
614</#macro> 
615 
616<#-- render CARD data and write to cache --> 
617<#function renderCardData cur_journalArticle> 
618    <#local thisEntryData> 
619        <@liferay_journal["journal-article"] 
620            articleId=cur_journalArticle.getArticleId() 
621            ddmTemplateKey="${embedTourCardUniId}" 
622            groupId=cur_journalArticle.getGroupId() 
623        /> 
624    </#local> 
625    <#local thisEntryId = cur_journalArticle.uuid?string + cacheSufix> 
626    <#local thisEntryDate = getModDateForArticle(cur_journalArticle)> 
627    <#if freemarkerFilterCache??> 
628        <#local writeMe = freemarkerFilterCache.putArticleItem(thisEntryId, thisEntryDate, thisEntryData)><#-- update cache --> 
629    </#if> 
630    <#return thisEntryData> 
631</#function> 
632 
633<#function collectJsString hash> 
634    <#local retString = ""> 
635    <#list hash as key,val> 
636        <#local retString = retString + '"${key}": ' + (val?is_number)?then('${val}','"${val}"') + (key?is_last)?then('',', ')> 
637    </#list> 
638    <#return retString> 
639</#function> 
640 
641 
642<#-- data collect --> 
643<#macro collectData hashArry id> 
644    <#list hashArry as cur_hash> 
645        <#list cur_hash as key,val> 
646            <#if val?string=""> 
647                <#continue><#-- skip empty val --> 
648            </#if> 
649            ${key}="${val}" 
650            <#if val?contains(",")> 
651                <#assign value = val?split(",")> 
652            <#else> 
653                <#assign value = [val]> 
654            </#if> 
655            <#if key = "data-ttype"> 
656                <#assign filter_tourType = filter_tourType + value/> 
657            <#elseif key = "data-tmonth"> 
658                <#assign filter_month = filter_month + value/> 
659            <#elseif key = "data-tdest"> 
660                <#assign filter_destination = filter_destination + value/> 
661            <#elseif key = "data-tprice"> 
662                <#assign filter_price_from = filter_price_from + value/> 
663            <#elseif key = "data-tcountry"> 
664                <#assign filter_destinationCountry = filter_destinationCountry + value/> 
665            <#elseif key = "data-tinterests"> 
666                <#assign filter_interests = filter_interests + value/> 
667            <#elseif key = "data-tlength"> 
668                <#assign filter_duration = filter_duration + value/> 
669            <#elseif key = "data-trec" && val?string != ""> 
670                <#assign filter_recommended = filter_recommended + value/> 
671            <#elseif key = "data-estartingp" && val != ""> 
672                <#assign filter_estartingpoint = filter_estartingpoint + value/> 
673            <#elseif key = "data-eduration"> 
674                <#assign filter_eduration = filter_eduration + value/> 
675            </#if> 
676        </#list> 
677    </#list> 
678</#macro> 
679 
680<#-- print a range inside combo --> 
681<#macro printRangeCombo array units name> 
682    <#local cur_array = []> 
683    <#if array?size != 0> 
684        <#list array as item> 
685            <#attempt> 
686                <#-- try --> 
687                <#local cur_array = cur_array + [item?number]> 
688            <#recover> 
689                <#-- catch --> 
690                <!-- item is not a number! --> 
691                <!-- array: ${array?join(", ")} --> 
692                <!-- item: ${item} --> 
693                <#local cur_array = [0,1]> 
694                <#break> 
695            </#attempt> 
696        </#list> 
697 
698        <#local cur_min = cur_array?min> 
699        <#local cur_max = cur_array?max> 
700        <#local cur_step = "1"> 
701        <div class="-Range-Value"> 
702            <span class="-Range-fromValue" data-from-value="">${cur_min}</span> 
703            <span class="-Range-fromValueSuffix">${units}</span> 
704            <span class="-Range-valueSeparator">-</span> 
705            <span class="-Range-toValue" data-to-value="">${cur_max}</span> 
706            <span class="-Range-toValueSuffix">${units}</span> 
707        </div> 
708        <div class="-Range-control"> 
709            <input type="range" id="from${name}" name="from${name}" data-from=""  
710                value="${cur_min}" min="${cur_min}" max="${cur_max}" step="${cur_step}" aria-label="from${name}"> 
711            <input type="range" id="to${name}" name="to${name}" data-to=""  
712                value="${cur_max}" min="${cur_min}" max="${cur_max}" step="${cur_step}" aria-label="to${name}" 
713                style="background: linear-gradient(to right, 
714                var(--_range-control-secondary-color) 0%, 
715                var(--_range-control-secondary-color) 20%, 
716                var(--_range-control-primary-color) 20%, 
717                var(--_range-control-primary-color) 66.66666666666666%, 
718                var(--_range-control-secondary-color) 66.66666666666666%, 
719                var(--_range-control-secondary-color) 100%); z-index: 0;"> 
720        </div> 
721    </#if> 
722 
723</#macro> 
724 
725<#function isRangePrintable array> 
726    <#local cur_array = []> 
727    <#if array?size != 0> 
728        <#list array as item> 
729            <#attempt> 
730                <#-- try --> 
731                <#local cur_array = cur_array + [item?number]> 
732            <#recover> 
733                <#local cur_array = [0,1]> 
734                <#break> 
735            </#attempt> 
736        </#list> 
737        <#if cur_array?min != cur_array?max> 
738            <#return true> 
739        </#if> 
740    </#if> 
741    <#return false> 
742</#function> 
743 
744 
745<#macro printDestinationsFilter array type> 
746    <#-- get array of destinations with types --> 
747    <#local otherTypeName = translationsUtils.getMessage(locale,'vta.webcontent.other')> 
748    <#local popularTypeName = "popular"><#-- default value if no popular tour... --> 
749    <#local existPopulars = false> 
750    <#local existOthers = false> 
751    <#local destArray = []> 
752    <!-- DEST : ${array?size} --> 
753    <!-- DEST : ${array?join(", ")} --> 
754     
755    <#local allUniqueDestIds = getAllUniqueArray(array)> 
756    <!-- UNIQ : ${allUniqueDestIds?size} --> 
757    <!-- UNIQ : ${allUniqueDestIds?join(", ")} --> 
758    <#list allUniqueDestIds as item> 
759        <#local popular = readByClassPkAndVocIdWcCatName(item vocPopularityId "None")><#-- return name or "error" for missing classPk --> 
760        <#if popular != "None" && popular != "error" > 
761            <#local typeName = popular> 
762            <#local popularTypeName = popular> 
763            <#local existPopulars = true> 
764        <#else> 
765            <#local typeName = readByClassPkAndVocIdWcCatName(item vocDestTypenId "${otherTypeName}")> 
766            <#local existOthers = true> 
767        </#if> 
768 
769        <#local destArray = destArray + [{ "typeName":typeName, "destId":item }]> 
770    </#list> 
771 
772    <#-- get array of unique types (labels of sections)--> 
773    <#local allUniqueTypes = []> 
774    <#if existPopulars><#-- add populars at start --> 
775        <#local allUniqueTypes = allUniqueTypes + [popularTypeName]> 
776    </#if> 
777    <#list destArray?sort_by("typeName") as item> 
778        <#if !(allUniqueTypes?seq_contains(item.typeName)) && item.typeName != popularTypeName && item.typeName != otherTypeName> 
779            <#local allUniqueTypes = allUniqueTypes + [item.typeName]> 
780        </#if> 
781    </#list> 
782    <#if existOthers><#-- add populars at end --> 
783        <#local allUniqueTypes = allUniqueTypes + [otherTypeName]> 
784    </#if> 
785     
786    <#-- iterate each type sets --> 
787    <#list allUniqueTypes as cur_item> 
788        <#-- types: ${cur_item} - ${popularTypeName} --> 
789        <#local filteredDestNames = destArray?filter(item -> item.typeName == cur_item)?map(item -> item.destId)> 
790        <#local collapseName = cur_item?replace("[^0-9a-zA-Z_]", "_", "r")> 
791        <#local openDropDown = (cur_item == popularTypeName)> 
792        <div> 
793            <div class="-Collapse -Collapse--typeChevron"> 
794                <div class="-Collapse-contents"> 
795                    <div class="-Collapse-content"> 
796                        <div class="-Collapse-head" id="${collapseName}Head"> 
797                            <a class="-Collapse-toggle" data-toggle="collapse" role="button" aria-expanded="${openDropDown?c}" 
798                                href="#${collapseName}Item" aria-controls="${collapseName}Item"> 
799                                <strong class="-Collapse-toggleContents"> 
800                                    <span class="-Collapse-toggleContent">${cur_item}</span> 
801                                    <span class="-Collapse-toggleIndicator"></span> 
802                                </strong> 
803                            </a> 
804                        </div> 
805                        <div id="${collapseName}Item" class="-Collapse-collapse collapse ${openDropDown?then('show','')}" aria-labelledby="${collapseName}Head"> 
806                            <div class="-Collapse-body"> 
807                             
808                            <@printFilterCheckBoxes filteredDestNames type/> 
809 
810                            </div> 
811                        </div> 
812                    </div> 
813                </div> 
814            </div> 
815        </div> 
816 
817    </#list> 
818     
819 
820</#macro> 
821 
822 
823<#function getAllUniqueArray array> 
824    <#-- create array of unique items from array --> 
825    <#local allUniqueItems = []> 
826    <#list array as item> 
827        <#if !(allUniqueItems?seq_contains(item))> 
828            <#local allUniqueItems = allUniqueItems + [item]> 
829        </#if> 
830    </#list> 
831 
832    <#return allUniqueItems> 
833</#function> 
834 
835 
836 
837<#-- filtr checkboxes --> 
838<#macro printFilterCheckBoxes array type> 
839 
840    <#local allUniqueItems = getAllUniqueArray(array)> 
841    <#local printArray = []> 
842    <#list allUniqueItems?sort as item> 
843        <#local screen_name = item> 
844        <#if item?string = ""> 
845            <#continue> 
846        <#elseif type = "tdest"> 
847            <#local screen_name = readByClassPkWebContentField(item,"ScreenName")> 
848        <#elseif type = "ttype"> 
849            <#local langKey = vtaLibrary.getTemplateForStructure(screen_name,"lang")> 
850            <#local screen_name = translationsUtils.getMessage(locale,langKey)> 
851        <#elseif type = "tinterests" || type = "estartingp"> 
852            <#local screen_name = assetCategoryService.fetchCategory(screen_name?number).getTitle(locale)> 
853        <#elseif type = "tcountry" && screen_name != "No country"> 
854            <#local screen_name = assetCategoryService.fetchCategory(screen_name?number).getTitle(locale)> 
855        <#elseif type = "eduration"> 
856            <#switch item?string> 
857            <#case "0"> 
858                <#local screen_name = translationsUtils.getMessage(locale,'vta.webcontent.short.up.2.hrs')> 
859                <#break> 
860            <#case "1"> 
861                <#local screen_name = translationsUtils.getMessage(locale,'vta.webcontent.medium')> 
862                <#break> 
863            <#case "2"> 
864                <#local screen_name = translationsUtils.getMessage(locale,'vta.webcontent.long.8plus.hrs')> 
865                <#break> 
866            <#default> 
867                <#local screen_name = "Unknown"> 
868            </#switch> 
869        </#if> 
870        <#local count = array?filter(it -> it == item)?size > 
871        <#local printArray = printArray + [{"screenName":screen_name, "item":item, "count":count}]> 
872    <#-- ${item}, ${screen_name}, ${count} --> 
873    </#list> 
874 
875    <div class="-stackLayout js-fset" data-ftype="${type}" data-space="04"> 
876        <#list printArray?sort_by("screenName") as item> 
877            <@printFilterCheckboxItem item.item item.screenName item.count type/> 
878        </#list> 
879    </div> 
880</#macro> 
881 
882        <#-- print one checkbox --> 
883        <#macro printFilterCheckboxItem item screen_name count type> 
884            <div class="custom-control custom-checkbox js-fitem"> 
885                <label> 
886                    <input type="checkbox" 
887                        class="-CustomControlInput custom-control-input js-fitem-input" 
888                        data-fname="${item}" 
889                        role="checkbox" value="${screen_name}"> 
890                    <span class="custom-control-label"> 
891                        <span class="custom-control-label-text filter-item">${screen_name}&nbsp;(<span class="-colorSecondaryPale js-fitem-count">${count}</span>)</span> <#-- &nbsp; to prevent orphan a number in the responsive design --> 
892                    </span> 
893                </label> 
894            </div> 
895        </#macro> 
896 
897 
898<#-- month list --> 
899<#macro printFilterDates array year> 
900    <div class="-gridLayout js-fset" data-fragment="1of4" data-space="02" data-overflowvisible="true" data-ftype="tmonth"> 
901        <div> 
902            <#-- ${array?sort?join(", ")} --> 
903            <#list 1..12 as cur_month> 
904            <#local cur_fname = year + "-" + cur_month?left_pad(2, "00")> 
905            <#local cur_is_enabled = array?seq_contains(cur_fname)> 
906            <#if year?number == curYearYY?number && cur_month?number lt curMonthMM?number><#--disable past months--> 
907                <#local cur_is_enabled = false> 
908            </#if> 
909            <#-- *${cur_fname}* --> 
910            <#local cur_temp_date = dateUtil.parseDate("yyyy-MM-dd", "1999-" + cur_month?left_pad(2, "00") + "-01", locale)><#-- fake date 1999-MM-01 --> 
911            <#local cur_month_string = dateUtil.getDate(cur_temp_date, "MMM", locale)> 
912                <div> 
913                    <div class="-CustomControl -CustomControl--typeButton"> 
914                        <div class="custom-control custom-checkbox ${cur_is_enabled?then('js-fitem','')}"> 
915                            <label> 
916                                <input name="departureMonth" 
917                                    type="checkbox" 
918                                    class="-CustomControlInput custom-control-input ${cur_is_enabled?then('js-fitem-input','')}" 
919                                    role="checkbox" value="${cur_month_string}" 
920                                    ${cur_is_enabled?then('data-fname="${cur_fname}"','')} 
921                                    ${cur_is_enabled?then("","disabled")}> 
922                                <span class="custom-control-label"> 
923                                    <span class="custom-control-label-text">${cur_month_string}</span> 
924                                </span> 
925                            </label> 
926                        </div> 
927                    </div> 
928                </div> 
929            </#list> 
930        </div> 
931    </div> 
932</#macro> 
933 
934<#-- read a filed form webcontent --> 
935<#function readByClassPkWebContentField classPK fieldReference> 
936    <#local ret = "*****"> 
937    <#if classPK !=""> 
938        <#local journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService")> 
939        <#local journalArticle = journalArticleLocalService.fetchLatestArticle(classPK?number)> 
940        <#local docXML = saxReaderUtil.read(journalArticle.getDocument().asXML())> 
941        <#local ret = docXML.selectSingleNode("/root/dynamic-element[@field-reference='${fieldReference}']/dynamic-content").getData()> 
942        <#assign counter = counter + 1> 
943    </#if> 
944    <#return ret> 
945</#function> 
946 
947<#-- read a category name form webcontent by classPK a vocabularyId--> 
948<#function readByClassPkAndVocIdWcCatName classPK vocabularyId noCategorySetReturnString> 
949    <#local ret = "error"> 
950    <#if classPK !=""> 
951        <#local assetCategoryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetCategoryLocalService") /> 
952        <#local categoryList=assetCategoryLocalService.getCategories("com.liferay.journal.model.JournalArticle",classPK?number) > 
953         
954        <#-- this category is NOT multioptional (if yes only first item will be returned --> 
955        <#local name = noCategorySetReturnString> 
956        <#list categoryList as category> 
957            <#if category.vocabularyId = vocabularyId> 
958                <#local name = category.getTitle(locale)> 
959            </#if> 
960        </#list> 
961 
962        <#local ret = name > 
963    </#if> 
964    <#return ret> 
965</#function> 
966 
967<#macro scripts> 
968    <#-- min/max price and length --> 
969    <#assign priceArray = []> 
970    <#list filter_price_from as item> 
971        <#if item?string != ""> 
972        <#assign priceArray = priceArray + [item?number]> 
973        </#if> 
974    </#list> 
975    <#if priceArray?size = 0> 
976        <#assign priceArray = [0,1]> 
977    </#if> 
978 
979 
980    <#assign durationArray = []> 
981    <#list filter_duration as item> 
982        <#if item?string != ""> 
983        <#assign durationArray = durationArray + [item?number]> 
984        </#if> 
985    </#list> 
986    <#if durationArray?size = 0> 
987        <#assign durationArray = [0,1]> 
988    </#if> 
989    <script> 
990 
991        ;AUI().ready(function() { 
992            // All data source 
993            var filterDataArray = [ 
994                <#list data_set as item> 
995                    ${item}<#sep>,</#sep> 
996                </#list> 
997            ]; 
998 
999            var dataObject = { 
1000                thisOrFilters: ["ttype","tmonth"], 
1001                filterDataArray: filterDataArray, 
1002                thisFilterCol: document.getElementById("${thisFilterScope}-filter"), 
1003                thisResultsCol: document.getElementById("${thisFilterScope}-list"), 
1004                rangePricesId: "rangePrices", 
1005                rangeDurationsId: "rangeDurations", 
1006                defaultRangePriceFrom: ${priceArray?min}, 
1007                defaultRangePriceTo: ${priceArray?max}, 
1008                defaultRangeLengthFrom: ${durationArray?min}, 
1009                defaultRangeLengthTo: ${durationArray?max}, 
1010                rangePriceFrom: ${priceArray?min}, 
1011                rangePriceTo: ${priceArray?max}, 
1012                rangeLengthFrom: ${durationArray?min}, 
1013                rangeLengthTo: ${durationArray?max}, 
1014                defaultSort: "${sortString}" 
1015            }; 
1016 
1017            handleRangeComponent(".-Range"); 
1018            startFilter(dataObject); 
1019        }); 
1020 
1021    </script> 
1022 
1023    <#--  <script> // DEBUG SCRIPT 
1024         
1025            var filterDataArray = [ 
1026                <#list data_set as item> 
1027                    ${item}<#sep>,</#sep> 
1028                </#list> 
1029            ]; 
1030 
1031            var dataObject = { 
1032                thisOrFilters: ["ttype","tmonth"], 
1033                filterDataArray: filterDataArray, 
1034                thisFilterCol: document.getElementById("${thisFilterScope}-filter"), 
1035                thisResultsCol: document.getElementById("${thisFilterScope}-list"), 
1036                rangePricesId: "rangePrices", 
1037                rangeDurationsId: "rangeDurations", 
1038                defaultRangePriceFrom: ${priceArray?min}, 
1039                defaultRangePriceTo: ${priceArray?max}, 
1040                defaultRangeLengthFrom: ${durationArray?min}, 
1041                defaultRangeLengthTo: ${durationArray?max}, 
1042                rangePriceFrom: ${priceArray?min}, 
1043                rangePriceTo: ${priceArray?max}, 
1044                rangeLengthFrom: ${durationArray?min}, 
1045                rangeLengthTo: ${durationArray?max}, 
1046                defaultSort: "${sortString}" 
1047            }; 
1048 
1049            //handleRangeComponent('.-Range'); 
1050            //startFilter(dataObject); 
1051 
1052 
1053    </script>  --> 
1054 
1055 
1056 
1057    <script> 
1058 
1059        ;function startSwipers(swiperContainers) { 
1060                    // + init swipers 
1061                function setSwiper(container, index) { 
1062                    let thumbContainer = container.querySelector('.js-swiper-thumb'); 
1063                    let mainContainer = container.querySelector('.js-swiper-main'); 
1064 
1065                    if (!thumbContainer.swiper) { 
1066                        var swiperThumb = new Swiper(thumbContainer, { 
1067                            spaceBetween: 2, 
1068                            speed: 500, 
1069                            grabCursor: true, 
1070                            keyboard: { 
1071                                enabled: true, 
1072                            }, 
1073                            slidesPerView: 3, 
1074                            freeMode: { 
1075                                enabled: true, 
1076                                sticky: true, 
1077                            }, 
1078                            watchSlidesProgress: false, 
1079                        }); 
1080                     
1081                        var swiperMain = new Swiper(mainContainer, { 
1082                            spaceBetween: 2, 
1083                            speed: 500, 
1084                            grabCursor: true, 
1085                            keyboard: { 
1086                                enabled: true, 
1087                            }, 
1088                            navigation: { 
1089                                nextEl: thumbContainer.querySelector('.swiper-button-next'), 
1090                                prevEl: thumbContainer.querySelector('.swiper-button-prev'), 
1091                            }, 
1092                            thumbs: { 
1093                                swiper: swiperThumb, 
1094                            }, 
1095                        }); 
1096 
1097                        // Uložit instance Swiperu, pokud je třeba s nimi dále pracovat 
1098                        thumbContainer.swiperInstance = swiperThumb; 
1099                        mainContainer.swiperInstance = swiperMain; 
1100
1101                    else { 
1102                        console.log(index, "uz existuje"); 
1103
1104                }; 
1105 
1106                var observerOptions = { 
1107                                root: null, // Viewport jako kořen 
1108                                rootMargin: '0px', 
1109                                threshold: 0.1 // Spustí se, když je alespoň 10% prvku viditelné 
1110                            }; 
1111 
1112                var observer = new IntersectionObserver((entries, observer) => { 
1113                    entries.forEach(entry => { 
1114                        if (entry.isIntersecting) { 
1115                            setSwiper(entry.target); 
1116                            observer.unobserve(entry.target); // Přestat sledovat prvek po inicializaci Swiperu 
1117
1118                    }); 
1119                }, observerOptions); 
1120 
1121                swiperContainers.forEach(container => { 
1122                    observer.observe(container); // Začít sledovat každý kontejner 
1123                }); 
1124        }; 
1125 
1126        ;AUI().ready(function() { 
1127            var swContainer = document.querySelectorAll('.js-swipers-container');  
1128            startSwipers(swContainer); 
1129        }); 
1130 
1131    </script> 
1132</#macro>