Se ha producido un error al procesar la plantilla.
Syntax error in template "34352066712900#33336#65816767" in line 31, column 54: Unknown built-in: "json". Help (latest version): https://freemarker.apache.org/docs/ref_builtins.html; you're using FreeMarker 2.3.33. The alphabetical list of built-ins: abs, absolute_template_name, ancestors, api, boolean, byte, c, c_lower_case, c_upper_case, cap_first, capitalize, ceiling, children, chop_linebreak, chunk, cn, contains, counter, date, date_if_unknown, datetime, datetime_if_unknown, default, double, drop_while, ends_with, ensure_ends_with, ensure_starts_with, esc, eval, eval_json, exists, filter, first, float, floor, groups, has_api, has_content, has_next, html, if_exists, index, index_of, int, interpret, is_boolean, is_collection, is_collection_ex, is_date, is_date_like, is_date_only, is_datetime, is_directive, is_enumerable, is_even_item, is_first, is_hash, is_hash_ex, is_indexable, is_infinite, is_last, is_macro, is_markup_output, is_method, is_nan, is_node, is_number, is_odd_item, is_sequence, is_string, is_time, is_transform, is_unknown_date_like, iso, iso_h, iso_h_nz, iso_local, iso_local_h, iso_local_h_nz, iso_local_m, iso_local_m_nz, iso_local_ms, iso_local_ms_nz, iso_local_nz, iso_m, iso_m_nz, iso_ms, iso_ms_nz, iso_nz, iso_utc, iso_utc_fz, iso_utc_h, iso_utc_h_nz, iso_utc_m, iso_utc_m_nz, iso_utc_ms, iso_utc_ms_nz, iso_utc_nz, item_cycle, item_parity, item_parity_cap, j_string, join, js_string, json_string, keep_after, keep_after_last, keep_before, keep_before_last, keys, last, last_index_of, left_pad, length, long, lower_abc, lower_case, map, markup_string, matches, max, min, namespace, new, next_sibling, no_esc, node_name, node_namespace, node_type, number, number_to_date, number_to_datetime, number_to_time, parent, previous_sibling, remove_beginning, remove_ending, replace, reverse, right_pad, root, round, rtf, seq_contains, seq_index_of, seq_last_index_of, sequence, short, size, sort, sort_by, split, starts_with, string, substring, switch, take_while, then, time, time_if_unknown, trim, truncate, truncate_c, truncate_c_m, truncate_m, truncate_w, truncate_w_m, uncap_first, upper_abc, upper_case, url, url_path, values, web_safe, with_args, with_args_last, word_list, xhtml, xml
1<#--
2 LANGUAGE HEADER DROPDOWN
3 -->
4<#assign currentURL = themeDisplay.getURLCurrent()>
5<#assign baseURL = themeDisplay.getPortalURL()>
6<#assign relativeURL = currentURL?replace(baseURL, "")>
7
8<#assign translatableParams = ["ics", "ctn"] />
9<#assign matchedItemsCache = buildMatchedItemsCache(translatableParams, locale) />
10
11<#assign desc = themeDisplay.getLanguageId()?split("_")?first >
12<div class="select-btn" id="language-select" role="button" aria-haspopup="listbox" aria-expanded="false" tabindex="0">
13 <#assign siteLanguage = themeDisplay.getLocale().getDisplayLanguage( themeDisplay.getLocale() )?cap_first>
14 <span
15 class="sBtn-text text-uppercase d-flex align-content-center align-items-center">${desc} <span
16 class="fa-solid fa-chevron-down" aria-hidden="true"></span></span>
17</div>
18 <ul class="options hide" role="listbox" aria-labelledby="language-select">
19 <li class="option actives" style="pointer-events:none" role="option" aria-selected="true">
20 <span class="option-text">
21 <svg aria-hidden="true" class="lexicon-icon mr-2 lexicon-icon-${themeDisplay.getLanguageId()?replace('_', '-')?lower_case}">
22 <use href="/o/classic-theme/images/clay/icons.svg#${themeDisplay.getLanguageId()?replace('_', '-')?lower_case}"></use>
23 </svg>
24 ${siteLanguage}
25 </span>
26 </li>
27 <#if entries?has_content>
28 <#list entries as curLanguage>
29 <p>LanguageIdTEST:${curLanguage.getLanguageId()}</p>
30
31 <p>matchedItemsCacheTEST:${matchedItemsCache?json}</p>
32
33
34 <#if !curLanguage.isSelected()>
35
36
37
38 <#assign entryHref = buildTranslatedHref(curLanguage.getURL(), curLanguage.getLanguageId(), translatableParams, matchedItemsCache) />
39 <li class="option" role="option"><span class="option-text"> <a href="${entryHref}" class="language-entry-short-text"
40 lang="${curLanguage.getLanguageId()}">${curLanguage.getLongDisplayName()?capitalize}</a> </span></li>
41
42
43 </#if>
44 </#list>
45 </#if>
46</ul>
47
48
49<#-- ============================================================
50 Traduccion de parametros de la URL al cambiar de idioma
51 ============================================================ -->
52
53<#function findMatchedItem paramName locale>
54 <#local paramValue = request.getParameter(paramName)! />
55 <#if !paramValue?has_content>
56 <#return "" />
57 </#if>
58
59 <#local paramValueTrim = paramValue?trim />
60 <#local paramType = paramName?upper_case />
61 <#local endpointURL = "/c/selectoptions/?languageId=" + locale?string + "&sort=name:asc&filter=optionsType eq '" + paramType + "'" />
62 <#local optionsResponse = restClient.get(endpointURL) />
63
64 <#list optionsResponse.items![] as item>
65 <#local valueI18n = item.value_i18n![] />
66 <#local found = false />
67
68 <#list valueI18n?keys as key>
69 <#if valueI18n[key]! == paramValueTrim>
70 <#local found = true />
71 <#break />
72 </#if>
73 </#list>
74
75 <#if !found && (item.value!"") == paramValueTrim>
76 <#local found = true />
77 </#if>
78
79 <#if found>
80 <#return item />
81 </#if>
82 </#list>
83
84 <#return "" />
85</#function>
86
87<#function buildMatchedItemsCache paramNames locale>
88 <#local cache = {} />
89 <#list paramNames as paramName>
90 <#local cache = cache + {paramName: findMatchedItem(paramName, locale)} />
91 </#list>
92 <#return cache />
93</#function>
94
95<#function translateParamInURL originalURL paramName targetLanguageId matchedItemsCache>
96 <#local paramValue = request.getParameter(paramName)! />
97 <#local matchedItem = matchedItemsCache[paramName]!"" />
98
99 <#if !paramValue?has_content || !matchedItem?has_content>
100 <#return originalURL />
101 </#if>
102
103 <#local rawValueInURL = originalURL?replace(".*[?&]" + paramName + "=([^&]*).*", "$1", "r") />
104
105 <#if rawValueInURL == originalURL>
106 <#return originalURL />
107 </#if>
108
109 <#local urlDecoder = staticUtil["java.net.URLDecoder"] />
110 <#local urlEncoder = staticUtil["java.net.URLEncoder"] />
111 <#local decodedValueInURL = urlDecoder.decode(rawValueInURL, "UTF-8") />
112
113 <#if decodedValueInURL != paramValue?trim>
114 <#return originalURL />
115 </#if>
116
117 <#local newValue = matchedItem.value_i18n[targetLanguageId]!matchedItem.value!paramValue />
118
119 <#if newValue == decodedValueInURL>
120 <#return originalURL />
121 </#if>
122
123 <#local newEncoded = urlEncoder.encode(newValue, "UTF-8") />
124
125 <#return originalURL?replace(paramName + "=" + rawValueInURL, paramName + "=" + newEncoded) />
126</#function>
127
128<#function buildTranslatedHref originalURL targetLanguageId paramNames matchedItemsCache>
129 <#local resultURL = originalURL />
130
131 <#list paramNames as paramName>
132 <#local resultURL = translateParamInURL(resultURL, paramName, targetLanguageId, matchedItemsCache) />
133 </#list>
134
135 <#return resultURL />
136</#function>
137
138
139<#-- ============================================================ -->
140
141<script>
142 $(document).ready(function () {
143 // Toggle el estado del menu de idiomas
144 $('.select-btn').on('click', function () {
145 var expanded = $(this).attr('aria-expanded') === 'true';
146 $(this).attr('aria-expanded', !expanded);
147 $('.options').toggleClass('hide', expanded);
148 });
149
150 // Acciones de teclado para la lupa
151 $('.select-btn').on('keydown', function (e) {
152 if (e.key === 'Enter' || e.key === ' ') {
153 e.preventDefault(); // Evitar desplazamiento al presionar espacio
154 $(this).click(); // Simula el click para abrir/cerrar el menu
155 }
156 });
157
158 // Cerrar el menu al hacer clic en cualquier parte fuera de el
159 $(document).on('click', function (event) {
160 if (!$(event.target).closest('.select-btn, .options').length) {
161 $('.options').addClass('hide');
162 $('.select-btn').attr('aria-expanded', 'false');
163 }
164 });
165
166 // Navegar con las teclas de flecha
167 let options = $('.option');
168 let selectedIndex = 0;
169
170 options.on('keydown', function (e) {
171 if (e.key === 'ArrowDown') {
172 selectedIndex = (selectedIndex + 1) % options.length;
173 options.eq(selectedIndex).focus();
174 }
175 if (e.key === 'ArrowUp') {
176 selectedIndex = (selectedIndex - 1 + options.length) % options.length;
177 options.eq(selectedIndex).focus();
178 }
179 if (e.key === 'Enter') {
180 window.location.href = $(this).find('a').attr('href'); // Redirige a la opcion seleccionada
181 }
182 });
183 });
184</script>
El producto se ha añadido a la cesta de la compra
Listado libros relacionados
-
URL del producto:
https://aenorportalesweb-uat.lxc.liferay.com/web/tienda/e/{friendlyURL_display-page-template}/{ClassNameId-CPDefinition}/{CPDefinition ID (Field: product.id)}
por ejemplo: https://aenorportalesweb-uat.lxc.liferay.com/web/tienda/e/producto-tienda/30025/${cpDefinitionId}










