Články - Tiskový servis
Při zpracování šablony došlo k chybě.
Java method "com.liferay.portal.json.JSONFactoryImpl.createJSONObject(String)" threw an exception when invoked on com.liferay.portal.json.JSONFactoryImpl object "com.liferay.portal.json.JSONFactoryImpl@1e1bb21e"; see cause exception in the Java stack trace.
----
FTL stack trace ("~" means nesting-related):
- Failed at: json = jsonFactoryUtil.createJSONObje... [in template "GLOBAL_MACROS" in function "getDocumentUrlFromJsonText" at line 706, column 13]
- Reached through: @global.printImgFromJsonText w="200" ... [in template "COMMON_MACROS" in macro "printArticlePreview" at line 2084, column 25]
- Reached through: @macros.printArticlePreview data [in template "20097#20123#10261171" at line 373, column 45]
----
1<#include "${templatesPath}/COMMON_SETUP" />
2
3<#--
4 Logika:
5 - slovnik TEMA obsahuje vsechny kategorie jako slovnik HLAVNI_TEMATICKA_OBLAST + muze obsahovat dalsi kategorie
6 - ve filtru se zobrazuji pouze kategorie ze slovniku HLAVNI_TEMATICKA_OBLAST
7 - hodnotu v url param kategorie hledame primarne ve slovniku TEMA,
8 - aby se dalo vyfiltrovat i podle kategorii, ktere nejsou ve filtru zobrazeny
9 - napr. pri prichodu z detailu clanku z boxu temata (kde je smes kategorii z obou slovniku)
10 - pokusime se najit kategorii i ve slovniku HLAVNI_TEMATICKA_OBLAST,
11 - pokud tam je:
12 - pridame jeji id od anyCategoryIds pro vyhledani
13 - ve filtru ji zobrazime jako vybranou
14 - nad vysledky zobrazime jako vybranou
15 - pokud tam neni:
16 - Nezobrazi se levy sloupec s filtrem.
17 - Nezobrazi se vybrane kategorie nad vysledky.
18 - Nazev stranky nebude Vsechny clanky, ale nazev konkretni kategorie z TEMA.
19-->
20<#assign
21 hlavniTematickaOblastVocabulary = global.getVocabulary(groupId, vocabularyName.HLAVNI_TEMATICKA_OBLAST)!""
22 temaVocabulary = global.getVocabulary(groupId, vocabularyName.TEMA)!""
23
24 categoriesHlavniTematickaOblast = macros.prepareCategories(vocabularyName.HLAVNI_TEMATICKA_OBLAST)
25 categoriesTema = macros.prepareCategories(vocabularyName.TEMA)
26
27 structClanek = macros.structClanek
28 structClanekBM = macros.structClanekBM
29 <#-- nevyhladava sa, len kvoli ziskaniu odkazu z CLANEK_BM na Metropolitan -->
30 structMetropolitan = macros.structMetropolitan
31 structTiskovaZprava = macros.structTiskovaZprava
32
33 structures = [
34 {
35 "name": "Aktualita",
36 "structureId": structClanek?has_content?then(structClanek.getStructureId(), ""),
37 "slug": requestParamValue.TYP_CLANEK
38 },
39 {
40 "name": "Článek z Brněnského metropolitanu",
41 "structureId": structClanekBM?has_content?then(structClanekBM.getStructureId(), ""),
42 "slug": requestParamValue.TYP_CLANEK_BM
43 },
44 {
45 "name": "Tisková zpráva",
46 "structureId": structTiskovaZprava?has_content?then(structTiskovaZprava.getStructureId(), ""),
47 "slug": requestParamValue.TYP_TISKOVA_ZPRAVA
48 }
49 ]
50
51 kategorieParamName = requestParamName.KATEGORIE
52 typObsahuParamName = requestParamName.TYP
53
54 selectedCategoriesHlavniTematickaOblast = getSelectedObjects(kategorieParamName, categoriesHlavniTematickaOblast)
55 selectedCategoriesTema = getSelectedObjects(kategorieParamName, categoriesTema)
56 selectedTypObsahu = getSelectedObjects(typObsahuParamName, structures)
57
58 isOnlyOneTemaLayout = (selectedCategoriesTema?size == 1) && (selectedCategoriesHlavniTematickaOblast?size == 0)
59 isAllArticlesLayout = !isOnlyOneTemaLayout
60 pageTitle = isOnlyOneTemaLayout?then(selectedCategoriesTema[0].name, "Všechny články")
61
62 pagerSpec = {
63 "preserveParamNames": [ kategorieParamName, typObsahuParamName ]
64 }
65
66 pager = global.initPager(pagerSpec)
67
68 <#-- ak su nejake vybrane typy obsahu (selectedTypObsahu), pouzi tie, inak pouzi vsetky povolene (structures) -->
69 selectedClassTypeIds = (selectedTypObsahu?size gt 0)?then(selectedTypObsahu?map(x -> x.structureId), structures?map(x -> x.structureId))
70
71 <#-- filtruju sa obsahy s kategoriou s danym nazvom jak zo slovnika HLAVNI_TEMATICKA_OBLAST, tak TEMA -->
72 anyCategoryIdsTema = selectedCategoriesTema?map(x -> x.id)
73 anyCategoryIdsHlavniTematickaOblast = selectedCategoriesHlavniTematickaOblast?map(x -> x.id)
74 anyCategoryIds = anyCategoryIdsTema + anyCategoryIdsHlavniTematickaOblast
75
76 spec = {
77 "classTypeIds": selectedClassTypeIds,
78 "orderByCol1": orderByCol.PUBLISH_DATE,
79 "orderByType1": orderByType.DESC,
80 "orderByCol2": orderByCol.TITLE,
81 "orderByType2": orderByType.ASC,
82 "start": pager.startIndex,
83 "end": pager.endIndex,
84 "anyCategoryIds": anyCategoryIds
85 }
86
87 <#-- TODO upravit tak aby sa nevolalo 2x getJAAssetEntryQuery -->
88 <#-- + miesto toho pouzit getJournalArticleListWithQuery ? -->
89 entries = global.getJAEntriesFromAEQ(spec)
90
91 total = AssetEntryLocalService.getEntriesCount(global.getJAAssetEntryQuery(spec))
92
93 pager = global.updatePager(pager, total)
94/>
95
96<main tabindex="-1" id="bno-main">
97 <@macros.printHeaderTitle title="${pageTitle}" />
98
99 <div class="bno-main">
100 <div class="bno-container">
101 <div class="bno-container__content">
102 <div class="bno-layout ${isAllArticlesLayout?then('bno-layout--ratio-1-3', '')}">
103 <#if isAllArticlesLayout>
104 <#-- DESKTOPOVA VERZE FILTRU -->
105 <aside class="bno-layout__col u-hide--tablet">
106 <fieldset>
107 <legend>Témata</legend>
108 <div class="bno-form-control bno-form-control--custom">
109 <ul class="bno-form-group">
110 <#-- Checkboxy pouze ze slovniku HLAVNI_TEMATICKA_OBLAST -->
111 <#list categoriesHlavniTematickaOblast as category>
112 <#assign randomId = stringUtil.randomId() />
113 <li class="bno-form-group__item">
114 <input
115 id="${randomId}"
116 class="bno-form-control__checkbox js-filter-add"
117 type="checkbox"
118 name="temata"
119 data-slug="${category.slug}"
120 aria-required="false"
121 aria-disabled="false"
122 ${isCategorySelected(kategorieParamName,category.slug)?then('checked','')}
123 >
124 <label class="bno-form-control__label" for="${randomId}">
125 ${category.name}
126 <#-- TODO number? -->
127 <#-- <span>(18)</span> -->
128 </label>
129 <span class="bno-form-control__indicator"></span>
130 </li>
131 </#list>
132 </ul>
133 </div>
134 </fieldset>
135
136 <fieldset>
137 <div class="bno-accordion bno-accordion--no-inner-offset bno-accordion--noborder" role="list">
138 <button
139 id="bno-accordion-header-0"
140 class="bno-accordion__header bno-accordion__header--noborder bno-accordion__header--no-inner-offset is-expanded"
141 role="listitem"
142 aria-expanded="true"
143 aria-controls="bno-accordion-content-0"
144 >
145 <legend>Typ obsahu</legend>
146 <span class="bno-icon bno-icon--arrow-narrow bno-icon--16x16" aria-hidden="true"></span>
147 </button>
148 <div
149 class="bno-accordion__content bno-accordion__content--no-inner-offset bno-accordion__content--noborder"
150 id="bno-accordion-content-0"
151 aria-labelledby="bno-accordion-header-0"
152 aria-hidden="false"
153 style="min-height: 117px; height: auto; visibility: visible; overflow: initial;"
154 >
155 <div class="bno-accordion__content-inner">
156 <div class="bno-form-control bno-form-control--custom">
157 <ul class="bno-form-group">
158 <#list structures as structure>
159 <#assign randomId = stringUtil.randomId() />
160 <li class="bno-form-group__item">
161 <input
162 id="${randomId}"
163 class="bno-form-control__checkbox js-filter-add"
164 type="checkbox"
165 name="typy-obsahu"
166 data-slug="${structure.slug}"
167 aria-required="false"
168 aria-disabled="false"
169 ${isCategorySelected(typObsahuParamName,structure.slug)?then('checked','')}
170 >
171 <label class="bno-form-control__label" for="${randomId}">
172 ${structure.name}
173 </label>
174 <span class="bno-form-control__indicator"></span>
175 </li>
176 </#list>
177 </ul>
178 </div>
179 </div>
180 </div>
181 </div>
182 </fieldset>
183 </aside>
184 </#if>
185 <section class="bno-layout__col">
186 <#if isAllArticlesLayout>
187 <#-- MOBILNI VERZE FILTRU -->
188 <button
189 class="bno-button bno-button--secondary bno-button--medium bno-button--spread-max u-hide-from--tablet bno-modal__trigger u-mb--32"
190 data-id="modal-01"
191 >
192 Filtrovat výsledky
193 <#-- <span class="u-text--badge">3</span> -->
194 </button>
195 <div id="modal-01" class="bno-modal bno-modal--max">
196 <div class="bno-modal__content">
197 <div class="bno-modal__header">
198 <h2>Filtry</h2>
199 </div>
200 <div class="bno-modal__content-inner">
201 <fieldset>
202 <legend>Témata</legend>
203 <div class="bno-form-control bno-form-control--custom">
204 <ul class="bno-form-group">
205 <#-- Checkboxy pouze ze slovniku HLAVNI_TEMATICKA_OBLAST -->
206 <#list categoriesHlavniTematickaOblast as category>
207 <#assign randomId = stringUtil.randomId() />
208 <li class="bno-form-group__item">
209 <input
210 id="${randomId}"
211 class="bno-form-control__checkbox js-filter-add"
212 type="checkbox"
213 name="temata"
214 data-slug="${category.slug}"
215 aria-required="false"
216 aria-disabled="false"
217 ${isCategorySelected(kategorieParamName,category.slug)?then('checked','')}
218 >
219 <label class="bno-form-control__label" for="${randomId}">
220 ${category.name}
221 <#-- <span>(18)</span> -->
222 </label>
223 <span class="bno-form-control__indicator"></span>
224 </li>
225 </#list>
226 </ul>
227 </div>
228 </fieldset>
229 <fieldset>
230 <div class="bno-accordion bno-accordion--no-inner-offset bno-accordion--noborder" role="list">
231 <button
232 id="bno-accordion-header-2"
233 class="bno-accordion__header bno-accordion__header--no-inner-offset bno-accordion__header--noborder"
234 role="listitem"
235 aria-expanded="false"
236 aria-controls="bno-accordion-content-2"
237 >
238 <legend>Typ obsahu</legend>
239 <span class="bno-icon bno-icon--arrow-narrow bno-icon--16x16" aria-hidden="true"></span>
240 </button>
241 <div
242 class="bno-accordion__content bno-accordion__content--no-inner-offset bno-accordion__content--noborder"
243 id="bno-accordion-content-2"
244 aria-labelledby="bno-accordion-header-2"
245 >
246 <div class="bno-accordion__content-inner">
247 <div class="bno-form-control bno-form-control--custom">
248 <ul class="bno-form-group">
249 <#list structures as structure>
250 <#assign randomId = stringUtil.randomId() />
251 <li class="bno-form-group__item">
252 <input
253 id="${randomId}"
254 class="bno-form-control__checkbox js-filter-add"
255 type="checkbox"
256 name="typy-obsahu"
257 data-slug="${structure.slug}"
258 aria-required="false"
259 aria-disabled="false"
260 ${isCategorySelected(typObsahuParamName,structure.slug)?then('checked','')}
261 >
262 <label class="bno-form-control__label" for="${randomId}">
263 ${structure.name}
264 </label>
265 <span class="bno-form-control__indicator"></span>
266 </li>
267 </#list>
268 </ul>
269 </div>
270 </div>
271 </div>
272 </div>
273 </fieldset>
274 </div>
275 <div class="bno-modal__footer">
276 <#-- TODO?
277 - Aby zde mohlo byt tlacitko Zobrazit vysledky, museli bychom zmenit chovani stranky.
278 - Nesmela by se prenacist po kazde zmene stavu checkboxu.
279 - a) Cekat s reloadem (a tedy novym hledanim) az po kliknuti na tento button. Do te doby nereagovat na zmeny stavu checkboxu.
280 - b) Zajistit plynulejsi chod bez hard-reload.
281 - Volat sluzbu pres API?
282 - Predelat na FE app?
283 -->
284 <#-- <button class="bno-button bno-button--primary bno-button--medium bno-button--spread-max">
285 <span>
286 Zobrazit výsledky
287 (39)
288 </span>
289 </button> -->
290 <button class="bno-button bno-button--grey-dark bno-button--medium bno-button--spread-max js-filter-reset">
291 <span>Zrušit filtry</span>
292 </button>
293 </div>
294 <button
295 class="bno-button bno-modal__close"
296 aria-labelledby="modal-close"
297 >
298 <span id="modal-close" class="bno-button__label u-sr-only">
299 Zavřít modální okno
300 </span>
301 </button>
302 </div>
303 <div class="bno-modal__backdrop"></div>
304 </div>
305 </#if>
306
307 <#if isAllArticlesLayout>
308 <#-- VYBRANE FILTRY -->
309 <#if selectedCategoriesHlavniTematickaOblast?size gt 0 || selectedTypObsahu?size gt 0>
310 <section class="u-mb--32" aria-label="Použité filtry">
311 <div class="bno-flexbox bno-flexbox--gap-8">
312 <span class="u-mt--10">Filtry:</span>
313 <div class="bno-tab-links bno-tab-links--filter u-mt--unset u-mb--unset">
314 <ul class="bno-list--plain bno-tab-links__holder" role="menubar" aria-label="Upřesnění vyhledávání">
315 <#-- vybrane filtry pouze ze slovniku HLAVNI_TEMATICKA_OBLAST -->
316 <#list selectedCategoriesHlavniTematickaOblast as category>
317 <li class="bno-tab-links__item" role="menuitem">
318 <button
319 class="bno-button bno-button--grey bno-button--medium js-filter-remove"
320 aria-label="Zrušit filtr Rozhovory"
321 data-slug="${category.slug}"
322 name="temata"
323 >
324 <span>${category.name}</span>
325 <span class="bno-icon bno-icon--cross bno-icon--14x14" aria-hidden="true"></span>
326 </button>
327 </li>
328 </#list>
329 <#list selectedTypObsahu as structure>
330 <li class="bno-tab-links__item" role="menuitem">
331 <button
332 class="bno-button bno-button--grey bno-button--medium js-filter-remove"
333 aria-label="Zrušit filtr Rozhovory"
334 data-slug="${structure.slug}"
335 name="typy-obsahu"
336 >
337 <span>${structure.name}</span>
338 <span class="bno-icon bno-icon--cross bno-icon--14x14" aria-hidden="true"></span>
339 </button>
340 </li>
341 </#list>
342 <li class="bno-tab-links__item" role="menuitem">
343 <button
344 class="bno-button bno-button--grey-dark bno-button--medium js-filter-reset"
345 aria-label="Zrušit všechny filtry"
346 >
347 <span>Zrušit filtry</span>
348 </button>
349 </li>
350 </ul>
351 </div>
352 </div>
353 </section>
354 </#if>
355 </#if>
356
357 <#-- VYSLEDKY -->
358 <#if total gt 0>
359 <ul class="bno-list--plain">
360 <#-- entries - smes ze struktur Clanek, ClanekBm, TZ -->
361 <#list entries as curEntry>
362 <#if curEntry.getAssetRenderer()??>
363 <#--
364 Note: funkce prepareDataClanek() je pro Clanky a ClankyBm, ale zde je pouzitelna i pro TZ,
365 nebot vraci properties, ktere jsou spolecne a potrebne pro zdejsi vypis:
366 title, url, displayDate, perex, categoriesHlavniTematickaOblast
367 -->
368 <#assign
369 data = macros.prepareDataClanek(curEntry, "")
370 />
371
372 <li>
373 <@macros.printArticlePreview data />
374 </li>
375 </#if>
376 </#list>
377 </ul>
378
379 <@global.printPagination pager />
380 <#else>
381 <p>Nebyly nalezeny žádné záznamy.</p>
382 </#if>
383 </section>
384 </div>
385 </div>
386 </div>
387 </div>
388</main>
389
390<script>
391 let kategorie = [
392 <#list selectedCategoriesHlavniTematickaOblast as kategorie>
393 '${kategorie.slug}'<#sep>,</#sep>
394 </#list>
395 ];
396
397 let typObsahu = [
398 <#list selectedTypObsahu as typObsahu>
399 '${typObsahu.slug}'<#sep>,</#sep>
400 </#list>
401 ];
402
403 function addToFilter(list, slug) {
404 const index = list.indexOf(slug);
405
406 if (index < 0) {
407 list.push(slug);
408
409 filter();
410 }
411 }
412
413 function removeFromFilter(list, slug) {
414 const index = list.indexOf(slug);
415
416 if (index >= 0) {
417 list.splice(index, 1);
418
419 filter();
420 }
421 }
422
423 function resetFilter() {
424 kategorie = [];
425 typObsahu = [];
426
427 filter();
428 }
429
430 const kategorieButtons = document.querySelectorAll('[name="temata"].js-filter-add');
431 kategorieButtons.forEach((item) => {
432 item.onclick = function() {
433 if (this.checked) {
434 addToFilter(kategorie, this.dataset.slug);
435 } else {
436 removeFromFilter(kategorie, this.dataset.slug);
437 }
438 };
439 });
440
441 const selectedKategorieButtons = document.querySelectorAll('[name="temata"].js-filter-remove');
442 selectedKategorieButtons.forEach((item) => {
443 item.onclick = function() {
444 removeFromFilter(kategorie, this.dataset.slug);
445 };
446 });
447
448 const typObsahuButtons = document.querySelectorAll('[name="typy-obsahu"].js-filter-add');
449 typObsahuButtons.forEach((item) => {
450 item.onclick = function() {
451 if (this.checked) {
452 addToFilter(typObsahu, this.dataset.slug);
453 } else {
454 removeFromFilter(typObsahu, this.dataset.slug);
455 }
456 };
457 });
458
459 const selectedTypObsahuButtons = document.querySelectorAll('[name="typy-obsahu"].js-filter-remove');
460 selectedTypObsahuButtons.forEach((item) => {
461 item.onclick = function() {
462 removeFromFilter(typObsahu, this.dataset.slug);
463 };
464 });
465
466 const resetButtons = document.querySelectorAll('.js-filter-reset');
467 resetButtons.forEach((item) => {
468 item.onclick = function() {
469 resetFilter();
470 };
471 });
472
473 function filter() {
474 var kategorieQuery = kategorie.join('&${kategorieParamName}=');
475
476 if (kategorieQuery.length > 0) {
477 kategorieQuery = '${kategorieParamName}=' + kategorieQuery;
478 }
479
480 var typObsahuQuery = typObsahu.join('&${typObsahuParamName}=');
481
482 if (typObsahuQuery.length > 0) {
483 typObsahuQuery = '${typObsahuParamName}=' + typObsahuQuery;
484 }
485
486 const query = [kategorieQuery, typObsahuQuery].join('&');
487
488 window.location = encodeURI("?" + query);
489 }
490</script>
491
492<#--
493 Funkce vrati seznam objektu, ktere byli zvolene na zaklade hodnot URL parametru paramName
494-->
495<#function getSelectedObjects paramName objectList>
496 <#assign selected = [] />
497
498 <#if paramName?has_content && objectList?size gt 0>
499 <#assign selectedValues = request.getParameterValues(paramName)![] />
500
501 <#list selectedValues as selectedValue>
502 <#assign filteredValues = objectList?filter(x -> x.slug?string == selectedValue)![] />
503
504 <#if filteredValues?size gt 0>
505 <#-- slug musi byt unikatny, preto sa najde maximalne jedna polozka -->
506 <#assign selected += [ filteredValues?first ] />
507 </#if>
508 </#list>
509
510 <#assign selected = selected?sort_by("slug") />
511 </#if>
512
513 <#return selected />
514</#function>
515
516<#function isCategorySelected paramName="" slug="">
517 <#assign isSelected = false />
518
519 <#if paramName?has_content && slug?has_content>
520 <#assign
521 selectedValues = request.getParameterValues(paramName)![]
522 isSelected = selectedValues?seq_contains(slug)
523 />
524 </#if>
525
526 <#return isSelected />
527</#function>
528
529<style>
530 .smb-theme fieldset {
531 border: none;
532 margin: unset;
533 padding: unset;
534 }
535
536 .smb-theme legend {
537 font-size: 14px;
538 font-weight: 600;
539 }
540</style>