{"id":42,"date":"2026-04-29T10:47:03","date_gmt":"2026-04-29T13:47:03","guid":{"rendered":"https:\/\/sites.williarts.com.br\/catedral\/?page_id=42"},"modified":"2026-05-12T17:35:49","modified_gmt":"2026-05-12T20:35:49","slug":"fotos","status":"publish","type":"page","link":"https:\/\/sites.williarts.com.br\/catedral\/fotos\/","title":{"rendered":"Fotos"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.27.6&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;]\r\n        <template id=\"photo-card-template\">\r\n        <a href=\"#\" class=\"photo-card\">\r\n            <img decoding=\"async\" src=\"\" alt=\"\">\r\n            <span class='photo-date'>Data<\/span>\r\n            <span class='photo-title'>Titulo<\/span>\r\n        <\/a>\r\n    <\/template>\r\n        <template id=\"spinner-template\">\r\n        <div class=\"spinner-container\">\r\n            <div class=\"spinner-overlay\">\r\n                <div class=\"spinner\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/template>\r\n\r\n    <div id=\"spinner-container\"><\/div>\r\n\r\n    <script>\r\n        const spinnerContainer = document.querySelector(\"#spinner-container\")\r\n        const spinnerTemplate = document.querySelector(\"#spinner-template\");\r\n\r\n        const createSpinner = () => {\r\n            const fragment = spinnerTemplate.content.cloneNode(true);\r\n            spinnerContainer.appendChild(fragment);\r\n        }\r\n\r\n        const removeSpinner = () => {\r\n            spinnerContainer.innerHTML = '';\r\n        }\r\n    <\/script>\r\n    <div class=\"breadcrumb-container\" style=\"margin-bottom: 20px; font-weight: bold; font-size: 24px;\"><\/div>\r\n    <div class=\"gallery-container\">\r\n    <\/div>\r\n    <div class=\"gallery-footer\">\r\n        <div><\/div>\r\n            <div id=\"pagination_6a35c3698ec11\" class=\"pagination-container\"><\/div>\r\n\r\n    <script>\r\n        document.addEventListener(\"DOMContentLoaded\", () => {\r\n            const paginationContainer = document.querySelector(\"#pagination_6a35c3698ec11\");\r\n\r\n            const createPagination = (totalPages, currentPage, onPageChange) => {\r\n                paginationContainer.innerHTML = \"\";\r\n\r\n                const createButton = (page) => {\r\n                    const button = document.createElement(\"button\");\r\n                    button.textContent = page;\r\n\r\n                    if (page === currentPage) {\r\n                        button.disabled = true;\r\n                        button.classList.add(\"active\");\r\n                    }\r\n\r\n                    button.addEventListener('click', (e) => {\r\n                        e.preventDefault();\r\n                        onPageChange(page);\r\n                    });\r\n\r\n                    return button;\r\n                };\r\n\r\n                const createDots = () => {\r\n                    const span = document.createElement(\"span\");\r\n                    span.textContent = \"...\";\r\n                    return span;\r\n                };\r\n\r\n                const createNavButton = (text, isPrev, targetPage, disabled) => {\r\n                    const button = document.createElement(\"button\");\r\n                    button.classList.add(\"nav-btn\");\r\n                    if (disabled) {\r\n                        button.disabled = true;\r\n                    }\r\n\r\n                    const container = document.createElement(\"div\");\r\n                    container.classList.add(\"nav-btn-content\");\r\n\r\n                    const icon = document.createElement(\"span\");\r\n                    icon.classList.add(\"nav-btn-icon\");\r\n                    icon.innerHTML = isPrev ?\r\n                        `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"><\/line><polyline points=\"12 19 5 12 12 5\"><\/polyline><\/svg>` :\r\n                        `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"><\/line><polyline points=\"12 5 19 12 12 19\"><\/polyline><\/svg>`;\r\n\r\n                    const spanText = document.createElement(\"span\");\r\n                    spanText.textContent = text;\r\n                    spanText.classList.add(\"nav-btn-text\");\r\n\r\n                    if (isPrev) {\r\n                        container.appendChild(icon);\r\n                        container.appendChild(spanText);\r\n                    } else {\r\n                        container.appendChild(spanText);\r\n                        container.appendChild(icon);\r\n                    }\r\n\r\n                    button.appendChild(container);\r\n\r\n                    if (!disabled) {\r\n                        button.addEventListener('click', (e) => {\r\n                            e.preventDefault();\r\n                            onPageChange(targetPage);\r\n                        });\r\n                    }\r\n\r\n                    return button;\r\n                };\r\n\r\n                \/\/ ANTERIOR\r\n                paginationContainer.appendChild(createNavButton(\"ANTERIOR\", true, currentPage - 1, currentPage === 1));\r\n\r\n                paginationContainer.appendChild(createButton(1));\r\n\r\n                const range = 1;\r\n                let start = Math.max(2, currentPage - range);\r\n                let end = Math.min(totalPages - 1, currentPage + range);\r\n\r\n                if (start > 2) {\r\n                    paginationContainer.appendChild(createDots());\r\n                }\r\n\r\n                for (let i = start; i <= end; i++) {\r\n                    paginationContainer.appendChild(createButton(i));\r\n                }\r\n\r\n                if (end < totalPages - 1) {\r\n                    paginationContainer.appendChild(createDots());\r\n                }\r\n\r\n                if (totalPages > 1) {\r\n                    paginationContainer.appendChild(createButton(totalPages));\r\n                }\r\n\r\n                \/\/ PR\u00d3XIMO\r\n                paginationContainer.appendChild(createNavButton(\"PR\u00d3XIMO\", false, currentPage + 1, currentPage === totalPages || totalPages === 0));\r\n            };\r\n\r\n            \/\/ exp\u00f5e globalmente (pra outros scripts usarem)\r\n            window.createPagination = createPagination;\r\n        });\r\n    <\/script>\r\n\r\n    <\/div>\r\n\r\n    <script>\r\n        document.addEventListener(\"DOMContentLoaded\", () => {\r\n            const galleryContainer = document.querySelector(\".gallery-container\");\r\n            const photoCardTemplate = document.querySelector(\"#photo-card-template\");\r\n            const paginationContainer = document.querySelector(\".pagination-container\");\r\n            const breadcrumbContainer = document.querySelector('.breadcrumb-container');\r\n            const siteUrl = 'https:\/\/sites.williarts.com.br\/catedral';\r\n\r\n            const baseGalleryUrl = '\/catedral\/fotos\/';\r\n            \/\/ API Service (Single Responsibility)\r\n            const Api = {\r\n                async fetch(endpoint) {\r\n                    try {\r\n                        const response = await fetch(`${siteUrl}\/wp-json\/api\/v1\/${endpoint}`);\r\n                        return await response.json();\r\n                    } catch (error) {\r\n                        console.error(\"Error fetching data:\", error);\r\n                        return null;\r\n                    }\r\n                }\r\n            };\r\n\r\n            const Router = {\r\n                set(path) {\r\n                    window.history.pushState({}, '', path);\r\n                }\r\n            }\r\n\r\n            \/\/ Factory Pattern for UI Cards\r\n            const CardFactory = {\r\n                _createBase(data) {\r\n                    const fragment = photoCardTemplate.content.cloneNode(true);\r\n                    const card = fragment.querySelector(\".photo-card\");\r\n                    const img = card.querySelector(\"img\");\r\n                    const spanDate = card.querySelector(\".photo-date\");\r\n                    const spanTitle = card.querySelector(\".photo-title\");\r\n\r\n                    spanDate.textContent = data.year || data.date;\r\n                    spanTitle.textContent = data.title;\r\n                    img.src = data.photo || '';\r\n                    img.alt = data.title || '';\r\n                    card.classList.add(\"fade-in\");\r\n\r\n                    return card;\r\n                },\r\n                years(data) {\r\n                    const card = document.createElement('a');\r\n                    card.dataset.year = data;\r\n                    card.classList.add('years-cards', 'fade-in');\r\n                    card.innerHTML = `<span>${data}<\/span>`;\r\n                    return card;\r\n                },\r\n                albums(data) {\r\n                    const card = this._createBase(data);\r\n\r\n                    card.dataset.id = data.id;\r\n                    card.dataset.year = data.year;\r\n                    card.dataset.title = data.title;\r\n\r\n                    card.classList.add(\"albums-cards\");\r\n\r\n                    \/\/ card.href = \"#\";\r\n                    \r\n                    return card;\r\n                },\r\n                photos(data) {\r\n                    const card = this._createBase(data);\r\n                    card.href = data.photo;\r\n                    card.style.backgroundColor = \"#fff\";\r\n                    return card;\r\n                }\r\n            };\r\n\r\n            \/\/ View Manager applying Strategy\/Template pattern\r\n            const GalleryView = {\r\n                renderEmpty() {\r\n                    galleryContainer.className = 'gallery-container empty fade-in';\r\n                    galleryContainer.innerHTML = '<div class=\"empty-state\">Nenhuma foto encontrada<\/div>';\r\n                    removeSpinner();\r\n                },\r\n\r\n                async load({\r\n                    endpoint,\r\n                    itemsKey,\r\n                    viewType,\r\n                    breadcrumbHTML,\r\n                    page,\r\n                    onPaginate\r\n                }) {\r\n                    if (galleryContainer.hasChildNodes()) galleryContainer.classList.add(\"hidden\");\r\n\r\n                    breadcrumbContainer.innerHTML = breadcrumbHTML;\r\n                    paginationContainer.innerHTML = '';\r\n                    createSpinner();\r\n\r\n                    const data = await Api.fetch(`${endpoint}?page=${page}`);\r\n                    if (!data || !data[itemsKey] || data[itemsKey].length === 0) {\r\n                        this.renderEmpty();\r\n                        return;\r\n                    }\r\n\r\n                    galleryContainer.innerHTML = '';\r\n                    window.createPagination(data.totalPages, page, onPaginate);\r\n\r\n                    galleryContainer.className = `gallery-container ${viewType === 'years' ? 'year' : 'photo'} hidden`;\r\n\r\n                    data[itemsKey].forEach(item => {\r\n                        galleryContainer.appendChild(CardFactory[viewType](item));\r\n                    });\r\n\r\n                    galleryContainer.classList.remove('hidden');\r\n                    removeSpinner();\r\n                }\r\n            };\r\n\r\n            \/\/ Application Controller\r\n            const App = {\r\n                updateUrl(path) {\r\n                    window.history.pushState({}, '', path);\r\n                },\r\n                loadYears(page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: 'photos\/years',\r\n                        itemsKey: 'years',\r\n                        viewType: 'years',\r\n                        breadcrumbHTML: '',\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadYears(newPage)\r\n                    });\r\n                },\r\n                loadAlbums(year, page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}${year}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: `photos\/albums\/${year}`,\r\n                        itemsKey: 'albums',\r\n                        viewType: 'albums',\r\n                        breadcrumbHTML: `<a href=\"#\" class=\"breadcrumb-home\" style=\"text-decoration: none;\">Anos<\/a> &gt; <span>${year}<\/span>`,\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadAlbums(year, newPage)\r\n                    });\r\n                },\r\n                loadPhotos(albumId, year, title, page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}${year}\/${albumId}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: `photos\/album\/${albumId}`,\r\n                        itemsKey: 'photos',\r\n                        viewType: 'photos',\r\n                        breadcrumbHTML: `<a href=\"#\" class=\"breadcrumb-home\" style=\"text-decoration: none;\">Anos<\/a> &gt; <a href=\"#\" class=\"breadcrumb-year\" data-year=\"${year}\" style=\"text-decoration: none;\">${year}<\/a> &gt; <span>${title}<\/span>`,\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadPhotos(albumId, year, title, newPage)\r\n                    });\r\n                }\r\n            };\r\n\r\n            \/\/ Modal Service (Singleton)\r\n            const ModalService = {\r\n                init() {\r\n                    let modal = document.querySelector('.photo-modal');\r\n                    if (!modal) {\r\n                        modal = document.createElement('div');\r\n                        modal.classList.add('photo-modal', 'hidden');\r\n                        modal.innerHTML = `\r\n                            <div class=\"photo-modal-overlay\"><\/div>\r\n                            <div class=\"photo-modal-content\">\r\n                                <button class=\"photo-modal-close\">&times;<\/button>\r\n                                <img decoding=\"async\" src=\"\" alt=\"\" \/>\r\n                            <\/div>\r\n                        `;\r\n                        document.body.appendChild(modal);\r\n\r\n                        modal.querySelector('.photo-modal-close').addEventListener('click', () => this.close());\r\n                        modal.querySelector('.photo-modal-overlay').addEventListener('click', () => this.close());\r\n                    }\r\n                    this.modalElement = modal;\r\n                },\r\n                open(imgSrc, imgAlt) {\r\n                    if (!this.modalElement) this.init();\r\n                    const img = this.modalElement.querySelector('img');\r\n                    img.src = imgSrc;\r\n                    img.alt = imgAlt || '';\r\n                    this.modalElement.classList.remove('hidden');\r\n                },\r\n                close() {\r\n                    if (!this.modalElement) return;\r\n                    this.modalElement.classList.add('hidden');\r\n                    this.modalElement.querySelector('img').src = '';\r\n                }\r\n            };\r\n\r\n            \/\/ Event Delegation Handler\r\n            document.addEventListener(\"click\", (e) => {\r\n                const breadcrumbHome = e.target.closest('.breadcrumb-home');\r\n                if (breadcrumbHome) {\r\n                    e.preventDefault();\r\n                    App.loadYears();\r\n                    return;\r\n                }\r\n\r\n                const breadcrumbYear = e.target.closest('.breadcrumb-year');\r\n                if (breadcrumbYear) {\r\n                    e.preventDefault();\r\n                    App.loadAlbums(breadcrumbYear.dataset.year);\r\n                    return;\r\n                }\r\n\r\n                const yearCard = e.target.closest(\".years-cards\");\r\n                if (yearCard) {\r\n                    e.preventDefault();\r\n                    App.loadAlbums(yearCard.dataset.year);\r\n                    return;\r\n                }\r\n\r\n                const albumCard = e.target.closest(\".albums-cards\");\r\n                if (albumCard) {\r\n                    e.preventDefault();\r\n                    App.loadPhotos(albumCard.dataset.id, albumCard.dataset.year, albumCard.dataset.title);\r\n                    return;\r\n                }\r\n\r\n                const photoCard = e.target.closest(\".photo-card\");\r\n                if (photoCard) {\r\n                    e.preventDefault();\r\n                    const img = photoCard.querySelector(\"img\");\r\n                    if (img) ModalService.open(img.src, img.alt);\r\n                }\r\n            });\r\n\r\n            \/\/ Initialize\r\n            const pathParts = window.location.pathname\r\n                .split('\/')\r\n                .filter(Boolean);\r\n\r\n            const fotosIndex = pathParts.indexOf('fotos');\r\n\r\n            if (fotosIndex === -1) {\r\n                App.loadYears();\r\n                return;\r\n            }\r\n\r\n            const params = pathParts.slice(fotosIndex + 1);\r\n\r\n            const paramStrategy = {\r\n                0: () => App.loadYears(),\r\n                1: () => App.loadAlbums(params[0]),\r\n                2: () => App.loadPhotos(params[1], params[0], '', 1, false)\r\n            };\r\n\r\n            (paramStrategy[params.length] || paramStrategy[0])();\r\n\r\n        });\r\n    <\/script>\r\n[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"\r\n        <template id=\"photo-card-template\">\r\n        <a href=\"#\" class=\"photo-card\">\r\n            <img decoding=\"async\" src=\"\" alt=\"\">\r\n            <span class='photo-date'>Data<\/span>\r\n            <span class='photo-title'>Titulo<\/span>\r\n        <\/a>\r\n    <\/template>\r\n        <template id=\"spinner-template\">\r\n        <div class=\"spinner-container\">\r\n            <div class=\"spinner-overlay\">\r\n                <div class=\"spinner\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/template>\r\n\r\n    <div id=\"spinner-container\"><\/div>\r\n\r\n    <script>\r\n        const spinnerContainer = document.querySelector(\"#spinner-container\")\r\n        const spinnerTemplate = document.querySelector(\"#spinner-template\");\r\n\r\n        const createSpinner = () => {\r\n            const fragment = spinnerTemplate.content.cloneNode(true);\r\n            spinnerContainer.appendChild(fragment);\r\n        }\r\n\r\n        const removeSpinner = () => {\r\n            spinnerContainer.innerHTML = '';\r\n        }\r\n    <\/script>\r\n    <div class=\"breadcrumb-container\" style=\"margin-bottom: 20px; font-weight: bold; font-size: 24px;\"><\/div>\r\n    <div class=\"gallery-container\">\r\n    <\/div>\r\n    <div class=\"gallery-footer\">\r\n        <div><\/div>\r\n            <div id=\"pagination_6a35c369999f3\" class=\"pagination-container\"><\/div>\r\n\r\n    <script>\r\n        document.addEventListener(\"DOMContentLoaded\", () => {\r\n            const paginationContainer = document.querySelector(\"#pagination_6a35c369999f3\");\r\n\r\n            const createPagination = (totalPages, currentPage, onPageChange) => {\r\n                paginationContainer.innerHTML = \"\";\r\n\r\n                const createButton = (page) => {\r\n                    const button = document.createElement(\"button\");\r\n                    button.textContent = page;\r\n\r\n                    if (page === currentPage) {\r\n                        button.disabled = true;\r\n                        button.classList.add(\"active\");\r\n                    }\r\n\r\n                    button.addEventListener('click', (e) => {\r\n                        e.preventDefault();\r\n                        onPageChange(page);\r\n                    });\r\n\r\n                    return button;\r\n                };\r\n\r\n                const createDots = () => {\r\n                    const span = document.createElement(\"span\");\r\n                    span.textContent = \"...\";\r\n                    return span;\r\n                };\r\n\r\n                const createNavButton = (text, isPrev, targetPage, disabled) => {\r\n                    const button = document.createElement(\"button\");\r\n                    button.classList.add(\"nav-btn\");\r\n                    if (disabled) {\r\n                        button.disabled = true;\r\n                    }\r\n\r\n                    const container = document.createElement(\"div\");\r\n                    container.classList.add(\"nav-btn-content\");\r\n\r\n                    const icon = document.createElement(\"span\");\r\n                    icon.classList.add(\"nav-btn-icon\");\r\n                    icon.innerHTML = isPrev ?\r\n                        `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"><\/line><polyline points=\"12 19 5 12 12 5\"><\/polyline><\/svg>` :\r\n                        `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"><\/line><polyline points=\"12 5 19 12 12 19\"><\/polyline><\/svg>`;\r\n\r\n                    const spanText = document.createElement(\"span\");\r\n                    spanText.textContent = text;\r\n                    spanText.classList.add(\"nav-btn-text\");\r\n\r\n                    if (isPrev) {\r\n                        container.appendChild(icon);\r\n                        container.appendChild(spanText);\r\n                    } else {\r\n                        container.appendChild(spanText);\r\n                        container.appendChild(icon);\r\n                    }\r\n\r\n                    button.appendChild(container);\r\n\r\n                    if (!disabled) {\r\n                        button.addEventListener('click', (e) => {\r\n                            e.preventDefault();\r\n                            onPageChange(targetPage);\r\n                        });\r\n                    }\r\n\r\n                    return button;\r\n                };\r\n\r\n                \/\/ ANTERIOR\r\n                paginationContainer.appendChild(createNavButton(\"ANTERIOR\", true, currentPage - 1, currentPage === 1));\r\n\r\n                paginationContainer.appendChild(createButton(1));\r\n\r\n                const range = 1;\r\n                let start = Math.max(2, currentPage - range);\r\n                let end = Math.min(totalPages - 1, currentPage + range);\r\n\r\n                if (start > 2) {\r\n                    paginationContainer.appendChild(createDots());\r\n                }\r\n\r\n                for (let i = start; i <= end; i++) {\r\n                    paginationContainer.appendChild(createButton(i));\r\n                }\r\n\r\n                if (end < totalPages - 1) {\r\n                    paginationContainer.appendChild(createDots());\r\n                }\r\n\r\n                if (totalPages > 1) {\r\n                    paginationContainer.appendChild(createButton(totalPages));\r\n                }\r\n\r\n                \/\/ PR\u00d3XIMO\r\n                paginationContainer.appendChild(createNavButton(\"PR\u00d3XIMO\", false, currentPage + 1, currentPage === totalPages || totalPages === 0));\r\n            };\r\n\r\n            \/\/ exp\u00f5e globalmente (pra outros scripts usarem)\r\n            window.createPagination = createPagination;\r\n        });\r\n    <\/script>\r\n\r\n    <\/div>\r\n\r\n    <script>\r\n        document.addEventListener(\"DOMContentLoaded\", () => {\r\n            const galleryContainer = document.querySelector(\".gallery-container\");\r\n            const photoCardTemplate = document.querySelector(\"#photo-card-template\");\r\n            const paginationContainer = document.querySelector(\".pagination-container\");\r\n            const breadcrumbContainer = document.querySelector('.breadcrumb-container');\r\n            const siteUrl = 'https:\/\/sites.williarts.com.br\/catedral';\r\n\r\n            const baseGalleryUrl = '\/catedral\/fotos\/';\r\n            \/\/ API Service (Single Responsibility)\r\n            const Api = {\r\n                async fetch(endpoint) {\r\n                    try {\r\n                        const response = await fetch(`${siteUrl}\/wp-json\/api\/v1\/${endpoint}`);\r\n                        return await response.json();\r\n                    } catch (error) {\r\n                        console.error(\"Error fetching data:\", error);\r\n                        return null;\r\n                    }\r\n                }\r\n            };\r\n\r\n            const Router = {\r\n                set(path) {\r\n                    window.history.pushState({}, '', path);\r\n                }\r\n            }\r\n\r\n            \/\/ Factory Pattern for UI Cards\r\n            const CardFactory = {\r\n                _createBase(data) {\r\n                    const fragment = photoCardTemplate.content.cloneNode(true);\r\n                    const card = fragment.querySelector(\".photo-card\");\r\n                    const img = card.querySelector(\"img\");\r\n                    const spanDate = card.querySelector(\".photo-date\");\r\n                    const spanTitle = card.querySelector(\".photo-title\");\r\n\r\n                    spanDate.textContent = data.year || data.date;\r\n                    spanTitle.textContent = data.title;\r\n                    img.src = data.photo || '';\r\n                    img.alt = data.title || '';\r\n                    card.classList.add(\"fade-in\");\r\n\r\n                    return card;\r\n                },\r\n                years(data) {\r\n                    const card = document.createElement('a');\r\n                    card.dataset.year = data;\r\n                    card.classList.add('years-cards', 'fade-in');\r\n                    card.innerHTML = `<span>${data}<\/span>`;\r\n                    return card;\r\n                },\r\n                albums(data) {\r\n                    const card = this._createBase(data);\r\n\r\n                    card.dataset.id = data.id;\r\n                    card.dataset.year = data.year;\r\n                    card.dataset.title = data.title;\r\n\r\n                    card.classList.add(\"albums-cards\");\r\n\r\n                    \/\/ card.href = \"#\";\r\n                    \r\n                    return card;\r\n                },\r\n                photos(data) {\r\n                    const card = this._createBase(data);\r\n                    card.href = data.photo;\r\n                    card.style.backgroundColor = \"#fff\";\r\n                    return card;\r\n                }\r\n            };\r\n\r\n            \/\/ View Manager applying Strategy\/Template pattern\r\n            const GalleryView = {\r\n                renderEmpty() {\r\n                    galleryContainer.className = 'gallery-container empty fade-in';\r\n                    galleryContainer.innerHTML = '<div class=\"empty-state\">Nenhuma foto encontrada<\/div>';\r\n                    removeSpinner();\r\n                },\r\n\r\n                async load({\r\n                    endpoint,\r\n                    itemsKey,\r\n                    viewType,\r\n                    breadcrumbHTML,\r\n                    page,\r\n                    onPaginate\r\n                }) {\r\n                    if (galleryContainer.hasChildNodes()) galleryContainer.classList.add(\"hidden\");\r\n\r\n                    breadcrumbContainer.innerHTML = breadcrumbHTML;\r\n                    paginationContainer.innerHTML = '';\r\n                    createSpinner();\r\n\r\n                    const data = await Api.fetch(`${endpoint}?page=${page}`);\r\n                    if (!data || !data[itemsKey] || data[itemsKey].length === 0) {\r\n                        this.renderEmpty();\r\n                        return;\r\n                    }\r\n\r\n                    galleryContainer.innerHTML = '';\r\n                    window.createPagination(data.totalPages, page, onPaginate);\r\n\r\n                    galleryContainer.className = `gallery-container ${viewType === 'years' ? 'year' : 'photo'} hidden`;\r\n\r\n                    data[itemsKey].forEach(item => {\r\n                        galleryContainer.appendChild(CardFactory[viewType](item));\r\n                    });\r\n\r\n                    galleryContainer.classList.remove('hidden');\r\n                    removeSpinner();\r\n                }\r\n            };\r\n\r\n            \/\/ Application Controller\r\n            const App = {\r\n                updateUrl(path) {\r\n                    window.history.pushState({}, '', path);\r\n                },\r\n                loadYears(page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: 'photos\/years',\r\n                        itemsKey: 'years',\r\n                        viewType: 'years',\r\n                        breadcrumbHTML: '',\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadYears(newPage)\r\n                    });\r\n                },\r\n                loadAlbums(year, page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}${year}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: `photos\/albums\/${year}`,\r\n                        itemsKey: 'albums',\r\n                        viewType: 'albums',\r\n                        breadcrumbHTML: `<a href=\"#\" class=\"breadcrumb-home\" style=\"text-decoration: none;\">Anos<\/a> &gt; <span>${year}<\/span>`,\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadAlbums(year, newPage)\r\n                    });\r\n                },\r\n                loadPhotos(albumId, year, title, page = 1, updateUrl = true) {\r\n                    if (updateUrl) Router.set(`${baseGalleryUrl}${year}\/${albumId}`);\r\n\r\n                    GalleryView.load({\r\n                        endpoint: `photos\/album\/${albumId}`,\r\n                        itemsKey: 'photos',\r\n                        viewType: 'photos',\r\n                        breadcrumbHTML: `<a href=\"#\" class=\"breadcrumb-home\" style=\"text-decoration: none;\">Anos<\/a> &gt; <a href=\"#\" class=\"breadcrumb-year\" data-year=\"${year}\" style=\"text-decoration: none;\">${year}<\/a> &gt; <span>${title}<\/span>`,\r\n                        page,\r\n                        onPaginate: (newPage) => this.loadPhotos(albumId, year, title, newPage)\r\n                    });\r\n                }\r\n            };\r\n\r\n            \/\/ Modal Service (Singleton)\r\n            const ModalService = {\r\n                init() {\r\n                    let modal = document.querySelector('.photo-modal');\r\n                    if (!modal) {\r\n                        modal = document.createElement('div');\r\n                        modal.classList.add('photo-modal', 'hidden');\r\n                        modal.innerHTML = `\r\n                            <div class=\"photo-modal-overlay\"><\/div>\r\n                            <div class=\"photo-modal-content\">\r\n                                <button class=\"photo-modal-close\">&times;<\/button>\r\n                                <img decoding=\"async\" src=\"\" alt=\"\" \/>\r\n                            <\/div>\r\n                        `;\r\n                        document.body.appendChild(modal);\r\n\r\n                        modal.querySelector('.photo-modal-close').addEventListener('click', () => this.close());\r\n                        modal.querySelector('.photo-modal-overlay').addEventListener('click', () => this.close());\r\n                    }\r\n                    this.modalElement = modal;\r\n                },\r\n                open(imgSrc, imgAlt) {\r\n                    if (!this.modalElement) this.init();\r\n                    const img = this.modalElement.querySelector('img');\r\n                    img.src = imgSrc;\r\n                    img.alt = imgAlt || '';\r\n                    this.modalElement.classList.remove('hidden');\r\n                },\r\n                close() {\r\n                    if (!this.modalElement) return;\r\n                    this.modalElement.classList.add('hidden');\r\n                    this.modalElement.querySelector('img').src = '';\r\n                }\r\n            };\r\n\r\n            \/\/ Event Delegation Handler\r\n            document.addEventListener(\"click\", (e) => {\r\n                const breadcrumbHome = e.target.closest('.breadcrumb-home');\r\n                if (breadcrumbHome) {\r\n                    e.preventDefault();\r\n                    App.loadYears();\r\n                    return;\r\n                }\r\n\r\n                const breadcrumbYear = e.target.closest('.breadcrumb-year');\r\n                if (breadcrumbYear) {\r\n                    e.preventDefault();\r\n                    App.loadAlbums(breadcrumbYear.dataset.year);\r\n                    return;\r\n                }\r\n\r\n                const yearCard = e.target.closest(\".years-cards\");\r\n                if (yearCard) {\r\n                    e.preventDefault();\r\n                    App.loadAlbums(yearCard.dataset.year);\r\n                    return;\r\n                }\r\n\r\n                const albumCard = e.target.closest(\".albums-cards\");\r\n                if (albumCard) {\r\n                    e.preventDefault();\r\n                    App.loadPhotos(albumCard.dataset.id, albumCard.dataset.year, albumCard.dataset.title);\r\n                    return;\r\n                }\r\n\r\n                const photoCard = e.target.closest(\".photo-card\");\r\n                if (photoCard) {\r\n                    e.preventDefault();\r\n                    const img = photoCard.querySelector(\"img\");\r\n                    if (img) ModalService.open(img.src, img.alt);\r\n                }\r\n            });\r\n\r\n            \/\/ Initialize\r\n            const pathParts = window.location.pathname\r\n                .split('\/')\r\n                .filter(Boolean);\r\n\r\n            const fotosIndex = pathParts.indexOf('fotos');\r\n\r\n            if (fotosIndex === -1) {\r\n                App.loadYears();\r\n                return;\r\n            }\r\n\r\n            const params = pathParts.slice(fotosIndex + 1);\r\n\r\n            const paramStrategy = {\r\n                0: () => App.loadYears(),\r\n                1: () => App.loadAlbums(params[0]),\r\n                2: () => App.loadPhotos(params[1], params[0], '', 1, false)\r\n            };\r\n\r\n            (paramStrategy[params.length] || paramStrategy[0])();\r\n\r\n        });\r\n    <\/script>\r\n\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-42","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/pages\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/comments?post=42"}],"version-history":[{"count":4,"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/pages\/42\/revisions"}],"predecessor-version":[{"id":440,"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/pages\/42\/revisions\/440"}],"wp:attachment":[{"href":"https:\/\/sites.williarts.com.br\/catedral\/wp-json\/wp\/v2\/media?parent=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}