diff --git a/js-src/index.js b/js-src/index.js index 195de8a..92ca122 100644 --- a/js-src/index.js +++ b/js-src/index.js @@ -65,6 +65,7 @@ document.addEventListener("DOMContentLoaded", function () { fakeSearchInput = searchMobile.querySelector('input') addListenersSearch() } + addListenersSearchOverlay(); const cookies = document.cookie.split(";").map((cookie) => { let [key, value] = cookie.split("="); @@ -83,6 +84,12 @@ document.addEventListener("DOMContentLoaded", function () { function startSearchTutorial() { console.log('Showing how to use search'); + const tutorialOverlay = document.querySelector('.tutorial-overlay-step-1'); + if (tutorialOverlay === null) { + console.error('tutorialOverlay missing'); + return; + } +// tutorialOverlay.classList.remove('hidden'); } function markSearchTutorialAsSeen() { @@ -174,10 +181,8 @@ function addListenersSearch() { const searchOverlay = document.querySelector('div.search-overlay'); const searchInput = searchOverlay.querySelector('div.search input'); fakeSearchInput.value = searchInput.value; - exitSearch.addEventListener('click', onExitSearch) - const search = document.querySelector('div.search-overlay div.search input'); - if (search !== null) { - search.addEventListener('change', onSearchChange); + if (exitSearch !== null) { + exitSearch.addEventListener('click', onExitSearch) } const searchIconDesktop = document.querySelector('nav.desktop a.search-icon'); if (searchIconDesktop !== null) { @@ -187,6 +192,13 @@ function addListenersSearch() { } } +function addListenersSearchOverlay() { + const search = document.querySelector('div.search-overlay div.search input'); + if (search !== null) { + search.addEventListener('change', onSearchChange); + } +} + function searchInWebsite(value, isToBottom) { window.find(value, false, !isToBottom, true) const selection = window.getSelection() @@ -247,8 +259,34 @@ function onSearchChange() { 'event': 'realsearch_term_keyup', 'term': search.value, }); - fakeSearchInput.value = search.value + if (fakeSearchInput !== undefined && fakeSearchInput !== null) { + fakeSearchInput.value = search.value + } + let found = search.value.match(/^#(\S+?)(?:\:(\S+?))?$/); const port = _port() + if (found) { + let attributeUrlPart = found[2]; + console.log(attributeUrlPart); + if (attributeUrlPart === undefined) { + attributeUrlPart = ''; + } + console.log(attributeUrlPart); + if (attributeUrlPart !== '') { + attributeUrlPart = '/atributo/' + attributeUrlPart; + } + console.log(attributeUrlPart); + const checkHashstagUrl = new URL(window.location.protocol + + "//" + + window.location.hostname + + port + + '/' + found[1] + attributeUrlPart); + fetch(checkHashstagUrl).then((res) => { + if (res.status === 200) { + window.location = checkHashstagUrl; + } + }); + return; + } const url = new URL(window.location.protocol + "//" + window.location.hostname diff --git a/public/css/styles.css b/public/css/styles.css index 75097d2..0e28e43 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -2,6 +2,33 @@ html { height: 100%; touch-action: none; } +div.open-browser-container { + display: flex; + justify-content: start; + width: 100%; + margin-left: 0px; + margin-right: 0px; + padding-left: 0px; + padding-right: 0px; + background: #f2eb8c; + color: blueviolet; } + div.open-browser-container a.open-in-browser { + text-decoration: none; + display: flex; + justify-content: space-between; + width: calc(100% - 20px); + align-items: center; + margin-left: 10px; + margin-right: 10px; } + div.open-browser-container a.open-in-browser img { + display: block; + height: 2rem; + width: 2rem; + margin-right: 0px; + margin-left: 0px; } + div.open-browser-container a.open-in-browser span { + display: block; } + body { margin: 0; padding: 0; @@ -36,6 +63,43 @@ body { align-items: center; vertical-align: middle; margin-bottom: 0.15em; } + body div.tutorial-overlay-step-1 { + position: fixed; + display: block; + width: 100%; + height: 100%; + background: rgba(100, 100, 100, 0.5); + top: 0%; + z-index: 999; } + body div.tutorial-overlay-step-1 > .explanation { + position: absolute; + left: 10px; + color: aquamarine; + background: rgba(100, 100, 100, 0.5); + width: 230px; + text-align: center; + border-radius: 10px; + border: solid 3px black; + font-size: 30px; + top: calc(100% - 80px - 203px - 90px); } + body div.tutorial-overlay-step-1 > .arrow { + position: absolute; + left: 90px; + top: calc(100% - 80px - 203px); + display: block; } + body div.tutorial-overlay-step-1.hidden { + display: none; } + body div.search-results > div.description { + display: flex; + align-items: center; + flex-direction: column; + background: #2160c4; + border: solid #9dc1fa 0.3rem; + color: white; + font-weight: bold; + border-radius: 20px; + width: calc(100% - 20px - 0.6rem); + padding: 10px; } body div.search-overlay { overflow-y: scroll; display: none; @@ -46,9 +110,11 @@ body { z-index: 3; top: 0; flex-direction: column; } - body div.search-overlay.active { - display: flex; } + body div.search-overlay.default div.search-results { + height: calc(100% - 80px - 2rem); + overflow-x: scroll; } body div.search-overlay div.search-results { + height: calc(100% - 80px); margin: 7px; } body div.search-overlay div.search-results img { width: 75px; } @@ -57,6 +123,12 @@ body { flex-direction: row; } body div.search-overlay div.search-results div.search-result div.row-title-url-image img { margin: 10px; } + body div.search-overlay div.search-results div.search-result p { + background: aliceblue; + width: fit-content; + padding: 20px; + margin-left: 90px; + margin-right: 20px; } body div.search-overlay div.bounding-search-bar { position: fixed; top: calc(100% - 74px); @@ -65,11 +137,6 @@ body { border-radius: 10px; height: 60px; display: flex; } - body div.search-overlay div.bounding-search-bar div.search { - width: calc(100% - 60px); - height: 60px; - margin-left: 0px; - margin-right: 0px; } body div.search-overlay div.bounding-search-bar a.up, body div.search-overlay div.bounding-search-bar a.down { display: none; } body div.search-overlay div.bounding-search-bar a.exit-search { @@ -344,14 +411,9 @@ body { position: absolute; left: 80px; top: 10%; - width: Min(calc(100% - 90px * 2), 500px); + width: Min(calc(100% - 120px), 500px); height: 80%; border-radius: 10px; } - body nav.mobile-shortcuts a.menu-expand { - position: absolute; - left: Min(calc(100% - 80px), 600px); - top: 0; - align-self: end; } body div.page-contents { background: #FEFEFA; position: fixed; @@ -463,44 +525,8 @@ body { body div.page-contents div.description a.suscribe-category-rss img { width: 40px; height: 40px; } - body div.page-contents div.open-browser-container { - display: flex; - justify-content: start; - width: 100%; - margin-left: 0px; - margin-right: 0px; - padding-left: 0px; - padding-right: 0px; - background: #f2eb8c; - color: blueviolet; } - body div.page-contents div.open-browser-container a.open-in-browser { - text-decoration: none; - display: flex; - justify-content: space-between; - width: calc(100% - 20px); - align-items: center; - margin-left: 10px; - margin-right: 10px; } - body div.page-contents div.open-browser-container a.open-in-browser img { - display: block; - height: 2rem; - width: 2rem; - margin-right: 0px; - margin-left: 0px; } - body div.page-contents div.open-browser-container a.open-in-browser span { - display: block; } body div.page-contents div.open-browser-container.android { display: none; } - body div.page-contents div.easter-egg { - display: flex; - justify-content: center; } - body div.page-contents div.burguillos-logo-container.active { - border: solid 1px black; - border-radius: 50%; - filter: invert(1); } - body div.page-contents div.burguillos-logo-container { - padding: 40px; - width: 120px; } body div.page-contents h1 { text-align: center; } body div.page-contents div.footer p, body div.page-contents div.footer h1, body div.page-contents div.footer h2, body div.page-contents div.footer h3, body div.page-contents div.footer h4, body div.page-contents div.footer a { @@ -511,6 +537,32 @@ body { width: 20px; height: 20px; } +div.easter-egg { + display: flex; + justify-content: center; } + +div.burguillos-logo-container.active { + filter: invert(1); } + +div.burguillos-logo-container { + width: 120px; } + +div.search-overlay div.search { + width: calc(100% - 60px); + height: 60px; + margin-left: 0px; + margin-right: 0px; } + +div.search-overlay.active { + display: flex; } + +div.search-overlay.default { + display: flex; } + div.search-overlay.default div.search { + width: 100%; } + div.search-overlay.default div.fake-text-box { + width: 100%; } + @media (min-width: 450px) { body div.page-contents table th, body div.page-contents table td { font-size: 20px; } } diff --git a/public/css/styles.scss b/public/css/styles.scss index 08c51dd..54a9bc6 100644 --- a/public/css/styles.scss +++ b/public/css/styles.scss @@ -16,6 +16,39 @@ html { height: 100%; touch-action: none; } + div.open-browser-container { + display: flex; + justify-content: start; + width: 100%; + margin-left: 0px; + margin-right: 0px; + padding-left: 0px; + padding-right: 0px; + background: $color_div; + color: $background_div; + + a.open-in-browser { + text-decoration: none; + display: flex; + justify-content: space-between; + width: calc(100% - 20px); + align-items: center; + margin-left: 10px; + margin-right: 10px; + + img { + display: block; + height: 2rem; + width: 2rem; + margin-right: 0px; + margin-left: 0px; + } + + span { + display: block; + } + } + } body { summary { @@ -54,6 +87,51 @@ body { margin-bottom: 0.15em; } + div.tutorial-overlay-step-1 { + position: fixed; + display: block; + width: 100%; + height: 100%; + background: rgba(100, 100, 100, 0.5); + top: 0%; + z-index: 999; + & > .explanation { + position: absolute; + left: 10px; + color: aquamarine; + background: rgba(100, 100, 100, 0.5); + width: 230px; + text-align: center; + border-radius: 10px; + border: solid 3px black; + font-size: 30px; + top: calc(100% - 80px - 203px - 90px); + } + & > .arrow { + position: absolute; + left: 90px; + top: calc(100% - 80px - 203px); + display: block; + } + &.hidden { + display: none; + } + } + + div.search-results > div.description { + display: flex; + align-items: center; + flex-direction: column; + background: #2160c4; + border: solid #9dc1fa 0.3rem; + color: white; + font-weight: bold; + + border-radius: 20px; + width: calc(100% - 20px - 0.6rem); + padding: 10px; + } + div.search-overlay { overflow-y: scroll; display: none; @@ -65,11 +143,16 @@ body { top: 0; flex-direction: column; - &.active { - display: flex; - } + + &.default { + div.search-results { + height: calc(100% - 80px - 2rem); + overflow-x: scroll; + } + } div.search-results { + height: calc(100% - 80px); margin: 7px; img { @@ -85,6 +168,13 @@ body { margin: 10px; } } + p { + background: aliceblue; + width: fit-content; + padding: 20px; + margin-left: 90px; + margin-right: 20px; + } } } @@ -97,12 +187,6 @@ body { height: 60px; display: flex; - div.search { - width: calc(100% - 60px); - height: 60px; - margin-left: 0px; - margin-right: 0px; - } a.up, a.down { display: none; @@ -502,17 +586,10 @@ body { position: absolute; left: 80px; top: 10%; - width: Min(calc(100% - 90px * 2), 500px); + width: Min(calc(100% - 120px), 500px); height: 80%; border-radius: 10px; } - - a.menu-expand { - position: absolute; - left: Min(calc(100% - 80px), 600px); - top: 0; - align-self: end; - } } div.page-contents { @@ -686,61 +763,11 @@ body { } } - div.open-browser-container { - display: flex; - justify-content: start; - width: 100%; - margin-left: 0px; - margin-right: 0px; - padding-left: 0px; - padding-right: 0px; - background: $color_div; - color: $background_div; - - a.open-in-browser { - text-decoration: none; - display: flex; - justify-content: space-between; - width: calc(100% - 20px); - align-items: center; - margin-left: 10px; - margin-right: 10px; - - img { - display: block; - height: 2rem; - width: 2rem; - margin-right: 0px; - margin-left: 0px; - } - - span { - display: block; - } - } - } div.open-browser-container.android { display: none; } - div.easter-egg { - display: flex; - justify-content: center; - } - - div.burguillos-logo-container.active { - border: solid 1px black; - border-radius: 50%; - filter: invert(1); - } - - div.burguillos-logo-container { - padding: 40px; - width: 120px; - } - - div.burguillos-logo-container.active img {} h1 { text-align: center; @@ -763,6 +790,42 @@ body { } } +div.easter-egg { + display: flex; + justify-content: center; +} + +div.burguillos-logo-container.active { + filter: invert(1); +} + +div.burguillos-logo-container { + width: 120px; +} + +div.burguillos-logo-container.active img {} + +div.search-overlay { + div.search { + width: calc(100% - 60px); + height: 60px; + margin-left: 0px; + margin-right: 0px; + } + &.active { + display: flex; + } + &.default { + display: flex; + div.search { + width: 100%; + } + div.fake-text-box { + width: 100%; + } + } +} + @media (min-width: 450px) { body { div.page-contents { diff --git a/public/img/arrow-pointing-down.webp b/public/img/arrow-pointing-down.webp index 5dd5eaa..23807f1 100644 Binary files a/public/img/arrow-pointing-down.webp and b/public/img/arrow-pointing-down.webp differ diff --git a/public/js/bundle.js b/public/js/bundle.js index e2b24d3..0ff3140 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -16,7 +16,7 @@ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tablesort__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _burguillosinfo_carousel_ad__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @burguillosinfo/carousel-ad */ \"./js-src/carousel-ad.ts\");\n\n\n\n\nwindow.Tablesort = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n__webpack_require__(/*! tablesort/src/sorts/tablesort.number */ \"./node_modules/tablesort/src/sorts/tablesort.number.js\");\nlet fakeSearchInput;\nlet searchMobile;\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n const menu_expand = document.querySelector('a.menu-expand');\n const mobile_foldable = document.querySelector('nav.mobile-foldable');\n const transparentFullscreenHide = document.querySelector('div.transparent-fullscreen-hide');\n const contentsWithoutMenu = document.querySelector('div.contents-without-menu');\n const tables = document.querySelectorAll('table');\n fillFarmaciaGuardia();\n // new CarouselAd().run()\n addEasterEggAnimation();\n if (menu_expand !== null && mobile_foldable !== null && transparentFullscreenHide !== null && contentsWithoutMenu !== null) {\n mobile_foldable.toggleAttribute('aria-hidden');\n if (mobile_foldable.getAttribute('aria-hidden') !== null) {\n mobile_foldable.setAttribute('aria-hidden', true);\n }\n transparentFullscreenHide.addEventListener('click', () => {\n mobile_foldable.classList.remove('show');\n transparentFullscreenHide.classList.remove('show');\n menu_expand.classList.remove('active');\n contentsWithoutMenu.removeAttribute('aria-hidden');\n mobile_foldable.setAttribute('aria-hidden', true);\n });\n menu_expand.addEventListener('click', () => {\n menu_expand.classList.toggle('active');\n mobile_foldable.classList.toggle('show');\n transparentFullscreenHide.classList.toggle('show');\n contentsWithoutMenu.toggleAttribute('aria-hidden');\n if (contentsWithoutMenu.getAttribute('aria-hidden') !== null) {\n contentsWithoutMenu.setAttribute('aria-hidden', true);\n }\n mobile_foldable.toggleAttribute('aria-hidden');\n if (mobile_foldable.getAttribute('aria-hidden') !== null) {\n mobile_foldable.setAttribute('aria-hidden', true);\n }\n });\n }\n for (const table of tables) {\n const header = table.querySelector('tr');\n if (header !== null) {\n header.setAttribute('data-sort-method', 'none');\n for (const th of header.querySelectorAll('th')) {\n if (th.getAttribute('data-sort-method') == null) {\n th.setAttribute('data-sort-method', 'thead');\n }\n }\n }\n new (tablesort__WEBPACK_IMPORTED_MODULE_0___default())(table);\n }\n if (window !== undefined && window.Android !== undefined) {\n executeAndroidExclusiveCode(Android);\n }\n searchMobile = document.querySelector('nav.mobile-shortcuts div.search');\n if (searchMobile !== null) {\n fakeSearchInput = searchMobile.querySelector('input');\n addListenersSearch();\n }\n const cookies = document.cookie.split(\";\").map(cookie => {\n let [key, value] = cookie.split(\"=\");\n return {\n key: key,\n value: value\n };\n }).reduce((acc, cookie) => {\n acc[cookie.key] = cookie.value;\n return acc;\n }, {});\n if (!cookies['search-tutorial-seen']) {\n startSearchTutorial();\n }\n}, false);\nfunction startSearchTutorial() {\n console.log('Showing how to use search');\n markSearchTutorialAsSeen();\n}\nfunction markSearchTutorialAsSeen() {\n document.cookie = 'search-tutorial-seen=1; SameSite=Lax;';\n}\nfunction fillFarmaciaGuardia() {\n const farmaciaName = document.querySelector('#farmacia-name');\n const farmaciaAddress = document.querySelector('#farmacia-address');\n if (farmaciaName !== null || farmaciaAddress !== null) {\n const port = _port();\n const url = new URL(window.location.protocol + \"//\" + window.location.hostname + port + '/farmacia-guardia.json');\n fetch(url).then(async res => {\n const farmacia = await res.json();\n if (farmaciaName !== null) {\n farmaciaName.innerText = farmacia.name;\n farmaciaAddress.innerText = farmacia.address;\n }\n });\n }\n}\nfunction addListenersSearch() {\n const searchInPage = document.querySelector('div.search-in-page');\n if (searchMobile !== null) {\n const searchIcon = searchMobile.querySelector('a.search-icon');\n searchIcon.addEventListener('click', e => {\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'fakesearch_term',\n 'term': fakeSearchInput.value\n });\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e);\n onFakeSearchClick(e);\n return true;\n });\n fakeSearchInput.addEventListener('keyup', e => {\n if (searchInPage === null) {\n return;\n }\n if (fakeSearchInput.value === \"\") {\n searchInPage.classList.remove('active');\n } else {\n searchInPage.classList.add('active');\n }\n if (e.keyCode !== 13) {\n return false;\n }\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'fakesearch_term_keyup',\n 'term': fakeSearchInput.value\n });\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e);\n onFakeSearchClick(e);\n return true;\n });\n }\n const nextResult = searchInPage.querySelector('a.down');\n const prevResult = searchInPage.querySelector('a.up');\n window.addEventListener(\"keydown\", e => {\n if (e.key.toLowerCase() === \"f\" && e.ctrlKey) {\n openAllDetails();\n }\n });\n window.addEventListener(\"blur\", e => {\n openAllDetails();\n });\n if (nextResult !== null && prevResult !== null) {\n nextResult.addEventListener('click', () => {\n searchInWebsite(fakeSearchInput.value, true);\n });\n prevResult.addEventListener('click', () => {\n searchInWebsite(fakeSearchInput.value, false);\n });\n }\n const exitSearch = document.querySelector('a.exit-search');\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n fakeSearchInput.value = searchInput.value;\n exitSearch.addEventListener('click', onExitSearch);\n const search = document.querySelector('div.search-overlay div.search input');\n if (search !== null) {\n search.addEventListener('change', onSearchChange);\n }\n const searchIconDesktop = document.querySelector('nav.desktop a.search-icon');\n if (searchIconDesktop !== null) {\n searchIconDesktop.addEventListener('click', e => {\n onFakeSearchClick(e);\n });\n }\n}\nfunction searchInWebsite(value, isToBottom) {\n window.find(value, false, !isToBottom, true);\n const selection = window.getSelection();\n openAllDetails();\n if (selection.anchorNode === null) {\n const pageContents = document.querySelector('div.page-contents');\n pageContents.focus();\n searchInWebsite(value, isToBottom);\n }\n const anchorNode = selection.anchorNode.parentNode;\n if (anchorNode.tagName !== null && anchorNode.tagName === \"INPUT\") {\n const pageContents = document.querySelector('div.page-contents');\n pageContents.focus();\n searchInWebsite(value, isToBottom);\n }\n if (anchorNode !== null) {\n const pageContents = document.querySelector('div.page-contents');\n const offsetTop = _getOffsetTopWithNParent(anchorNode, pageContents);\n pageContents.scroll(0, offsetTop - 150);\n }\n}\nfunction openAllDetails() {\n for (const detail of document.querySelectorAll('details')) {\n detail.open = true;\n }\n}\nfunction _getOffsetTopWithNParent(element, nParent, _carry = 0) {\n if (element === null) {\n return null;\n }\n if (element === nParent) {\n return _carry;\n }\n _carry += element.offsetTop;\n return _getOffsetTopWithNParent(element.offsetParent, nParent, _carry);\n}\nfunction _port() {\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port;\n }\n return port;\n}\nfunction onSearchChange() {\n const search = document.querySelector('div.search-overlay div.search input');\n const searchResults = document.querySelector('div.search-overlay div.search-results');\n if (search === null || searchResults === null) {\n return;\n }\n const query = search.value;\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'realsearch_term_keyup',\n 'term': search.value\n });\n fakeSearchInput.value = search.value;\n const port = _port();\n const url = new URL(window.location.protocol + \"//\" + window.location.hostname + port + '/search.json');\n url.searchParams.set('q', query);\n fetch(url).then(async res => {\n const json = await res.json();\n if (!json.ok) {\n noResults(searchResults);\n return;\n }\n console.log(json.searchObjects.length);\n if (json.searchObjects.length < 1) {\n noResults(searchResults);\n return;\n }\n showResults(searchResults, json.searchObjects);\n });\n search.focus();\n}\nfunction showResults(searchResults, searchObjects) {\n searchResults.innerHTML = \"\";\n for (let searchObject of searchObjects) {\n const searchResultContainer = document.createElement('div');\n searchResultContainer.classList.add('search-result');\n const rowTitleUrlImageDiv = document.createElement('div');\n rowTitleUrlImageDiv.classList.add('row-title-url-image');\n const columnTitleUrl = document.createElement('div');\n columnTitleUrl.classList.add('column-title-url');\n const img = document.createElement('img');\n const title = document.createElement('b');\n const url = document.createElement('a');\n const content = document.createElement('p');\n title.innerText = searchObject.title;\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port;\n }\n if (searchObject.url.match(/^\\//)) {\n searchObject.url = window.location.protocol + \"//\" + window.location.hostname + port + searchObject.url;\n }\n let urlImage = searchObject.urlImage;\n if (urlImage !== null && urlImage.match(/^\\//)) {\n urlImage = window.location.protocol + \"//\" + window.location.hostname + port + urlImage;\n }\n if (urlImage !== null) {\n img.alt = \"\";\n img.src = urlImage;\n }\n url.href = searchObject.url;\n url.innerText = searchObject.url;\n content.innerText = searchObject.content;\n if (urlImage !== null) {\n rowTitleUrlImageDiv.appendChild(img);\n }\n columnTitleUrl.appendChild(title);\n columnTitleUrl.appendChild(document.createElement('br'));\n columnTitleUrl.appendChild(url);\n rowTitleUrlImageDiv.appendChild(columnTitleUrl);\n searchResultContainer.appendChild(rowTitleUrlImageDiv);\n searchResultContainer.appendChild(content);\n searchResults.appendChild(searchResultContainer);\n }\n}\nfunction noResults(searchResults) {\n searchResults.innerHTML = \"\";\n const p = document.createElement('p');\n p.innerText = 'No se han encontrado resultados.';\n searchResults.appendChild(p);\n}\nfunction onExitSearch() {\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay !== null) {\n searchOverlay.classList.toggle('active');\n }\n}\nfunction onFakeSearchClick(e) {\n e.preventDefault();\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay === null) {\n return;\n }\n searchOverlay.classList.toggle('active');\n const search = searchOverlay.querySelector('div.search input');\n if (search !== null) {\n search.focus();\n }\n return false;\n}\nfunction absoluteToHost(imageUrl) {\n if (imageUrl.match(/^\\//)) {\n imageUrl = window.location.protocol + \"//\" + window.location.host + imageUrl;\n }\n return imageUrl.replace(/\\?.*$/, '');\n}\nfunction addListenerOpenInBrowserButton(android) {\n const openInBrowserLink = document.querySelector('a.open-in-browser');\n if (openInBrowserLink === null) {\n return;\n }\n openInBrowserLink.addEventListener('click', () => {\n android.openInBrowser(window.location.href);\n });\n}\nfunction executeAndroidExclusiveCode(android) {\n document.querySelectorAll('*.android').forEach(element => {\n element.classList.remove('android');\n });\n document.querySelectorAll('*.no-android-app').forEach(element => {\n element.style.display = 'none';\n });\n addListenerOpenInBrowserButton(android);\n const pinToHomeUrl = document.querySelector('a.pin-to-home');\n if (pinToHomeUrl === null) {\n return;\n }\n pinToHomeUrl.addEventListener('click', () => {\n const url = new URL(window.location.href);\n const pathandQuery = url.pathname + url.search;\n const label = url.pathname.replace(/^.*\\//g, '').replace(/(?:^|-)\\w/g, function (character) {\n return character.toUpperCase();\n }).replace(/-/g, ' ') + ' - Burguillos.info';\n const firstImg = document.querySelector('div.description img');\n let iconUrl;\n if (firstImg !== null) {\n if (!firstImg.src.match(/\\.svg(?:\\?|$)/)) {\n iconUrl = absoluteToHost(firstImg.src);\n }\n }\n if (iconUrl === undefined) {\n const imagePreview = document.querySelector('meta[name=\"image\"]');\n iconUrl = absoluteToHost(imagePreview.content);\n }\n android.pinPage(pathandQuery, label, iconUrl);\n });\n}\nfunction addEasterEggAnimation() {\n const logoContainer = document.querySelector('div.burguillos-logo-container');\n if (logoContainer === null) {\n return;\n }\n logoContainer.addEventListener('click', () => {\n logoContainer.classList.toggle('active');\n });\n}\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n/* harmony import */ var tablesort__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tablesort__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _burguillosinfo_carousel_ad__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @burguillosinfo/carousel-ad */ \"./js-src/carousel-ad.ts\");\n\n\n\n\nwindow.Tablesort = __webpack_require__(/*! tablesort */ \"./node_modules/tablesort/src/tablesort.js\");\n__webpack_require__(/*! tablesort/src/sorts/tablesort.number */ \"./node_modules/tablesort/src/sorts/tablesort.number.js\");\nlet fakeSearchInput;\nlet searchMobile;\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n const menu_expand = document.querySelector('a.menu-expand');\n const mobile_foldable = document.querySelector('nav.mobile-foldable');\n const transparentFullscreenHide = document.querySelector('div.transparent-fullscreen-hide');\n const contentsWithoutMenu = document.querySelector('div.contents-without-menu');\n const tables = document.querySelectorAll('table');\n fillFarmaciaGuardia();\n // new CarouselAd().run()\n addEasterEggAnimation();\n if (menu_expand !== null && mobile_foldable !== null && transparentFullscreenHide !== null && contentsWithoutMenu !== null) {\n mobile_foldable.toggleAttribute('aria-hidden');\n if (mobile_foldable.getAttribute('aria-hidden') !== null) {\n mobile_foldable.setAttribute('aria-hidden', true);\n }\n transparentFullscreenHide.addEventListener('click', () => {\n mobile_foldable.classList.remove('show');\n transparentFullscreenHide.classList.remove('show');\n menu_expand.classList.remove('active');\n contentsWithoutMenu.removeAttribute('aria-hidden');\n mobile_foldable.setAttribute('aria-hidden', true);\n });\n menu_expand.addEventListener('click', () => {\n menu_expand.classList.toggle('active');\n mobile_foldable.classList.toggle('show');\n transparentFullscreenHide.classList.toggle('show');\n contentsWithoutMenu.toggleAttribute('aria-hidden');\n if (contentsWithoutMenu.getAttribute('aria-hidden') !== null) {\n contentsWithoutMenu.setAttribute('aria-hidden', true);\n }\n mobile_foldable.toggleAttribute('aria-hidden');\n if (mobile_foldable.getAttribute('aria-hidden') !== null) {\n mobile_foldable.setAttribute('aria-hidden', true);\n }\n });\n }\n for (const table of tables) {\n const header = table.querySelector('tr');\n if (header !== null) {\n header.setAttribute('data-sort-method', 'none');\n for (const th of header.querySelectorAll('th')) {\n if (th.getAttribute('data-sort-method') == null) {\n th.setAttribute('data-sort-method', 'thead');\n }\n }\n }\n new (tablesort__WEBPACK_IMPORTED_MODULE_0___default())(table);\n }\n if (window !== undefined && window.Android !== undefined) {\n executeAndroidExclusiveCode(Android);\n }\n searchMobile = document.querySelector('nav.mobile-shortcuts div.search');\n if (searchMobile !== null) {\n fakeSearchInput = searchMobile.querySelector('input');\n addListenersSearch();\n }\n addListenersSearchOverlay();\n const cookies = document.cookie.split(\";\").map(cookie => {\n let [key, value] = cookie.split(\"=\");\n return {\n key: key,\n value: value\n };\n }).reduce((acc, cookie) => {\n acc[cookie.key] = cookie.value;\n return acc;\n }, {});\n if (!cookies['search-tutorial-seen']) {\n startSearchTutorial();\n }\n}, false);\nfunction startSearchTutorial() {\n console.log('Showing how to use search');\n const tutorialOverlay = document.querySelector('.tutorial-overlay-step-1');\n if (tutorialOverlay === null) {\n console.error('tutorialOverlay missing');\n return;\n }\n // tutorialOverlay.classList.remove('hidden');\n}\n\nfunction markSearchTutorialAsSeen() {\n console.log('Tutorial ended');\n document.cookie = 'search-tutorial-seen=1; SameSite=Lax;';\n}\nfunction fillFarmaciaGuardia() {\n const farmaciaName = document.querySelector('#farmacia-name');\n const farmaciaAddress = document.querySelector('#farmacia-address');\n if (farmaciaName !== null || farmaciaAddress !== null) {\n const port = _port();\n const url = new URL(window.location.protocol + \"//\" + window.location.hostname + port + '/farmacia-guardia.json');\n fetch(url).then(async res => {\n const farmacia = await res.json();\n if (farmaciaName !== null) {\n farmaciaName.innerText = farmacia.name;\n farmaciaAddress.innerText = farmacia.address;\n }\n });\n }\n}\nfunction addListenersSearch() {\n const searchInPage = document.querySelector('div.search-in-page');\n if (searchMobile !== null) {\n const searchIcon = searchMobile.querySelector('a.search-icon');\n searchIcon.addEventListener('click', e => {\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'fakesearch_term',\n 'term': fakeSearchInput.value\n });\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e);\n onFakeSearchClick(e);\n return true;\n });\n fakeSearchInput.addEventListener('keyup', e => {\n if (searchInPage === null) {\n return;\n }\n if (fakeSearchInput.value === \"\") {\n searchInPage.classList.remove('active');\n } else {\n searchInPage.classList.add('active');\n }\n if (e.keyCode !== 13) {\n return false;\n }\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'fakesearch_term_keyup',\n 'term': fakeSearchInput.value\n });\n searchInput.value = fakeSearchInput.value;\n onSearchChange(e);\n onFakeSearchClick(e);\n return true;\n });\n }\n const nextResult = searchInPage.querySelector('a.down');\n const prevResult = searchInPage.querySelector('a.up');\n window.addEventListener(\"keydown\", e => {\n if (e.key.toLowerCase() === \"f\" && e.ctrlKey) {\n openAllDetails();\n }\n });\n window.addEventListener(\"blur\", e => {\n openAllDetails();\n });\n if (nextResult !== null && prevResult !== null) {\n nextResult.addEventListener('click', () => {\n searchInWebsite(fakeSearchInput.value, true);\n });\n prevResult.addEventListener('click', () => {\n searchInWebsite(fakeSearchInput.value, false);\n });\n }\n const exitSearch = document.querySelector('a.exit-search');\n const searchOverlay = document.querySelector('div.search-overlay');\n const searchInput = searchOverlay.querySelector('div.search input');\n fakeSearchInput.value = searchInput.value;\n if (exitSearch !== null) {\n exitSearch.addEventListener('click', onExitSearch);\n }\n const searchIconDesktop = document.querySelector('nav.desktop a.search-icon');\n if (searchIconDesktop !== null) {\n searchIconDesktop.addEventListener('click', e => {\n onFakeSearchClick(e);\n });\n }\n}\nfunction addListenersSearchOverlay() {\n const search = document.querySelector('div.search-overlay div.search input');\n if (search !== null) {\n search.addEventListener('change', onSearchChange);\n }\n}\nfunction searchInWebsite(value, isToBottom) {\n window.find(value, false, !isToBottom, true);\n const selection = window.getSelection();\n openAllDetails();\n if (selection.anchorNode === null) {\n const pageContents = document.querySelector('div.page-contents');\n pageContents.focus();\n searchInWebsite(value, isToBottom);\n }\n const anchorNode = selection.anchorNode.parentNode;\n if (anchorNode.tagName !== null && anchorNode.tagName === \"INPUT\") {\n const pageContents = document.querySelector('div.page-contents');\n pageContents.focus();\n searchInWebsite(value, isToBottom);\n }\n if (anchorNode !== null) {\n const pageContents = document.querySelector('div.page-contents');\n const offsetTop = _getOffsetTopWithNParent(anchorNode, pageContents);\n pageContents.scroll(0, offsetTop - 150);\n }\n}\nfunction openAllDetails() {\n for (const detail of document.querySelectorAll('details')) {\n detail.open = true;\n }\n}\nfunction _getOffsetTopWithNParent(element, nParent, _carry = 0) {\n if (element === null) {\n return null;\n }\n if (element === nParent) {\n return _carry;\n }\n _carry += element.offsetTop;\n return _getOffsetTopWithNParent(element.offsetParent, nParent, _carry);\n}\nfunction _port() {\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port;\n }\n return port;\n}\nfunction onSearchChange() {\n const search = document.querySelector('div.search-overlay div.search input');\n const searchResults = document.querySelector('div.search-overlay div.search-results');\n if (search === null || searchResults === null) {\n return;\n }\n const query = search.value;\n window.dataLayer = window.dataLayer || [];\n window.dataLayer.push({\n 'event': 'realsearch_term_keyup',\n 'term': search.value\n });\n if (fakeSearchInput !== undefined && fakeSearchInput !== null) {\n fakeSearchInput.value = search.value;\n }\n let found = search.value.match(/^#(\\S+?)(?:\\:(\\S+?))?$/);\n const port = _port();\n if (found) {\n let attributeUrlPart = found[2];\n console.log(attributeUrlPart);\n if (attributeUrlPart === undefined) {\n attributeUrlPart = '';\n }\n console.log(attributeUrlPart);\n if (attributeUrlPart !== '') {\n attributeUrlPart = '/atributo/' + attributeUrlPart;\n }\n console.log(attributeUrlPart);\n const checkHashstagUrl = new URL(window.location.protocol + \"//\" + window.location.hostname + port + '/' + found[1] + attributeUrlPart);\n fetch(checkHashstagUrl).then(res => {\n if (res.status === 200) {\n window.location = checkHashstagUrl;\n }\n });\n return;\n }\n const url = new URL(window.location.protocol + \"//\" + window.location.hostname + port + '/search.json');\n url.searchParams.set('q', query);\n fetch(url).then(async res => {\n const json = await res.json();\n if (!json.ok) {\n noResults(searchResults);\n return;\n }\n console.log(json.searchObjects.length);\n if (json.searchObjects.length < 1) {\n noResults(searchResults);\n return;\n }\n showResults(searchResults, json.searchObjects);\n });\n search.focus();\n}\nfunction showResults(searchResults, searchObjects) {\n searchResults.innerHTML = \"\";\n for (let searchObject of searchObjects) {\n const searchResultContainer = document.createElement('div');\n searchResultContainer.classList.add('search-result');\n const rowTitleUrlImageDiv = document.createElement('div');\n rowTitleUrlImageDiv.classList.add('row-title-url-image');\n const columnTitleUrl = document.createElement('div');\n columnTitleUrl.classList.add('column-title-url');\n const img = document.createElement('img');\n const title = document.createElement('b');\n const url = document.createElement('a');\n const content = document.createElement('p');\n title.innerText = searchObject.title;\n let port = window.location.port;\n if (port !== '') {\n port = ':' + port;\n }\n if (searchObject.url.match(/^\\//)) {\n searchObject.url = window.location.protocol + \"//\" + window.location.hostname + port + searchObject.url;\n }\n let urlImage = searchObject.urlImage;\n if (urlImage !== null && urlImage.match(/^\\//)) {\n urlImage = window.location.protocol + \"//\" + window.location.hostname + port + urlImage;\n }\n if (urlImage !== null) {\n img.alt = \"\";\n img.src = urlImage;\n }\n url.href = searchObject.url;\n url.innerText = searchObject.url;\n content.innerText = searchObject.content;\n if (urlImage !== null) {\n rowTitleUrlImageDiv.appendChild(img);\n }\n columnTitleUrl.appendChild(title);\n columnTitleUrl.appendChild(document.createElement('br'));\n columnTitleUrl.appendChild(url);\n rowTitleUrlImageDiv.appendChild(columnTitleUrl);\n searchResultContainer.appendChild(rowTitleUrlImageDiv);\n searchResultContainer.appendChild(content);\n searchResults.appendChild(searchResultContainer);\n }\n}\nfunction noResults(searchResults) {\n searchResults.innerHTML = \"\";\n const p = document.createElement('p');\n p.innerText = 'No se han encontrado resultados.';\n searchResults.appendChild(p);\n}\nfunction onExitSearch() {\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay !== null) {\n searchOverlay.classList.toggle('active');\n }\n}\nfunction onFakeSearchClick(e) {\n e.preventDefault();\n const searchOverlay = document.querySelector('div.search-overlay');\n if (searchOverlay === null) {\n return;\n }\n searchOverlay.classList.toggle('active');\n const search = searchOverlay.querySelector('div.search input');\n if (search !== null) {\n search.focus();\n }\n return false;\n}\nfunction absoluteToHost(imageUrl) {\n if (imageUrl.match(/^\\//)) {\n imageUrl = window.location.protocol + \"//\" + window.location.host + imageUrl;\n }\n return imageUrl.replace(/\\?.*$/, '');\n}\nfunction addListenerOpenInBrowserButton(android) {\n const openInBrowserLink = document.querySelector('a.open-in-browser');\n if (openInBrowserLink === null) {\n return;\n }\n openInBrowserLink.addEventListener('click', () => {\n android.openInBrowser(window.location.href);\n });\n}\nfunction executeAndroidExclusiveCode(android) {\n document.querySelectorAll('*.android').forEach(element => {\n element.classList.remove('android');\n });\n document.querySelectorAll('*.no-android-app').forEach(element => {\n element.style.display = 'none';\n });\n addListenerOpenInBrowserButton(android);\n const pinToHomeUrl = document.querySelector('a.pin-to-home');\n if (pinToHomeUrl === null) {\n return;\n }\n pinToHomeUrl.addEventListener('click', () => {\n const url = new URL(window.location.href);\n const pathandQuery = url.pathname + url.search;\n const label = url.pathname.replace(/^.*\\//g, '').replace(/(?:^|-)\\w/g, function (character) {\n return character.toUpperCase();\n }).replace(/-/g, ' ') + ' - Burguillos.info';\n const firstImg = document.querySelector('div.description img');\n let iconUrl;\n if (firstImg !== null) {\n if (!firstImg.src.match(/\\.svg(?:\\?|$)/)) {\n iconUrl = absoluteToHost(firstImg.src);\n }\n }\n if (iconUrl === undefined) {\n const imagePreview = document.querySelector('meta[name=\"image\"]');\n iconUrl = absoluteToHost(imagePreview.content);\n }\n android.pinPage(pathandQuery, label, iconUrl);\n });\n}\nfunction addEasterEggAnimation() {\n const logoContainer = document.querySelector('div.burguillos-logo-container');\n if (logoContainer === null) {\n return;\n }\n logoContainer.addEventListener('click', () => {\n logoContainer.classList.toggle('active');\n });\n}\n\n//# sourceURL=webpack://BurguillosInfo/./js-src/index.js?"); /***/ }), diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep index 9010f60..22cce7f 100644 --- a/templates/layouts/default.html.ep +++ b/templates/layouts/default.html.ep @@ -81,9 +81,7 @@ -
- -
+%= include 'page/_search_tutorial'
%= include 'page/_mobile_foldable', categories => $categories
@@ -111,7 +109,7 @@
% } - <%= content %> + <%= content %>
Añade esta página a la pantalla de inicio de tu móvil.
@@ -131,4 +129,5 @@
%= include 'page/_mobile_menu', categories => $categories + diff --git a/templates/layouts/search_results.html.ep b/templates/layouts/search_results.html.ep new file mode 100644 index 0000000..4cae6c5 --- /dev/null +++ b/templates/layouts/search_results.html.ep @@ -0,0 +1,94 @@ + +% my $categories = stash 'categories'; +% my $current_category_slug = stash 'current_category_slug'; +% my $description_og = stash 'description_og'; +% $description_og =~ s/\s+/ /g; +% $description_og = substr $description_og, 0, 157; +% $description_og =~ s/\s\S+$//; +% $description_og.='...'; +% my $base_url = config 'base_url'; +% use Time::Piece; +% my $t = Time::Piece->new(); +% my $year = $t->year; +% my $search_term = stash 'search_term' // ''; +% if ($search_term eq '#index') { +% $search_term = ''; +% } + + + + + + + + + + +% my $css_version = config 'css_version'; + + + + <%= title %> + + + + + + +% my $ogimage = stash 'ogimage'; +% say STDERR $ogimage; +% my $user_agent = stash 'useragent'; + + +% if (defined $ogimage) { +% my $url_for = url_for || ''; + + + +% } else { + + +% } + + + + + +% if (defined $ogimage) { + Portada de <%= title %> +% } + + + +
+
+
+% if ($is_android) { +
+ + + Prueba nuestra aplicación para Android. Más fácil, mejor. + +
+% } +
+ <%= content %> +

Burguillos Info ©2022-<%=$year%> Sergio Iglesias

+
+ +
+ + diff --git a/templates/page/_list_posts.html.ep b/templates/page/_list_posts.html.ep index ba616b4..dd741a3 100644 --- a/templates/page/_list_posts.html.ep +++ b/templates/page/_list_posts.html.ep @@ -1,34 +1,30 @@ % my $posts = stash 'posts'; -

Artículos

-
+% my $base_url = config 'base_url'; +

Resultados de la busqueda

% unless (defined $posts && @$posts) { -

Parece que aun no hay artículos.

+

No se pudo encontrar nada...

% } % for my $post (@$posts) { - -
<% - my $date_article = DateTime::Format::ISO8601->parse_datetime($post->{date}); - $date_article->set_time_zone('Europe/Madrid'); - %>
-

<%= ''.$date_article %>

<% - my $title = $post->{title}; - if (length($title) > 50) { - $title = substr($title, 0, 47).'...'; - } - if (defined $post->{image}) { - %>
- Portada de <%=$title%> -
<% - } - %>
-

<%=$title%>

<% - my $xml = Mojo::DOM->new($post->{content}); - my $text = $xml->all_text; - if (length($text) > 50) { - $text = substr($text, 0, 47).'...'; - } - %>

<%=$text%>

Escrito por <%=$post->{author}%>

-
-
-% } -
+% my $url = "$base_url/posts/$post->{slug}"; +% my $title = $post->{title}; +% if (length($title) > 50) { +% $title = substr($title, 0, 47).'...'; +% } +
+
+% if (defined $post->{image}) { + +% } +
+ <%=$post->{title}%>
+ <%=$url%> +
+
+% my $xml = Mojo::DOM->new($post->{content}); +% my $text = $xml->all_text; +% if (length($text) > 120) { +% $text = substr($text, 0, 117).'...'; +% } +

<%=$text%>

+
+% } diff --git a/templates/page/_mobile_menu.html.ep b/templates/page/_mobile_menu.html.ep index ecf1045..e9c32b9 100644 --- a/templates/page/_mobile_menu.html.ep +++ b/templates/page/_mobile_menu.html.ep @@ -2,8 +2,4 @@ diff --git a/templates/page/_search_bar.html.ep b/templates/page/_search_bar.html.ep index 113560c..799a440 100644 --- a/templates/page/_search_bar.html.ep +++ b/templates/page/_search_bar.html.ep @@ -1,8 +1,9 @@ +% my $search_term = stash 'search_term' // ''; diff --git a/templates/page/_search_tutorial.html.ep b/templates/page/_search_tutorial.html.ep new file mode 100644 index 0000000..ba4c911 --- /dev/null +++ b/templates/page/_search_tutorial.html.ep @@ -0,0 +1,4 @@ + diff --git a/templates/page/attribute.html.ep b/templates/page/attribute.html.ep index aea06c7..9698901 100644 --- a/templates/page/attribute.html.ep +++ b/templates/page/attribute.html.ep @@ -11,10 +11,12 @@ % my $description_og = '
'.$attribute->{description}.'
'; % $description_og = Mojo::DOM->new($description_og)->all_text; % my $posts = stash 'posts'; -% layout 'default', current_category_slug => $category->{slug}, description_og => $description_og; +% layout 'search_results', current_category_slug => $category->{slug}, description_og => $description_og, search_term => "#$category->{slug}:$attribute->{identifier}"; % title $attribute->{title};

<%= $attribute->{title} %>

<%== $attribute->{description} %> +
+
%= include 'page/_list_posts', posts => $posts;
diff --git a/templates/page/index.html.ep b/templates/page/index.html.ep index d1be0bc..990f9f2 100644 --- a/templates/page/index.html.ep +++ b/templates/page/index.html.ep @@ -7,30 +7,17 @@ % % use BurguillosInfo::Posts; % +% my $current_category = stash 'current_category'; % my $description_og = '
'.$current_category->{description}.'
'; % $description_og = Mojo::DOM->new($description_og)->all_text; -% layout 'default', current_category_slug => $current_category->{slug}, description_og => $description_og; +% layout 'search_results', current_category_slug => $current_category->{slug}, description_og => $description_og, search_term => "#$current_category->{slug}"; % title $current_category->{title};

<%= $current_category->{title} %>

<%== $current_category->{description} %> +
+
% my $children_categories = $current_category->{children}; -% my $attributes = $current_category->{attributes}; -% if (@$children_categories || %$attributes) { -

Quizás te interese.

-% for my $child_category (@$children_categories) { -

<%==$child_category->{title}%>

-% } -% for my $attribute_slug (keys %$attributes) { -% my $attribute = $attributes->{$attribute_slug}; -

{slug}/atributo/$attribute->{identifier}"%>"><%==$attribute->{menu_text}%>

-% } -% } % my ($category_posts) = BurguillosInfo::Posts->new->RetrieveAllPostsForCategory($current_category->{slug}); %= include 'page/_list_posts', posts => $category_posts; -

Suscribete a esta categoría.

- - - Icono de suscripción rss -