Subprefeitura Cidade Tiradentes

Exibindo 1 para 1 de 3
Um erro ocorreu enquanto processava o modelo.
The following has evaluated to null or missing:
==> cf  [in template "20095#20121#170610" at line 236, column 65]

----
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: ${cf.customValue.data}  [in template "20095#20121#170610" at line 236, column 63]
----
1<#setting locale="pt_BR" /> 
2<#setting time_zone="GMT-3" /> 
3<#assign title=.vars["reserved-article-title"].data /> 
4<#assign publicationDate=.vars['reserved-article-display-date'].data /> 
5<#assign format="EEEE, d 'de' MMMM 'de' yyyy" /> 
6<#assign timeFormat="HH:mm" /> 
7 
8<#assign publicationDate=publicationDate?datetime("EEE, d MMM yyyy HH:mm:ss Z") /> 
9<#assign formattedTime=publicationDate?datetime?string(timeFormat) /> 
10<#assign publicationDate = publicationDate?date?string(format) /> 
11 
12<style> 
13    .psp-date-title--space-between { 
14        display: flex; 
15        justify-content: space-between; 
16        flex-direction: row; 
17        gap: 4px; 
18
19         
20    @media screen and (max-width: 768px){ 
21        .psp-date-title--space-between { 
22            flex-direction: column; 
23
24
25    .social-icon { 
26        width: 48px; 
27        height: 48px; 
28        background-size: cover; 
29        display: inline-block; 
30        transition: scale 0.3s ease; 
31
32    .social-icon:hover { 
33        scale: 1.2; 
34
35    .social-icon--facebook { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHBhdGggZD0iTTQyIDM3YTUgNSAwIDAgMS01IDVIMTFhNSA1IDAgMCAxLTUtNVYxMWE1IDUgMCAwIDEgNS01aDI2YTUgNSAwIDAgMSA1IDV2MjZ6IiBmaWxsPSIjM0Y1MUI1Ii8+PHBhdGggZD0iTTM0LjM2OCAyNUgzMXYxM2gtNVYyNWgtM3YtNGgzdi0yLjQxYy4wMDItMy41MDggMS40NTktNS41OSA1LjU5Mi01LjU5SDM1djRoLTIuMjg3QzMxLjEwNCAxNyAzMSAxNy42IDMxIDE4LjcyM1YyMWg0bC0uNjMyIDR6IiBmaWxsPSIjRkZGIi8+PC9zdmc+'); } 
36    .social-icon--whatsapp { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHZpZXdCb3g9IjAgMCA0OCA0OCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNC44NjggNDMuMzAzIDIuNjk0LTkuODM1YTE4Ljk0MSAxOC45NDEgMCAwIDEgLTIuNTM1LTkuNDg5Yy4wMDUtMTAuNDY1IDguNTIxLTE4Ljk3OSAxOC45ODctMTguOTc5YTE4Ljg2NyAxOC44NjcgMCAwIDEgMTMuNDMgNS41NjYgMTguODY2IDE4Ljg2NiAwIDAgMSA1LjU1NiAxMy40MjhjLS4wMDQgMTAuNDY1LTguNTIyIDE4Ljk4LTE4Ljk4NiAxOC45OC0uMDAxIDAgMCAwIDAgMGgtLjAwOGExOC45NjUgMTguOTY1IDAgMCAxIC05LjA3My0yLjMxMXoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtNC44NjggNDMuODAzYS40OTkuNDk5IDAgMCAxIC0uNDgyLS42MzFsMi42MzktOS42MzZhMTkuNDggMTkuNDggMCAwIDEgLTIuNDk3LTkuNTU2Yy4wMDQtMTAuNzQyIDguNzQ1LTE5LjQ4IDE5LjQ4Ni0xOS40OGExOS4zNjcgMTkuMzY3IDAgMCAxIDEzLjc4NCA1LjcxMyAxOS4zNjIgMTkuMzYyIDAgMCAxIDUuNzAyIDEzLjc4MWMtLjAwNCAxMC43NDEtOC43NDYgMTkuNDgtMTkuNDg2IDE5LjQ4YTE5LjUzNSAxOS41MzUgMCAwIDEgLTkuMTQ0LTIuMjc3bC05Ljg3NSAyLjU4OWEuNDU3LjQ1NyAwIDAgMSAtLjEyNy4wMTd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI0LjAxNCA1YTE4Ljg2NyAxOC44NjcgMCAwIDEgMTMuNDMgNS41NjYgMTguODY2IDE4Ljg2NiAwIDAgMSA1LjU1NiAxMy40MjhjLS4wMDQgMTAuNDY1LTguNTIyIDE4Ljk4LTE4Ljk4NiAxOC45OGgtLjAwOGExOC45NjUgMTguOTY1IDAgMCAxIC05LjA3My0yLjMxMWwtMTAuMDY1IDIuNjQgMi42OTQtOS44MzVhMTguOTQxIDE4Ljk0MSAwIDAgMSAtMi41MzUtOS40ODljLjAwNS0xMC40NjUgOC41MjEtMTguOTc5IDE4Ljk4Ny0xOC45NzltMC0xYy0xMS4wMTYgMC0xOS45ODIgOC45NjItMTkuOTg3IDE5Ljk3OWEyMC4wMSAyMC4wMSAwIDAgMCAyLjQ2MSA5LjYyMmwtMi41ODUgOS40MzlhLjk5OC45OTggMCAwIDAgMS4yMTkgMS4yMzFsOS42ODctMi41NGEyMC4wMjYgMjAuMDI2IDAgMCAwIDkuMTk3IDIuMjQ0YzExLjAyNCAwIDE5Ljk5LTguOTYzIDE5Ljk5NS0xOS45OGExOS44NTYgMTkuODU2IDAgMCAwIC01Ljg0OC0xNC4xMzUgMTkuODY5IDE5Ljg2OSAwIDAgMCAtMTQuMTM5LTUuODZ6IiBmaWxsPSIjY2ZkOGRjIi8+PHBhdGggZD0ibTM1LjE3NiAxMi44MzJhMTUuNjczIDE1LjY3MyAwIDAgMCAtMTEuMTU3LTQuNjI2Yy04LjcwNCAwLTE1Ljc4MyA3LjA3Ni0xNS43ODcgMTUuNzc0YTE1LjczOCAxNS43MzggMCAwIDAgMi40MTMgOC4zOTZsLjM3Ni41OTctMS41OTUgNS44MjEgNS45NzMtMS41NjYuNTc3LjM0MmExNS43NSAxNS43NSAwIDAgMCA4LjAzMiAyLjE5OWguMDA2YzguNjk4IDAgMTUuNzc3LTcuMDc3IDE1Ljc4LTE1Ljc3NmExNS42OCAxNS42OCAwIDAgMCAtNC42MTgtMTEuMTYxeiIgZmlsbD0iIzQwYzM1MSIvPjxwYXRoIGQ9Im0xOS4yNjggMTYuMDQ1Yy0uMzU1LS43OS0uNzI5LS44MDYtMS4wNjgtLjgyLS4yNzctLjAxMi0uNTkzLS4wMTEtLjkwOS0uMDExcy0uODMuMTE5LTEuMjY1LjU5NC0xLjY2MSAxLjYyMi0xLjY2MSAzLjk1NiAxLjcgNC41OSAxLjkzNyA0LjkwNiAzLjI4MiA1LjI1OSA4LjEwNCA3LjE2MWM0LjAwNyAxLjU4IDQuODIzIDEuMjY2IDUuNjkzIDEuMTg3czIuODA3LTEuMTQ3IDMuMjAyLTIuMjU1LjM5NS0yLjA1Ny4yNzctMi4yNTVjLS4xMTktLjE5OC0uNDM1LS4zMTYtLjkwOS0uNTU0cy0yLjgwNy0xLjM4NS0zLjI0Mi0xLjU0My0uNzUxLS4yMzctMS4wNjguMjM4Yy0uMzE2LjQ3NC0xLjIyNSAxLjU0My0xLjUwMiAxLjg1OS0uMjc3LjMxNy0uNTU0LjM1Ny0xLjAyOC4xMTlzLTIuMDAyLS43MzgtMy44MTUtMi4zNTRjLTEuNDEtMS4yNTctMi4zNjItMi44MS0yLjYzOS0zLjI4NS0uMjc3LS40NzQtLjAzLS43MzEuMjA4LS45NjguMjEzLS4yMTMuNDc0LS41NTQuNzEyLS44MzEuMjM3LS4yNzcuMzE2LS40NzUuNDc0LS43OTEuMTU4LS4zMTcuMDc5LS41OTQtLjA0LS44MzEuLTExNy0uMjM4LTEuMDM5LTIuNTg0LTEuNDYxLTMuNTIyeiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); } 
37    .social-icon--linkedin { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHBhdGggZD0iTTQyIDM3YTUgNSAwIDAgMS01IDVIMTFhNSA1IDAgMCAxLTUtNVYxMWE1IDUgMCAwIDEgNS01aDI2YTUgNSAwIDAgMSA1IDV2MjZ6IiBmaWxsPSIjMDI4OEQxIi8+PHBhdGggZD0iTTEyIDE5aDV2MTdoLTV6bTIuNDg1LTJoLS4wMjhDMTIuOTY1IDE3IDEyIDE1Ljg4OCAxMiAxNC40OTkgMTIgMTMuMDggMTIuOTk1IDEyIDE0LjUxNCAxMmMxLjUyMSAwIDIuNDU4IDEuMDggMi40ODYgMi40OTlDMTcgMTUuODg3IDE2LjAzNSAxNyAxNC40ODUgMTd6TTM2IDM2aC01di05LjA5OWMwLTIuMTk4LTEuMjI1LTMuNjk4LTMuMTkyLTMuNjk4LTEuNTAxIDAtMi4zMTMgMS4wMTItMi43MDcgMS45OS0uMTQ0LjM1LS4xMDEgMS4zMTgtLjEwMSAxLjgwN3Y5aC01VjE5aDV2Mi42MTZDMjUuNzIxIDIwLjUgMjYuODUgMTkgMjkuNzM4IDE5YzMuNTc4IDAgNi4yNjEgMi4yNSA2LjI2MSA3LjI3NEwzNiAzNnoiIGZpbGw9IiNGRkYiLz48L3N2Zz4='); } 
38    .social-icon--twitter { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCIgY2xpcC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMzggNDJIMTBhNCA0IDAgMCAxLTQtNFYxMGE0IDQgMCAwIDEgNC00aDI4YTQgNCAwIDAgMSA0IDR2MjhhNCA0IDAgMCAxLTQgNHoiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZmlsbD0iIzIxMjEyMSIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik0zNC4yNTcgMzRIMjcuODJMMTMuODI5IDE0aDYuNDM3em0tNS42Ny0xLjY5NmgyLjU2M0wxOS40OTkgMTUuNjk2aC0yLjU2M3oiLz48cGF0aCBkPSJNMTUuODY2IDM0bDcuMjAzLTguMzQ0LS45NDItMS4yNDlMMTMuODIzIDM0em04LjU4NC0xMi4yNzlsLjkwNSAxLjI4OUwzMy4xMzYgMTRoLTJ6Ii8+PC9nPjwvc3ZnPg=='); } 
39    .social-icon--instagram { 
40        --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M11.999 7.377a4.623 4.623 0 1 0 0 9.248a4.623 4.623 0 0 0 0-9.248m0 7.627a3.004 3.004 0 1 1 0-6.008a3.004 3.004 0 0 1 0 6.008'/%3E%3Ccircle cx='16.806' cy='7.207' r='1.078' fill='%23000'/%3E%3Cpath fill='%23000' d='M20.533 6.111A4.605 4.605 0 0 0 17.9 3.479a6.606 6.606 0 0 0-2.186-.42c-.963-.042-1.268-.054-3.71-.054s-2.755 0-3.71.054a6.554 6.554 0 0 0-2.184.42a4.6 4.6 0 0 0-2.633 2.632a6.585 6.585 0 0 0-.419 2.186c-.043.962-.056 1.267-.056 3.71c0 2.442 0 2.753.056 3.71c.015.748.156 1.486.419 2.187a4.61 4.61 0 0 0 2.634 2.632a6.584 6.584 0 0 0 2.185.45c.963.042 1.268.055 3.71.055s2.755 0 3.71-.055a6.615 6.615 0 0 0 2.186-.419a4.613 4.613 0 0 0 2.633-2.633c.263-.7.404-1.438.419-2.186c.043-.962.056-1.267.056-3.71s0-2.753-.056-3.71a6.581 6.581 0 0 0-.421-2.217m-1.218 9.532a5.043 5.043 0 0 1-.311 1.688a2.987 2.987 0 0 1-1.712 1.711a4.985 4.985 0 0 1-1.67.311c-.95.044-1.218.055-3.654.055c-2.438 0-2.687 0-3.655-.055a4.96 4.96 0 0 1-1.669-.311a2.985 2.985 0 0 1-1.719-1.711a5.08 5.08 0 0 1-.311-1.669c-.043-.95-.053-1.218-.053-3.654c0-2.437 0-2.686.053-3.655a5.038 5.038 0 0 1 .311-1.687c.305-.789.93-1.41 1.719-1.712a5.01 5.01 0 0 1 1.669-.311c.951-.043 1.218-.055 3.655-.055s2.687 0 3.654.055a4.96 4.96 0 0 1 1.67.311a2.991 2.991 0 0 1 1.712 1.712a5.08 5.08 0 0 1 .311 1.669c.043.951.054 1.218.054 3.655c0 2.436 0 2.698-.043 3.654z'/%3E%3C/svg%3E"); 
41        background-color: currentColor; 
42        -webkit-mask-image: var(--svg); 
43        -webkit-mask-size: 100% 100%; 
44
45</style> 
46 
47<div class="psp-date-title--space-between mb-5"> 
48    <div class="psp-date-title"> 
49        ${publicationDate} | Horário: ${formattedTime} 
50    </div> 
51    <div style="display: flex; gap: 16px;align-items:center;"> 
52        <span>Compartilhe:</span> 
53        <a class="mt-n1" target="_blank" href="https://api.whatsapp.com/send?text=${themeDisplay.getPortalURL() + themeDisplay.getURLCurrent()}"> 
54<svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 32 32" width="20px" height="20px"><path fill="#EC6608" fill-rule="evenodd" d="M 24.503906 7.503906 C 22.246094 5.246094 19.246094 4 16.050781 4 C 9.464844 4 4.101563 9.359375 4.101563 15.945313 C 4.097656 18.050781 4.648438 20.105469 5.695313 21.917969 L 4 28.109375 L 10.335938 26.445313 C 12.078125 27.398438 14.046875 27.898438 16.046875 27.902344 L 16.050781 27.902344 C 22.636719 27.902344 27.996094 22.542969 28 15.953125 C 28 12.761719 26.757813 9.761719 24.503906 7.503906 Z M 16.050781 25.882813 L 16.046875 25.882813 C 14.265625 25.882813 12.515625 25.402344 10.992188 24.5 L 10.628906 24.285156 L 6.867188 25.269531 L 7.871094 21.605469 L 7.636719 21.230469 C 6.640625 19.648438 6.117188 17.820313 6.117188 15.945313 C 6.117188 10.472656 10.574219 6.019531 16.054688 6.019531 C 18.707031 6.019531 21.199219 7.054688 23.074219 8.929688 C 24.949219 10.808594 25.980469 13.300781 25.980469 15.953125 C 25.980469 21.429688 21.523438 25.882813 16.050781 25.882813 Z M 21.496094 18.445313 C 21.199219 18.296875 19.730469 17.574219 19.457031 17.476563 C 19.183594 17.375 18.984375 17.328125 18.785156 17.625 C 18.585938 17.925781 18.015625 18.597656 17.839844 18.796875 C 17.667969 18.992188 17.492188 19.019531 17.195313 18.871094 C 16.894531 18.722656 15.933594 18.40625 14.792969 17.386719 C 13.90625 16.597656 13.304688 15.617188 13.132813 15.320313 C 12.957031 15.019531 13.113281 14.859375 13.261719 14.710938 C 13.398438 14.578125 13.5625 14.363281 13.710938 14.1875 C 13.859375 14.015625 13.910156 13.890625 14.011719 13.691406 C 14.109375 13.492188 14.058594 13.316406 13.984375 13.167969 C 13.910156 13.019531 13.3125 11.546875 13.0625 10.949219 C 12.820313 10.367188 12.574219 10.449219 12.390625 10.4375 C 12.21875 10.429688 12.019531 10.429688 11.820313 10.429688 C 11.621094 10.429688 11.296875 10.503906 11.023438 10.804688 C 10.75 11.101563 9.980469 11.824219 9.980469 13.292969 C 9.980469 14.761719 11.050781 16.183594 11.199219 16.382813 C 11.347656 16.578125 13.304688 19.59375 16.300781 20.886719 C 17.011719 21.195313 17.566406 21.378906 18 21.515625 C 18.714844 21.742188 19.367188 21.710938 19.882813 21.636719 C 20.457031 21.550781 21.648438 20.914063 21.898438 20.214844 C 22.144531 19.519531 22.144531 18.921875 22.070313 18.796875 C 21.996094 18.671875 21.796875 18.597656 21.496094 18.445313 Z"/></svg></a> 
55        <a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=${themeDisplay.getPortalURL() + themeDisplay.getURLCurrent()}"><i class="psp-icon-facebook"></i></a> 
56        <a target="_blank" href="https://twitter.com/intent/tweet?url=${themeDisplay.getPortalURL() + themeDisplay.getURLCurrent()}"><svg class="lexicon-icon lexicon-icon-twitter-x" role="presentation" viewBox="0 0 512 512"> 
57          <use xlink:href="/o/dialect-theme/images/clay/icons.svg#twitter-x"></use> 
58         </svg></a> 
59        <a target="_blank" href="https://www.linkedin.com/shareArticle?mini=true&url=${themeDisplay.getPortalURL() + themeDisplay.getURLCurrent()}"><i class="psp-icon-linkedin"></i></a> 
60    </div> 
61</div> 
62 
63<p class="psp-news-title mb-2"> 
64 ${title} 
65</p> 
66         
67<#if (description.getData())??> 
68 <div class="psp-news-description mb-5">${description.getData()}</div> 
69</#if> 
70 
71<#if (subtitle.getData())??> 
72 <div class="psp-news-description mb-5">${subtitle.getData()}</div> 
73</#if> 
74 
75<#-- Apenas renderiza a imagem principal se ela existir (Sem Fallback) --> 
76<#if (image.getData())?? && image.getData() != ""> 
77    <img class="mb-4" alt="${image.getAttribute('alt')}" data-fileentryid="${image.getAttribute('fileEntryId')}" src="${image.getData()}" loading="lazy" decoding="async" /> 
78</#if> 
79     
80<#-- ========================================== --> 
81<#-- LÓGICA DO SLIDER ANTES/DEPOIS              --> 
82<#-- ========================================== --> 
83 
84<#assign conteudoFinal = (content.getData())!"" /> 
85 
86<#-- O servidor só processa o HTML/CSS se a tag for encontrada no texto --> 
87<#if conteudoFinal?contains("[[antes/depois]]")> 
88    <#-- Mantendo fallback apenas para o Slider --> 
89    <#assign fallbackImgAntes = "https://placehold.co/800x500/eeeeee/999999?text=Sem+Imagem+Antes" /> 
90    <#assign fallbackImgDepois = "https://placehold.co/800x500/cccccc/666666?text=Sem+Imagem+Depois" /> 
91 
92    <#assign imgAntes = image_before.getData()!fallbackImgAntes /> 
93    <#if imgAntes == ""><#assign imgAntes = fallbackImgAntes /></#if> 
94 
95    <#assign imgDepois = image_after.getData()!fallbackImgDepois /> 
96    <#if imgDepois == ""><#assign imgDepois = fallbackImgDepois /></#if> 
97 
98    <#assign sliderHtml> 
99        <div class="cx-slider-wrapper"> 
100            <style> 
101                .cx-slider-container { --pos: 50%; position: relative; width: 100%; max-width: 800px; margin: 2rem auto; border-radius: 12px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.15); display: flex; } 
102                .cx-img-panel { width: 100%; display: flex; } 
103                .cx-img-panel img { width: 100%; height: auto; object-fit: cover; pointer-events: none; display: block; } 
104                .cx-img-before { position: absolute; inset: 0; clip-path: polygon(0 0, var(--pos) 0, var(--pos) 100%, 0 100%); } 
105                .cx-label { position: absolute; top: 20px; padding: 6px 14px; background: rgba(0,0,0,0.6); color: #fff; border-radius: 20px; font-family: sans-serif; font-size: 13px; font-weight: bold; pointer-events: none; z-index: 5; } 
106                .cx-label-before { left: 20px; } .cx-label-after { right: 20px; } 
107                .cx-slider { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; z-index: 10; cursor: ew-resize; margin: 0; } 
108                .cx-handle { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 4px; background: #fff; transform: translateX(-50%); pointer-events: none; z-index: 8; box-shadow: 0 0 10px rgba(0,0,0,0.4); } 
109                .cx-handle-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 40px; height: 40px; background: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 10px rgba(0,0,0,0.3); } 
110                .cx-handle-btn svg { width: 24px; height: 24px; color: #333; } 
111            </style> 
112            <div class="cx-slider-container" style="--pos: 50%;"> 
113                <div class="cx-img-panel cx-img-after"> 
114                    <img src="${imgDepois}" alt="Imagem Depois" loading="lazy" decoding="async" /> 
115                    <span class="cx-label cx-label-after">Depois</span> 
116                </div> 
117                <div class="cx-img-panel cx-img-before"> 
118                    <img src="${imgAntes}" alt="Imagem Antes" loading="lazy" decoding="async" /> 
119                    <span class="cx-label cx-label-before">Antes</span> 
120                </div> 
121                <input type="range" min="0" max="100" value="50" class="cx-slider" aria-label="Controlador de comparação antes e depois" oninput="this.parentElement.style.setProperty('--pos', this.value + '%')"> 
122                <div class="cx-handle"><div class="cx-handle-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6M9 18l6-6-6-6" /></svg></div></div> 
123            </div> 
124        </div> 
125    </#assign> 
126 
127    <#assign conteudoFinal = conteudoFinal?replace("<p>[[antes/depois]]</p>", sliderHtml) /> 
128    <#assign conteudoFinal = conteudoFinal?replace("[[antes/depois]]", sliderHtml) /> 
129</#if> 
130 
131<div class="psp-news-text"> 
132   ${conteudoFinal} 
133</div> 
134 
135<#assign articleId = .vars["reserved-article-id"].data /> 
136 
137<div class="psp-section-title mt-6 mb-4 d-none" data-article-id="${articleId}"> 
138    <div class="psp-section-title__main mr-5"> 
139        <div class="psp-section-title__icon text-7 mr-5"><i class="material-icon">collections</i></div> 
140        <div class="psp-section-title__text text-6 font-weight-semi-bold"> 
141            <div>Galeria de imagens</div> 
142        </div> 
143    </div> 
144    <div class="psp-section-title__divider d-none d-sm-block"></div> 
145</div> 
146 
147<div class="pswp-gallery psp-gallery-${randomNamespace}" data-input-gallery></div> 
148 
149<script> 
150    (function() { 
151        const articleId = document.querySelector('[data-article-id]').getAttribute('data-article-id'); 
152        const groupId = themeDisplay.getSiteGroupId(); 
153        const galleryContainer = document.querySelector('[data-input-gallery]'); 
154 
155        async function fetchArticle() { 
156            try { 
157                const article = await fetch(`/o/headless-delivery/v1.0/sites/${groupId}/structured-contents/by-key/${articleId}`); 
158                if (!article.ok) throw new Error("Erro ao buscar a notícia"); 
159                const data = await article.json(); 
160                renderArticle(data); 
161            } catch (error) { 
162                console.error("[Galeria] Falha ao carregar artigo base:", error); 
163
164
165 
166        async function fetchDoc(id) { 
167            try { 
168                const doc = await fetch('/o/headless-delivery/v1.0/documents/' + id); 
169                if (!doc.ok) return null; 
170                return await doc.json(); 
171            } catch (error) { 
172                console.error("[Galeria] Falha ao carregar a imagem com ID:", id); 
173                return null; 
174
175
176 
177        async function renderArticle(data) { 
178            if (!data.relatedContents || data.relatedContents.length === 0) return; 
179             
180            document.querySelector(`[data-article-id="${articleId}"]`).classList.remove('d-none'); 
181 
182            const ids = data.relatedContents.map(object => object.id); 
183 
184            // Fetching paralelo de alta performance 
185            const docs = await Promise.all(ids.map(id => fetchDoc(id))); 
186             
187            const fragment = document.createDocumentFragment(); 
188            docs.forEach(doc => { 
189                if (doc) renderImage(doc, fragment); 
190            }); 
191             
192            galleryContainer.appendChild(fragment); 
193            initLightbox(); 
194
195 
196        function removeStringDownload(stringToRemove){ 
197            return stringToRemove.replace(/(\?|&)download=true/g, '$1download=false'); 
198
199 
200        function renderImage(img, container) { 
201            if (!img.contentUrl) return; 
202                         
203            const imgURL = removeStringDownload(img.contentUrl); 
204 
205            const galleryLink = document.createElement('a'); 
206            galleryLink.setAttribute('title', 'Link para a imagem da galeria'); 
207            galleryLink.setAttribute('href', imgURL); 
208            galleryLink.setAttribute('data-pswp-width', '1200'); 
209            galleryLink.setAttribute('data-pswp-height', '800'); 
210            galleryLink.setAttribute('target', '_blank'); 
211 
212            const picture = document.createElement('picture'); 
213            const smallerMedia = document.createElement('source'); 
214            smallerMedia.setAttribute('media', '(max-width:300px)'); 
215            smallerMedia.setAttribute('srcset', img.contentUrl); 
216             
217            const biggerMedia = document.createElement('source'); 
218            biggerMedia.setAttribute('media', '(max-width:1000px) and (min-width:300px)'); 
219            biggerMedia.setAttribute('srcset', img.contentUrl); 
220             
221            const imgElement = document.createElement('img'); 
222            imgElement.setAttribute('alt', 'Imagem da galeria'); 
223            imgElement.src = imgURL; 
224            imgElement.setAttribute('loading', 'lazy');  
225            imgElement.setAttribute('decoding', 'async'); 
226             
227            picture.append(smallerMedia, biggerMedia, imgElement); 
228            galleryLink.appendChild(picture); 
229 
230            const captionContentDiv = document.createElement('div'); 
231            captionContentDiv.classList.add('hidden-caption-content'); 
232 
233            if (Array.isArray(img.customFields)) { 
234                img.customFields.forEach(cf => { 
235                    if (cf.name === "Descrição Imagem" && cf.customValue.data !== "") { 
236                        captionContentDiv.innerHTML += `<span>${cf.customValue.data}</span><br>`; 
237
238                    if (cf.name === "Crédito Imagem" && cf.customValue.data !== "") { 
239                        captionContentDiv.innerHTML += `<span>Fotos de: ${cf.customValue.data}</span>`; 
240
241                }); 
242
243 
244            galleryLink.appendChild(captionContentDiv); 
245            container.appendChild(galleryLink); 
246
247 
248        function initLightbox() { 
249            var galleryImageElem = document.querySelector(".psp-gallery-" + "${randomNamespace}"); 
250 
251            if (galleryImageElem && typeof PSP !== 'undefined') { 
252                const lightbox = new PSP.vendors.PhotoSwipeLightbox({ 
253                    gallery: '.psp-gallery-' + "${randomNamespace}", 
254                    children: 'a', 
255                    pswpModule: () => import('https://unpkg.com/photoswipe'), 
256                }); 
257 
258                lightbox.on('uiRegister', function() { 
259                    lightbox.pswp.ui.registerElement({ 
260                        name: 'custom-caption', 
261                        order: 9, 
262                        isButton: false, 
263                        appendTo: 'root', 
264                        html: 'Caption text', 
265                        onInit: (el, pswp) => { 
266                            lightbox.pswp.on('change', () => { 
267                                const currSlideElement = lightbox.pswp.currSlide.data.element; 
268                                let captionHTML = ''; 
269                                if (currSlideElement) { 
270                                    const hiddenCaption = currSlideElement.querySelector('.hidden-caption-content'); 
271                                    captionHTML = hiddenCaption ? hiddenCaption.innerHTML : currSlideElement.querySelector('img').getAttribute('alt'); 
272
273                                el.classList.toggle('d-none', !captionHTML.trim()); 
274                                el.innerHTML = captionHTML || ''; 
275                            }); 
276
277                    }); 
278                }); 
279                lightbox.init(); 
280
281
282 
283        fetchArticle(); 
284    })(); 
285</script>