S'ha produït un error mentre es processava la plantilla.
The following has evaluated to null or missing: ==> webContentData.titleMap.ca_ES [in template "20097#20123#BLOG_DETALLE" at line 334, column 41] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: ${webContentData.titleMap.ca_ES} [in template "20097#20123#BLOG_DETALLE" at line 334, column 39] ----
1<#-- Parseo de la fecha de publicación y días -->
2<#assign publishDate = .vars['reserved-article-display-date'].data>
3<#assign originalLocale = .locale>
4<#setting locale = localeUtil.getDefault()>
5<#assign publishDate = publishDate?datetime("EEE, d MMM yyyy HH:mm:ss Z")>
6<#assign locale = originalLocale>
7<#assign localeCurrent = themeDisplay.getLocale() />
8
9<#assign numberOfSlides = GrupoImagenVideo.getSiblings()?size>
10
11<#-- Obtención de categorías del publicador de contenidos -->
12<#assign journalArticleResourceLocalService = serviceLocator.findService("com.liferay.journal.service.JournalArticleResourceLocalService")>
13<#assign assetEntryLocalService = serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService")>
14<#assign journalArticleId = .vars['reserved-article-id'].data>
15<#assign articleResourcePrimaryKey = journalArticleResourceLocalService.getArticleResourcePrimKey(groupId, journalArticleId)>
16<#assign assetEntry = assetEntryLocalService.getEntry("com.liferay.journal.model.JournalArticle", articleResourcePrimaryKey)>
17<#assign assetCategories = assetEntry.getCategories()>
18
19<#assign portalURL = themeDisplay.getPortalURL() />
20<#assign currentUrl = themeDisplay.getPortalURL() + themeDisplay.getURLCurrent() />
21
22<#-- Obtención de otras noticias relacionadas -->
23<#assign GroupLocalService = serviceLocator.findService("com.liferay.portal.kernel.service.GroupLocalService")>
24<#assign assetEntryQuery = objectUtil('com.liferay.asset.kernel.service.persistence.AssetEntryQuery')>
25<#assign void = assetEntryQuery.setOrderByCol1("publishDate")>
26<#assign void = assetEntryQuery.setOrderByCol2("title")>
27<#assign relatedNews = assetEntryLocalService.getEntries(assetEntryQuery)>
28
29<div id="${randomNamespace}detallePost"
30 class="mm__content__detail">
31
32 <div class="container">
33
34 <#-- Título -->
35 <h1 id="titulo_post">
36 <#if (TitularPost.getData())??>
37 ${TitularPost.getData()}
38 </#if>
39 </h1>
40
41 <#-- Subtítulo -->
42 <h2 id="descripcion_post" class="col-md-10 px-0">
43 <#if (SubtituloPost.getData())??>
44 ${SubtituloPost.getData()}
45 </#if>
46 </h2>
47
48 <div class="mm__share">
49 <div class="dropdown">
50 <a class="dropdown-toggle"
51 href="#"
52 id="mm__social-network"
53 data-toggle="dropdown"
54 aria-haspopup="true"
55 aria-expanded="false">
56 <svg xmlns="http://www.w3.org/2000/svg"
57 width="50"
58 height="50"
59 viewBox="0 0 63 63"
60 fill="none">
61 <circle cx="31.5"
62 cy="31.5"
63 r="30"
64 stroke="#007BC2"
65 stroke-width="3" />
66 <path d="M41 44.8003L22 31.5003L41 18.2003"
67 stroke="#007BC2"
68 stroke-width="3" />
69 <circle cx="39.1008"
70 cy="20.1003"
71 r="5.3"
72 fill="white"
73 stroke="#007BC2"
74 stroke-width="3" />
75 <circle cx="39.1008"
76 cy="42.9001"
77 r="5.3"
78 fill="white"
79 stroke="#007BC2"
80 stroke-width="3" />
81 <circle cx="20.1008"
82 cy="31.5002"
83 r="5.3"
84 fill="white"
85 stroke="#007BC2"
86 stroke-width="3" />
87 </svg>
88 </a>
89 <div class="mm__social-network dropdown-menu dropdown-menu-right"
90 aria-labelledby="mm__social-network"
91 style="position: absolute; will-change: transform; top: 0px; transform: translate3d(25px, 30px, 0px); min-width: 0;">
92 <ul>
93 <li>
94 <a target="_blank"
95 class="share"
96 href="https://twitter.com/intent/tweet?original_referer=${TitularPost.getData()}&text=${TitularPost.getData()}&tw_p=tweetbutton&url=${currentUrl}&hashtags=MutualMedica">
97 <svg xmlns="http://www.w3.org/2000/svg"
98 width="35"
99 height="35"
100 fill="currentColor"
101 class="bi bi-twitter"
102 viewBox="0 0 16 16">
103 <path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z" />
104 </svg>
105 </a>
106 </li>
107 <li>
108 <a target="_blank"
109 class="share"
110 href="https://wa.me/?text=${currentUrl}">
111 <svg xmlns="http://www.w3.org/2000/svg"
112 width="35"
113 height="35"
114 fill="currentColor"
115 class="bi bi-whatsapp"
116 viewBox="0 0 16 16">
117 <path d="M13.601 2.326A7.854 7.854 0 0 0 7.994 0C3.627 0 .068 3.558.064 7.926c0 1.399.366 2.76 1.057 3.965L0 16l4.204-1.102a7.933 7.933 0 0 0 3.79.965h.004c4.368 0 7.926-3.558 7.93-7.93A7.898 7.898 0 0 0 13.6 2.326zM7.994 14.521a6.573 6.573 0 0 1-3.356-.92l-.24-.144-2.494.654.666-2.433-.156-.251a6.56 6.56 0 0 1-1.007-3.505c0-3.626 2.957-6.584 6.591-6.584a6.56 6.56 0 0 1 4.66 1.931 6.557 6.557 0 0 1 1.928 4.66c-.004 3.639-2.961 6.592-6.592 6.592zm3.615-4.934c-.197-.099-1.17-.578-1.353-.646-.182-.065-.315-.099-.445.099-.133.197-.513.646-.627.775-.114.133-.232.148-.43.05-.197-.1-.836-.308-1.592-.985-.59-.525-.985-1.175-1.103-1.372-.114-.198-.011-.304.088-.403.087-.088.197-.232.296-.346.1-.114.133-.198.198-.33.065-.134.034-.248-.015-.347-.05-.099-.445-1.076-.612-1.47-.16-.389-.323-.335-.445-.34-.114-.007-.247-.007-.38-.007a.729.729 0 0 0-.529.247c-.182.198-.691.677-.691 1.654 0 .977.71 1.916.81 2.049.098.133 1.394 2.132 3.383 2.992.47.205.84.326 1.129.418.475.152.904.129 1.246.08.38-.058 1.171-.48 1.338-.943.164-.464.164-.86.114-.943-.049-.084-.182-.133-.38-.232z" />
118 </svg>
119 </a>
120 </li>
121 <li>
122 <a target="_blank"
123 class="share"
124 href="https://www.linkedin.com/shareArticle?mini=true&url=${currentUrl}&title=${TitularPost.getData()}&source=LinkedIn">
125 <svg xmlns="http://www.w3.org/2000/svg"
126 width="35"
127 height="35"
128 fill="currentColor"
129 class="bi bi-linkedin"
130 viewBox="0 0 16 16">
131 <path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z" />
132 </svg>
133 </a>
134 </li>
135 <li>
136 <a target="_blank"
137 class="share"
138 href="mailto:?subject=${TitularPost.getData()}&body=${currentUrl}">
139 <svg xmlns="http://www.w3.org/2000/svg"
140 width="35"
141 height="35"
142 fill="currentColor"
143 class="bi bi-envelope"
144 viewBox="0 0 16 16">
145 <path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4Zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1H2Zm13 2.383-4.708 2.825L15 11.105V5.383Zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741ZM1 11.105l4.708-2.897L1 5.383v5.722Z" />
146 </svg>
147 </a>
148 </li>
149 </ul>
150 </div>
151 </div>
152 </div>
153
154 <div class="mm__category" style="max-width: 30rem;">
155 <#list assetCategories as category>
156 <#if localeCurrent?contains("ca_ES")>
157 <a href="${portalURL}/ca/blog?categories=${category.getCategoryId()}"
158 class="btn">${category.getTitle(localeCurrent)}</a>
159 <#else>
160 <a href="${portalURL}/blog?categories=${category.getCategoryId()}"
161 class="btn">${category.getTitle(localeCurrent)}</a>
162 </#if>
163 </#list>
164 </div>
165
166 <div class="mm__date">
167 <p>
168 <#assign
169 webContentData = jsonFactoryUtil.createJSONObject(AutorPost.getData())
170 />
171
172 <#if webContentData?? && webContentData.title??>
173 <#if localeCurrent?contains("ca_ES")>
174 <a href="${portalURL}/ca/autor?idAutor=${webContentData.classPK}">
175 ${webContentData.titleMap.ca_ES}
176 </a>
177 <#else>
178 <a href="${portalURL}/autor?idAutor=${webContentData.classPK}">
179 ${webContentData.titleMap.es_ES}
180 </a>
181 </#if>
182 ·
183 </#if> ${publishDate?string["dd/MM/yy"]} · <#if (TiempoLecturaPost.getData())??> ${TiempoLecturaPost.getData()} </#if>
184 </p>
185 </div>
186 <#-- Carrusel de imagenes y vídeos -->
187 <#if GrupoImagenVideo.getSiblings()?has_content>
188
189 <div id="${randomNamespace}blogCarousel"
190 class="carousel slide mm-img-carousel"
191 data-ride="carousel"
192 data-interval="false"
193 data-wrap="false">
194 <div class="carousel-inner">
195 <#list GrupoImagenVideo.getSiblings() as multimedia>
196 <@printMultimedia multimedia multimedia?is_first />
197 </#list>
198 </div>
199
200 <#-- Indicadores carrusel si hay más de un elemento multimedia -->
201 <#if GrupoImagenVideo.getSiblings()?size gt 1 || TextoPost.getData()?contains('<div class="embed-responsive')>
202 <ol class="carousel-indicators">
203 <#assign contadorIndicadores = 0/>
204 <#list 0..<GrupoImagenVideo.getSiblings()?size as i>
205 <li data-target="#${randomNamespace}blogCarousel"
206 data-slide-to="${i}"
207 class="${(i == 0)?string('active','')}"
208 id="${randomNamespace}slide${i_index}"></li>
209 <#assign contadorIndicadores = contadorIndicadores + 1/>
210 </#list>
211 <#if TextoPost.getData()?contains('<div class="embed-responsive')>
212 <li data-target="#${randomNamespace}blogCarousel"
213 data-slide-to="${contadorIndicadores}"
214 class="${(contadorIndicadores == 0)?string('active','')}"
215 id="${randomNamespace}slide${contadorIndicadores}"></li>
216 </#if>
217 </ol>
218 </#if>
219
220 </div>
221 </#if>
222
223
224 <#-- Contenido principal de la post y enlaces -->
225
226 <div id="textoPost"
227 class="mm__text__notice">
228 <#if (TextoPost.getData())??>
229 ${TextoPost.getData()}
230 </#if>
231 </div>
232
233 <#if AdjuntosPost.getSiblings()?has_content>
234 <#if AdjuntosPost.getSiblings()[0].getData()?has_content>
235 <div class="mm__content__info-relacionada">
236
237 <h3><@liferay.language key="mutualmedica.blog.detalle.informacion" /></h3>
238 <#list AdjuntosPost.getSiblings() as enlaceVar>
239 <#if enlaceVar.getData()?has_content>
240 <#assign nombreDocumento = enlaceVar.getData()?split("/")>
241
242 <a class="mm__link__document"
243 href="${enlaceVar.getData()}"
244 target="_blank">${nombreDocumento[4]}</a>
245
246 </#if>
247 </#list>
248 </div>
249 </#if>
250 </#if>
251 <div class="mm__content__btn">
252 <#if localeCurrent?contains("ca_ES")>
253 <a class="mm__btn"
254 href="${portalURL}/ca/blog"><@liferay.language key="mutualmedica.blog.detalle.volver" /></a>
255 <#else>
256 <a class="mm__btn"
257 href="${portalURL}/blog"><@liferay.language key="mutualmedica.blog.detalle.volver" /></a>
258 </#if>
259 </div>
260 </div>
261
262</div>
263
264<div id="otrosPosts">
265 <#if relatedNews?has_content && (relatedNews?size > 1)>
266
267 <#assign baseUrl = themeDisplay.getScopeGroup().getPathFriendlyURL(themeDisplay.getLayout().isPrivateLayout(),themeDisplay)>
268 <#assign groupUrl = GroupLocalService.getGroup(themeDisplay.getLayout().getGroupId()).getFriendlyURL()>
269
270 <div class="mm__more__notices">
271 <div class="container">
272 <h2><@liferay.language key="mutualmedica.blog.detalle.otros" /></h2>
273 <div class="row">
274 <#assign relatedCount = 0 >
275 <#list relatedNews as related>
276 <#if relatedCount < 3>
277 <#if related.getClassName() == "com.liferay.journal.model.JournalArticle">
278 <#assign assetRenderer = related.getAssetRenderer()/>
279 <#assign journalArticle = assetRenderer.getAssetObject() />
280 <#if journalArticleId != journalArticle.articleId>
281 <#assign assetRenderer = related.getAssetRenderer()/>
282 <#assign journalArticle = assetRenderer.getAssetObject() />
283 <#assign document = saxReaderUtil.read(journalArticle.getContent())>
284 <#assign rootElement = document.getRootElement()>
285 <#assign defaultLanguageId = parseXml ("@default-locale", rootElement)>
286 <#assign layoutURL = journalArticle.urlTitle />
287 <#assign newsTitle = getField("TitularPost", localeCurrent, defaultLanguageId, rootElement)!>
288 <#assign imgPost = getField("ImagenPost", localeCurrent, defaultLanguageId, rootElement)!>
289 <#assign autPost = getField("AutorPost", localeCurrent, defaultLanguageId, rootElement)!>
290 <#assign templecPost = getField("TiempoLecturaPost", localeCurrent, defaultLanguageId, rootElement)!>
291
292
293 <#if newsTitle?has_content && newsTitle != "">
294 <#if localeCurrent?contains("ca_ES")>
295 <#assign urlDetalleOtroPost = portalURL + "/ca" + themeDisplay.getLayout().getFriendlyURL() + "/mutualmedica/" + journalArticle.getUrlTitle(localeCurrent)>
296 <#else>
297 <#assign urlDetalleOtroPost = portalURL + themeDisplay.getLayout().getFriendlyURL() + "/mutualmedica/" + journalArticle.getUrlTitle(localeCurrent)>
298 </#if>
299
300 <div class="col-12 col-md-4 col-xl-4"
301 onclick="location.href='${urlDetalleOtroPost}'">
302
303 <div class="mm__content__card"
304 tabindex="0"
305 title="${newsTitle}"
306 aria-label="${newsTitle}">
307
308 <#if imgPost?has_content && imgPost != "">
309 <#assign imgContentData = jsonFactoryUtil.createJSONObject(imgPost)/>
310 <div class="mm__content__image-list">
311 <img alt="${imgContentData.alt}"
312 data-fileentryid="${imgContentData.fileEntryId}"
313 src="${imgContentData.url}" />
314 </div>
315 </#if>
316
317
318
319 <#if newsTitle?has_content && newsTitle != "">
320 <h3>${newsTitle}
321 </h3>
322
323 <#assign relatedCount = relatedCount+1 >
324 <p>
325 ${journalArticle.displayDate?string["dd/MM/yy"]} <#if (templecPost)??>· ${templecPost} </#if> <#assign
326 webContentData = jsonFactoryUtil.createJSONObject(autPost)
327 />
328
329 <#if webContentData?? && webContentData.title??>
330 ·
331 <#if localeCurrent?contains("ca_ES")>
332 <a href="${portalURL}/ca/autor?idAutor=${webContentData.classPK}"
333 class="insideLink">
334 ${webContentData.titleMap.ca_ES}
335 </a>
336 <#else>
337 <a href="${portalURL}/autor?idAutor=${webContentData.classPK}"
338 class="insideLink">
339 ${webContentData.titleMap.es_ES}
340 </a>
341 </#if>
342
343 </#if>
344 </p>
345 </#if>
346
347 </div>
348 </div>
349 </#if>
350 </#if>
351 </#if>
352 </#if>
353 </#list>
354 </div>
355 </div>
356 </div>
357
358 </#if>
359
360</div>
361
362<#function getField field languageId defaultLanguageId xml>
363 <#local defaultSelector = "//dynamic-content[@language-id='" + defaultLanguageId + "' and ancestor-or-self::*[@field-reference='" + field + "']]">
364 <#local localeSelector = "//dynamic-content[@language-id='" + languageId + "' and parent::*[@field-reference='" + field + "']]">
365 <#local selector = saxReaderUtil.createXPath(localeSelector)>
366 <#local value = selector.selectSingleNode(xml)!>
367 <#if value?has_content><#return value.getText()></#if>
368 <#local selector = saxReaderUtil.createXPath(defaultSelector)>
369 <#local value = selector.selectSingleNode(xml)!>
370 <#if value?has_content><#return value.getText()></#if>
371 <#return "">
372</#function>
373
374<#function parseXml xpath xml>
375 <#local selector = saxReaderUtil.createXPath(xpath)>
376 <#local result = selector.selectSingleNode(xml)!>
377 <#if result?has_content><#return result.getStringValue()></#if>
378 <#return "">
379</#function>
380
381
382<#macro printMultimedia multimedia active>
383 <div class="carousel-item ${active?string('active','')}">
384 <#if multimedia.ImagenPost.getData()?? && multimedia.ImagenPost.getData() != "">
385 <img alt="${multimedia.ImagenPost.getAttribute("alt")}"
386 src="${multimedia.ImagenPost.getData()}" />
387 <#elseif multimedia.VideoPost.getData()?? && multimedia.VideoPost.getData() != "">
388 <video src="${multimedia.VideoPost.getData()}"
389 controls="controls autoplay" />
390 <#else>
391 <img class="mm-logo"
392 alt="Imagen por defecto"
393 src="${themeDisplay.companyLogo}" />
394 </#if>
395 </div>
396</#macro>
397
398<script type="text/javascript">
399 window.onload = function () {
400 var textoPost = document.getElementById('textoPost');
401 if (textoPost != null) {
402 if (textoPost.querySelector('.embed-responsive')) {
403 var divVideoEmbebido = document.getElementsByClassName('embed-responsive')[0];
404 const node = document.createElement('div');
405 node.classList.add('carousel-item');
406
407 divVideoEmbebido.style.width = '500px';
408
409 node.appendChild(divVideoEmbebido);
410 document.getElementsByClassName('carousel-inner')[0].appendChild(node);
411
412 }
413 }
414 };
415
416 jQuery('.insideLink').click(function (event) {
417 event.stopImmediatePropagation();
418 });
419</script>
420
421<script type="application/ld+json">
422 {
423 "@context" : "https://schema.org",
424 "@type" : "Article",
425 "headline" : "<#if (TitularPost.getData())??>${TitularPost.getData()}</#if>",
426 "author" : {
427 "@type" : "Organization",
428 "name" : "${themeDisplay.getLayout().getGroup().getDescriptiveName()}"
429 },
430 "datePublished" : "${publishDate}",
431 "image" : {
432 "@type" : "ImageObject",
433 "url" : "${themeDisplay.getPortalURL()}<#if (GrupoImagenVideo.ImagenPost.getData())?? && GrupoImagenVideo.ImagenPost.getData() != "">${GrupoImagenVideo.ImagenPost.getData()}</#if>"
434 }
435 }
436</script>