Prišlo je do napake pri odpiranju teme.
Java method "com.sun.proxy.$Proxy1381.getArticle(long, String)" threw an exception when invoked on com.sun.proxy.$Proxy1381 object "com.liferay.journal.service.impl.JournalArticleLocalServiceImpl@e56be6e"; see cause exception in the Java stack trace.
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign card_article = journalArticle... [in template "20099#20125#494283" at line 94, column 15]
----
1<#assign theme_js_path = themeDisplay.getPathThemeJavaScript() />
2<#assign theme_css_path = themeDisplay.getPathThemeCss() />
3
4<#assign journalArticleLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleLocalService") />
5
6<#assign product_categories = [] />
7
8<#if entries?has_content>
9 <#list entries as curEntry>
10 <#assign categories = curEntry.getCategories() />
11
12 <#list categories as curCategory>
13 <#assign categoryName = curCategory.getName() />
14 <#if !product_categories?seq_contains(curCategory)>
15 <#assign product_categories += [curCategory] />
16 </#if>
17 </#list>
18 </#list>
19</#if>
20
21<#assign show_custom_title = false />
22
23<#assign portlet_preferences = portletDisplay.getPortletSetup() />
24<#assign portlet_preferences_map = portlet_preferences.getMap() />
25
26<#if portlet_preferences_map?? && portlet_preferences_map["portletSetupUseCustomTitle"]??>
27 <#assign VOID = portlet_preferences.setValue("portletSetupUseCustomTitle", "false") />
28 <#assign show_custom_title = portlet_preferences_map["portletSetupUseCustomTitle"][0]?boolean />
29</#if>
30
31${portletDisplay.setShowPortletCssIcon(true)}
32
33<#assign is_asset_card = true />
34
35<#list portletPreferences as key, value_sequence>
36 <#if key == "anyAssetType" && value_sequence[0] == "true">
37 <#assign is_asset_card = false />
38 </#if>
39</#list>
40
41<#if entries?has_content>
42 <#assign assetRenderer = entries[0].getAssetRenderer() />
43 <#assign className = assetRenderer.getClassName() />
44
45 <#if className == "com.liferay.journal.model.JournalArticle">
46 <#assign assetClassTypeId = entries[0].getClassTypeId() />
47
48 <#assign DDMStructureLocalServiceUtil = staticUtil["com.liferay.dynamic.data.mapping.service.DDMStructureLocalServiceUtil"] />
49
50 <#assign structure = DDMStructureLocalServiceUtil.getStructure(assetClassTypeId) />
51 <#assign structure_name = structure.getName(locale)?trim?upper_case />
52
53 <#if structure_name != "ZAME CARD" && structure_name != "PRODUCT CARD">
54 <#assign is_asset_card = false />
55 </#if>
56 <#else>
57 <#assign is_asset_card = false />
58 </#if>
59</#if>
60
61<#if is_asset_card>
62 <link rel="stylesheet" href="${theme_css_path}/components-standalone/badges-and-filters.css" />
63
64 <div id="product-cards-list-${randomNamespace}">
65 <div class="container">
66 <#if product_categories?has_content>
67 <div class="d-flex flex-wrap g-gap-2 justify-content-center mb-5" id="product-cards-list-categories-${randomNamespace}">
68 <label class="g-chip g-chip--selected" data-category="vse">
69 <input type="checkbox" checked />
70 <span>Vse</span>
71 </label>
72 <#list product_categories as curCategory>
73 <#assign category_normalized = curCategory.getName()?replace("ž", "z")?replace("č", "c")?replace("ć", "c")?replace("đ", "d")?replace("š", "s")?replace("Ž", "z")?replace("Č", "c")?replace("Ć", "c")?replace("Đ", "d")?replace("Š", "s")?replace(" ", "-")?lower_case />
74 <label class="g-chip" data-category="${category_normalized}">
75 <input type="checkbox" />
76 <span>${curCategory.getName()}</span>
77 </label>
78 </#list>
79 </div>
80 </#if>
81 </div>
82
83 <div class="container mb-6">
84 <div class="row justify-content-center mb-5">
85 <#if entries?has_content>
86 <#list entries as curEntry>
87 <div class="col-lg-4 col-md-6 mb-4">
88 <#assign assetRenderer = curEntry.getAssetRenderer() />
89 <#assign asset_object = assetRenderer.getAssetObject() />
90 <#assign card_article_id = asset_object.articleId />
91
92 <#assign group_id = themeDisplay.getScopeGroupId() />
93
94 <#assign card_article = journalArticleLocalService.getArticle(getterUtil.getLong(group_id), card_article_id) />
95 <#assign card_template_ddm_key = card_article.getDDMTemplateKey() />
96
97 <#assign card_article_content = journalArticleLocalService.getArticleDisplay(getterUtil.getLong(group_id), card_article_id, card_template_ddm_key, "", locale, themeDisplay).getContent() />
98
99 ${card_article_content}
100 </div>
101
102 </#list>
103 </#if>
104 </div>
105 </div>
106 </div>
107
108 <script>
109 Liferay.on("allPortletsReady", function () {
110 const cards = document.querySelectorAll("#product-cards-list-${randomNamespace} div[data-category]");
111 const categorySelectors = document.querySelectorAll("#product-cards-list-categories-${randomNamespace} label");
112 const vseButton = document.querySelector('#product-cards-list-categories-${randomNamespace} label[data-category="vse"]');
113 const activeCategories = new Set(["vse"]);
114
115 const allCategories = new Set([
116 <#if product_categories?has_content>
117 <#list product_categories as curCategory>
118 <#assign category_normalized = curCategory.getName()?replace("ž", "z")?replace("č", "c")?replace("ć", "c")?replace("đ", "d")?replace("š", "s")?replace("Ž", "z")?replace("Č", "c")?replace("Ć", "c")?replace("Đ", "d")?replace("Š", "s")?replace(" ", "-")?lower_case />
119 "${category_normalized}",
120 </#list>
121 </#if>
122 ]);
123
124 allCategories.forEach(category => {
125 let counter = 0;
126
127 cards.forEach(card => {
128 if(card.dataset.category.includes(category)) {
129 counter++;
130 }
131 });
132
133 const categorySelector = document.querySelector(`#product-cards-list-categories-${randomNamespace} <#noparse>label[data-category="${category}"]</#noparse> span`);
134
135 <#-- fixing liferay duplicate categories bug -->
136 const categorySelectors = document.querySelectorAll(`#product-cards-list-categories-${randomNamespace} <#noparse>label[data-category="${category}"]</#noparse> span`);
137
138 categorySelectors.forEach((cat, index) => {
139 if(index !== 0){
140 cat.parentNode.remove();
141 }
142 })
143
144
145 <#noparse>
146 categorySelector.innerHTML += ` (${counter})`;
147 </#noparse>
148 })
149
150 <#noparse>
151 function findCardsWithCategory(category) {
152 return document.querySelectorAll(`#product-cards-list-${randomNamespace} div[data-category="${category}"]`).parentElement;
153 }
154 </#noparse>
155
156 function resetCards() {
157 cards.forEach(card => {
158 card.parentElement.classList.remove("d-none");
159 })
160 }
161
162 function showActiveCategoriesCards() {
163 cards.forEach(card => {
164 const cardCategory = card.dataset.category;
165 if(activeCategories.has(cardCategory)) {
166 card.parentElement.classList.remove("d-none");
167 } else {
168 card.parentElement.classList.add("d-none");
169 }
170 })
171 }
172
173 function uncheckAllFilter() {
174 activeCategories.delete("vse");
175 uncheckCategorySelector(vseButton);
176 }
177
178 function checkAllFilter() {
179 activeCategories.clear();
180 activeCategories.add("vse");
181 checkCategorySelector(vseButton);
182 resetCards();
183 }
184
185 function removeSelectedClassesFromCategorySelectors(categorySelectors) {
186 categorySelectors.forEach(categorySelector => {
187 removeActiveClassFromCategorySelector(categorySelector);
188 });
189 }
190
191 function addActiveClassToCategorySelector(button) {
192 button.classList.add("g-chip--selected");
193 }
194 function removeActiveClassFromCategorySelector(button) {
195 button.classList.remove("g-chip--selected");
196 }
197
198 function checkCategorySelector(button) {
199 addActiveClassToCategorySelector(button)
200 button.querySelector("input").checked = true;
201 }
202
203 function uncheckCategorySelector(button) {
204 removeActiveClassFromCategorySelector(button);
205 button.querySelector("input").checked = false;
206 }
207
208 function resetActiveCategories() {
209 removeSelectedClassesFromCategorySelectors(categorySelectors);
210 checkAllFilter();
211 }
212
213 function toggleActiveCategory(category, button) {
214 if(activeCategories.has(category)) {
215 activeCategories.delete(category);
216 uncheckCategorySelector(button);
217 } else {
218 activeCategories.add(category);
219 checkCategorySelector(button);
220 uncheckAllFilter();
221 }
222
223 if(activeCategories.size === 0) {
224 checkAllFilter();
225 }
226 }
227
228 categorySelectors.forEach(button => {
229 button.addEventListener("click", function(e) {
230 e.preventDefault();
231
232 if(button.dataset.category !== "vse") {
233 const buttonCategory = button.dataset.category;
234
235 toggleActiveCategory(buttonCategory, button);
236
237 if(!activeCategories.has("vse")) {
238 showActiveCategoriesCards();
239 }
240 } else {
241 resetActiveCategories();
242 }
243 })
244 })
245 });
246
247 </script>
248<#else>
249 <div class="container">
250 <div class="alert alert-danger">You're using "Product cards list with filter" template. Please choose Product card or ZAME card as asset type!</div>
251 </div>
252</#if>