feat: horário em 3 dias, horário de funcionamento compacto, textura na equipa, estrutura/SEO
- Horário de aulas: cartões mais pequenos e estreitos; a partir de 992px mostra o dia anterior, hoje ao centro e o seguinte (a dar a volta à semana), com as horas alinhadas e os dias laterais esbatidos. O JPG continua a semana toda. - Horário de funcionamento: cartões compactos numa <dl>, ordenados por hora. - Equipa: fundo no cinzento da parede do ginásio com juntas de blocos e grão muito discretos (SVG inline). - Tira o «FitMe 3070» do header e esconde a newsletter. - Estrutura: um <main> em todas as páginas públicas (skip link aponta-lhe), h2 por secção com aria-labelledby, h3 nos itens em vez de h4, sem secções aninhadas, alts distintos na galeria e no h1 do CrossFit. - robots.txt e sitemap.xml gerados com o domínio da instalação; SEO_NOINDEX no .env tira uma cópia de staging dos motores de pesquisa. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
90ee2a93bc
commit
8ebf20f52f
11 files changed
+317
-57
No files matched your search
@@ -40,6 +40,8 @@ RewriteRule ^home/inscricao/?$ site/inscricao.php [L,QSA]
|
|||||||
RewriteRule ^home/crossfit/?$ site/crossfit.php [L,QSA]
|
RewriteRule ^home/crossfit/?$ site/crossfit.php [L,QSA]
|
||||||
RewriteRule ^home/privacidade/?$ site/privacidade.php [L,QSA]
|
RewriteRule ^home/privacidade/?$ site/privacidade.php [L,QSA]
|
||||||
RewriteRule ^evento/([a-zA-Z0-9-]+)/?$ site/evento.php?slug=$1 [L,QSA]
|
RewriteRule ^evento/([a-zA-Z0-9-]+)/?$ site/evento.php?slug=$1 [L,QSA]
|
||||||
|
RewriteRule ^robots\.txt$ site/seo_files.php?f=robots [L]
|
||||||
|
RewriteRule ^sitemap\.xml$ site/seo_files.php?f=sitemap [L]
|
||||||
|
|
||||||
# Pass the Authorization header through to PHP
|
# Pass the Authorization header through to PHP
|
||||||
RewriteCond %{HTTP:Authorization} .
|
RewriteCond %{HTTP:Authorization} .
|
||||||
|
|||||||
@@ -101,3 +101,26 @@ function site_horario(PDO $pdo, string $local = ''): array {
|
|||||||
try { $st = $pdo->prepare($sql); $st->execute($args); return $st->fetchAll(PDO::FETCH_ASSOC); }
|
try { $st = $pdo->prepare($sql); $st->execute($args); return $st->fetchAll(PDO::FETCH_ASSOC); }
|
||||||
catch (Throwable $e) { return []; }
|
catch (Throwable $e) { return []; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Indexing ─────────────────────────────────────────────────────────────────
|
||||||
|
// SEO_NOINDEX=true in .env keeps an install out of search results (meta robots
|
||||||
|
// + robots.txt "Disallow: /"). For staging copies such as fitme.andmore.pt,
|
||||||
|
// which serve the same content as the real domain and would otherwise compete
|
||||||
|
// with it as duplicate content.
|
||||||
|
function seo_noindex(): bool {
|
||||||
|
return filter_var(env('SEO_NOINDEX', 'false'), FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public, indexable URLs for sitemap.xml: the fixed pages plus any live event
|
||||||
|
// landing page.
|
||||||
|
function site_sitemap_urls(PDO $pdo): array {
|
||||||
|
$urls = [
|
||||||
|
['loc' => base_url(), 'priority' => '1.0'],
|
||||||
|
['loc' => base_url('home/crossfit'), 'priority' => '0.8'],
|
||||||
|
['loc' => base_url('home/privacidade'), 'priority' => '0.2'],
|
||||||
|
];
|
||||||
|
foreach (site_active_events($pdo) as $ev) {
|
||||||
|
$urls[] = ['loc' => base_url('evento/' . rawurlencode($ev['slug'])), 'priority' => '0.6'];
|
||||||
|
}
|
||||||
|
return $urls;
|
||||||
|
}
|
||||||
@@ -13,3 +13,6 @@ $GLOBALS['_view_shared'] = compact('info', 'navbar', 'current_uri_2');
|
|||||||
echo view('include'); // renders view('seo') inside <head>
|
echo view('include'); // renders view('seo') inside <head>
|
||||||
echo view('navbar');
|
echo view('navbar');
|
||||||
echo view('messenger_chat');
|
echo view('messenger_chat');
|
||||||
|
// Page content landmark — closed at the top of site/includes/footer.php, so
|
||||||
|
// every public page gets one <main> (and the skip link a real target).
|
||||||
|
echo '<main id="conteudo">' . "\n";
|
||||||
+165
-1
@@ -581,9 +581,19 @@ section[id] {
|
|||||||
background: var(--fitme-white);
|
background: var(--fitme-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Team backdrop: the warm grey of the gym's block wall in the header photo
|
||||||
|
(sampled ≈ rgb(70,66,62)), a touch darker so white names still pop. On top,
|
||||||
|
very faint mortar joints in running bond (120×60 blocks, alternate rows
|
||||||
|
offset by half a block) plus a fine concrete grain, both as inline SVG
|
||||||
|
tiles, and a soft shade at the top and bottom edges. */
|
||||||
.trainers-section {
|
.trainers-section {
|
||||||
background: var(--fitme-dark);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
background-color: #403d3a;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(180deg, rgba(0, 0, 0, .28) 0%, transparent 18%, transparent 82%, rgba(0, 0, 0, .28) 100%),
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
|
||||||
|
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='120'%3E%3Cpath d='M0 1H240M0 61H240M1 0V60M121 0V60M61 60V120M181 60V120' fill='none' stroke='rgba(0,0,0,0.09)' stroke-width='1.5'/%3E%3Cpath d='M0 3.5H240M0 63.5H240' fill='none' stroke='rgba(255,255,255,0.022)' stroke-width='1'/%3E%3C/svg%3E");
|
||||||
|
background-size: 100% 100%, 200px 200px, 240px 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trainers-section:before {
|
.trainers-section:before {
|
||||||
@@ -623,6 +633,59 @@ section[id] {
|
|||||||
|
|
||||||
.workhours-section {
|
.workhours-section {
|
||||||
background: var(--fitme-white);
|
background: var(--fitme-white);
|
||||||
|
padding: 48px 0 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workhours-section .section-title {
|
||||||
|
margin-bottom: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compact opening-hours cards: dark day label on top, hours underneath,
|
||||||
|
side by side and close together (wraps to a column on phones). */
|
||||||
|
.wh-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-day {
|
||||||
|
flex: 0 1 210px;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--fitme-surface);
|
||||||
|
border: 1px solid var(--fitme-surface-2);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-day dt {
|
||||||
|
background: var(--fitme-dark-3);
|
||||||
|
color: #fff;
|
||||||
|
font-size: .9rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-day dd {
|
||||||
|
margin: 0;
|
||||||
|
padding: 7px 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--fitme-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-day dd + dd {
|
||||||
|
border-top: 1px solid var(--fitme-surface-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wh-day dd.wh-closed {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--fitme-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 575px) {
|
||||||
|
.wh-day { flex-basis: 100%; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-section {
|
.map-section {
|
||||||
@@ -698,6 +761,7 @@ section[id] {
|
|||||||
mix-blend-mode: multiply;
|
mix-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-box-item h3,
|
||||||
.icon-box-item h4 {
|
.icon-box-item h4 {
|
||||||
margin-bottom: .75rem;
|
margin-bottom: .75rem;
|
||||||
font-size: 1.15rem;
|
font-size: 1.15rem;
|
||||||
@@ -819,6 +883,7 @@ section[id] {
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trainer-item h3,
|
||||||
.trainer-item h4 {
|
.trainer-item h4 {
|
||||||
margin-bottom: .3rem;
|
margin-bottom: .3rem;
|
||||||
}
|
}
|
||||||
@@ -835,6 +900,7 @@ section[id] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trainers-section .section-title h2,
|
.trainers-section .section-title h2,
|
||||||
|
.trainers-section .trainer-item h3,
|
||||||
.trainers-section .trainer-item h4,
|
.trainers-section .trainer-item h4,
|
||||||
.trainers-section .trainer-item>*:last-child {
|
.trainers-section .trainer-item>*:last-child {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -1136,10 +1202,16 @@ section[id] {
|
|||||||
margin-bottom: 2.5rem;
|
margin-bottom: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The form heading is an h3 under the section's h2 — keep the h2 look. */
|
||||||
|
h3.contact-title {
|
||||||
|
font-size: 2.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.contact-info-warp {
|
.contact-info-warp {
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contact-info-warp h3,
|
||||||
.contact-info-warp h4 {
|
.contact-info-warp h4 {
|
||||||
color: var(--fitme-accent);
|
color: var(--fitme-accent);
|
||||||
margin-bottom: .5rem;
|
margin-bottom: .5rem;
|
||||||
@@ -2152,6 +2224,7 @@ section[id] {
|
|||||||
max-height: 34px;
|
max-height: 34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-box-item h3,
|
||||||
.icon-box-item h4 {
|
.icon-box-item h4 {
|
||||||
font-size: .95rem;
|
font-size: .95rem;
|
||||||
}
|
}
|
||||||
@@ -2551,6 +2624,96 @@ section[id] {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Horário: compact cards (on screen, every width) ───────────────────────────
|
||||||
|
Smaller, narrower cards and type so a day reads at a glance and three days
|
||||||
|
fit side by side on desktop. The JPG export keeps its own sizing. */
|
||||||
|
.schedule:not(.schedule-export) .schedule_cell {
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: .6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_cell > .schedule_box {
|
||||||
|
flex: 0 1 112px;
|
||||||
|
padding: 6px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_box img {
|
||||||
|
height: 22px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_box a {
|
||||||
|
font-size: 10px;
|
||||||
|
min-height: 2.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_info {
|
||||||
|
margin: auto -3px -6px;
|
||||||
|
padding: 4px 6px;
|
||||||
|
font-size: 11.5px;
|
||||||
|
min-height: 2.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_box:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_dayhead {
|
||||||
|
margin-bottom: .7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .rounded_frame {
|
||||||
|
width: 104px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: .95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_section_label {
|
||||||
|
margin: .5rem 0 .8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule:not(.schedule-export) .schedule_section_label span {
|
||||||
|
font-size: .72rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Desktop: yesterday · today · tomorrow ─────────────────────────────────────
|
||||||
|
≥992px, main.js shows three days — the chosen one (today by default) centred
|
||||||
|
between its neighbours, wrapping round the week — and tags each visible
|
||||||
|
header/cell with .sched-pos-1/2/3 for its column. Rows stay time-aligned, so
|
||||||
|
classes at the same hour line up across the three days. The side days are
|
||||||
|
toned down so the centre one leads. */
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_panel {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 420px));
|
||||||
|
column-gap: 28px;
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_section_label {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .sched-pos-1 { grid-column: 1 !important; }
|
||||||
|
.schedule.is-3day:not(.schedule-export) .sched-pos-2 { grid-column: 2 !important; }
|
||||||
|
.schedule.is-3day:not(.schedule-export) .sched-pos-3 { grid-column: 3 !important; }
|
||||||
|
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_cell.sched-side {
|
||||||
|
opacity: .5;
|
||||||
|
transition: opacity var(--fitme-transition);
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_cell.sched-side:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_dayhead.sched-side .rounded_frame {
|
||||||
|
background: var(--fitme-surface-2);
|
||||||
|
color: var(--fitme-text-muted);
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_dayhead.sched-pos-2 .rounded_frame {
|
||||||
|
background: var(--fitme-accent);
|
||||||
|
color: var(--fitme-dark);
|
||||||
|
}
|
||||||
|
.schedule.is-3day:not(.schedule-export) .schedule_dayhead.sched-side {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Aula experimental modal ───────────────────────────────────────────────── */
|
/* ── Aula experimental modal ───────────────────────────────────────────────── */
|
||||||
.modal-content.trial-modal {
|
.modal-content.trial-modal {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
@@ -2963,6 +3126,7 @@ section[id] {
|
|||||||
/* The name used to be the tile's last child and got its size from the
|
/* The name used to be the tile's last child and got its size from the
|
||||||
`.trainer-item>*:last-child` rule; pin it so it stays the same whether or
|
`.trainer-item>*:last-child` rule; pin it so it stays the same whether or
|
||||||
not a title follows it. */
|
not a title follows it. */
|
||||||
|
.trainers-section .trainer-item h3,
|
||||||
.trainers-section .trainer-item h4 {
|
.trainers-section .trainer-item h4 {
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-9
@@ -152,10 +152,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/* ── Schedule day filter ─────────────────────────────────────────────────────
|
/* ── Schedule day filter ─────────────────────────────────────────────────────
|
||||||
The on-screen schedule shows one day at a time; a day-picker bar switches days
|
The on-screen schedule shows the chosen day (phones) or that day centred
|
||||||
(each header + class cell is tagged with data-day). Defaults to today when the
|
between the day before and after (desktop ≥992px); a day-picker bar switches
|
||||||
gym is open that day, otherwise the first day. The JPG export is unaffected —
|
days (each header + class cell is tagged with data-day). Defaults to today
|
||||||
its clone removes every .sched-hide and re-renders the full week. */
|
when the gym is open that day, otherwise the first day. The JPG export is
|
||||||
|
unaffected — its clone removes every .sched-hide and re-renders the full week. */
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
// Works on the home page (#horario) and the CrossFit page (bare .schedule).
|
// Works on the home page (#horario) and the CrossFit page (bare .schedule).
|
||||||
var scope = document.querySelector('.schedule');
|
var scope = document.querySelector('.schedule');
|
||||||
@@ -166,19 +167,40 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var buttons = filter.querySelectorAll('.sdf-btn');
|
var buttons = filter.querySelectorAll('.sdf-btn');
|
||||||
var labels = scope.querySelectorAll('.schedule_section_label');
|
var labels = scope.querySelectorAll('.schedule_section_label');
|
||||||
|
|
||||||
// Toggle a class (not inline display) — .sched-hide carries !important so it
|
// Desktop shows three days — the chosen one centred between the day before
|
||||||
// reliably wins, and the export clone simply strips it to show every day.
|
// and the day after (wrapping round the week); phones show just the one.
|
||||||
|
var wide = window.matchMedia('(min-width: 992px)');
|
||||||
|
var week = Array.prototype.map.call(buttons, function (b) { return b.getAttribute('data-day'); });
|
||||||
|
var current = null;
|
||||||
|
|
||||||
|
// Toggle classes (not inline display) — .sched-hide carries !important so it
|
||||||
|
// reliably wins, and the export clone simply strips it (and ignores the
|
||||||
|
// .sched-pos-* columns) to show every day.
|
||||||
function showDay(day) {
|
function showDay(day) {
|
||||||
|
current = day;
|
||||||
|
var i = week.indexOf(day), n = week.length;
|
||||||
|
var three = wide.matches && n >= 3;
|
||||||
|
var visible = three ? [week[(i - 1 + n) % n], day, week[(i + 1) % n]] : [day];
|
||||||
|
scope.classList.toggle('is-3day', three);
|
||||||
cells.forEach(function (c) {
|
cells.forEach(function (c) {
|
||||||
c.classList.toggle('sched-hide', c.getAttribute('data-day') !== day);
|
var pos = visible.indexOf(c.getAttribute('data-day'));
|
||||||
|
c.classList.toggle('sched-hide', pos === -1);
|
||||||
|
c.classList.remove('sched-pos-1', 'sched-pos-2', 'sched-pos-3', 'sched-side');
|
||||||
|
if (pos !== -1) {
|
||||||
|
var col = three ? pos + 1 : 1;
|
||||||
|
c.classList.add('sched-pos-' + col);
|
||||||
|
if (three && col !== 2) c.classList.add('sched-side');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
buttons.forEach(function (b) {
|
buttons.forEach(function (b) {
|
||||||
b.classList.toggle('active', b.getAttribute('data-day') === day);
|
b.classList.toggle('active', b.getAttribute('data-day') === day);
|
||||||
});
|
});
|
||||||
// Show a Manhã / Tarde divider only when the day has a class in that block.
|
// Show a Manhã / Tarde divider only when a visible day has a class in that block.
|
||||||
labels.forEach(function (lbl) {
|
labels.forEach(function (lbl) {
|
||||||
var sec = lbl.getAttribute('data-section');
|
var sec = lbl.getAttribute('data-section');
|
||||||
var has = !!scope.querySelector('.schedule_cell[data-day="' + day + '"][data-section="' + sec + '"]');
|
var has = visible.some(function (d) {
|
||||||
|
return !!scope.querySelector('.schedule_cell[data-day="' + d + '"][data-section="' + sec + '"]');
|
||||||
|
});
|
||||||
lbl.classList.toggle('sched-hide', !has);
|
lbl.classList.toggle('sched-hide', !has);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -187,6 +209,13 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var btn = e.target.closest('.sdf-btn');
|
var btn = e.target.closest('.sdf-btn');
|
||||||
if (btn) showDay(btn.getAttribute('data-day'));
|
if (btn) showDay(btn.getAttribute('data-day'));
|
||||||
});
|
});
|
||||||
|
// Clicking a side day's header centres it.
|
||||||
|
scope.addEventListener('click', function (e) {
|
||||||
|
var head = e.target.closest('.schedule_dayhead.sched-side');
|
||||||
|
if (head) showDay(head.getAttribute('data-day'));
|
||||||
|
});
|
||||||
|
var reflow = function () { if (current) showDay(current); };
|
||||||
|
if (wide.addEventListener) wide.addEventListener('change', reflow); else if (wide.addListener) wide.addListener(reflow);
|
||||||
|
|
||||||
// Pre-select today when the schedule has a button for it (PT day names),
|
// Pre-select today when the schedule has a button for it (PT day names),
|
||||||
// otherwise the first day.
|
// otherwise the first day.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
</main><?php /* opened at the end of site/_open.php */ ?>
|
||||||
|
|
||||||
<!-- Footer section -->
|
<!-- Footer section -->
|
||||||
<footer class="footer-section set-bg fade-in"
|
<footer class="footer-section set-bg fade-in"
|
||||||
data-setbg="<?= base_url(($current_uri_2 ?? '') == 'crossfit' ? 'site/assets/img/footer-bg-cf.jpg' : 'site/assets/img/footer-bg-gym.jpg') ?>">
|
data-setbg="<?= base_url(($current_uri_2 ?? '') == 'crossfit' ? 'site/assets/img/footer-bg-cf.jpg' : 'site/assets/img/footer-bg-gym.jpg') ?>">
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ if (!$files || !is_array($files)) $files = [];
|
|||||||
<div id="primary-slider" class="splide" style="padding:0;">
|
<div id="primary-slider" class="splide" style="padding:0;">
|
||||||
<div class="splide__track">
|
<div class="splide__track">
|
||||||
<ul class="splide__list">
|
<ul class="splide__list">
|
||||||
<?php foreach($files as $f): ?>
|
<?php foreach($files as $gi => $f): /* distinct alt per photo — identical alts read as one image */ ?>
|
||||||
<li class="splide__slide"><img src="<?= base_url($f) ?>" alt="Instalações FitMe 3070"></li>
|
<li class="splide__slide"><img src="<?= base_url($f) ?>" alt="<?= htmlspecialchars(($gallery_h2 ?? 'Instalações') . ' — FitMe 3070, foto ' . ($gi + 1)) ?>"<?= $gi > 0 ? ' loading="lazy"' : '' ?>></li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="container h-100">
|
<div class="container h-100">
|
||||||
<div class="d-flex h-100 text-center align-items-center">
|
<div class="d-flex h-100 text-center align-items-center">
|
||||||
<div class="w-100 text-white">
|
<div class="w-100 text-white">
|
||||||
<h1 class="display-3"><img src="<?= base_url('site/assets/img/logos/logo_crossfit_white.svg')?>" alt="CrossFit" style="opacity: .85; max-width: 320px;"></h1>
|
<h1 class="display-3"><img src="<?= base_url('site/assets/img/logos/logo_crossfit_white.svg')?>" alt="CrossFit 3070 — box de CrossFit em Mira" style="opacity: .85; max-width: 320px;"></h1>
|
||||||
<p class="lead mb-0"></p>
|
<p class="lead mb-0"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ $canonical = $GLOBALS['_canonical_override'] ?? base_url($page !== '' ? 'home/'
|
|||||||
<meta name="theme-color" content="#C2D500">
|
<meta name="theme-color" content="#C2D500">
|
||||||
<title><?= htmlspecialchars($page_title) ?></title>
|
<title><?= htmlspecialchars($page_title) ?></title>
|
||||||
<link rel="canonical" href="<?= $canonical ?>">
|
<link rel="canonical" href="<?= $canonical ?>">
|
||||||
|
<?php if (seo_noindex()): /* staging copies (e.g. fitme.andmore.pt) must not compete with the real domain */ ?>
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Preconnect to external origins -->
|
<!-- Preconnect to external origins -->
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
|
||||||
@@ -72,4 +75,4 @@ $canonical = $GLOBALS['_canonical_override'] ?? base_url($page !== '' ? 'home/'
|
|||||||
<?= view('seo') ?>
|
<?= view('seo') ?>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="#home" class="skip-link">Saltar para o conteúdo</a>
|
<a href="#conteudo" class="skip-link">Saltar para o conteúdo</a>
|
||||||
+39
-43
@@ -50,7 +50,6 @@ $reviews = site_reviews(); // null when not configured / nothin
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<span class="hero-brand">FitMe 3070</span>
|
|
||||||
<h1>Ginásio, Box, Aulas<br><span>& Acompanhamento</span></h1>
|
<h1>Ginásio, Box, Aulas<br><span>& Acompanhamento</span></h1>
|
||||||
<div class="hero-cta-row">
|
<div class="hero-cta-row">
|
||||||
<a href="?assunto=insc#contactos" class="site-btn">Inscreve-te Já!</a>
|
<a href="?assunto=insc#contactos" class="site-btn">Inscreve-te Já!</a>
|
||||||
@@ -63,13 +62,13 @@ $reviews = site_reviews(); // null when not configured / nothin
|
|||||||
// ── Oferta (Feature section) ───────────────────────────────────────────────────
|
// ── Oferta (Feature section) ───────────────────────────────────────────────────
|
||||||
if ($offer):
|
if ($offer):
|
||||||
?>
|
?>
|
||||||
<section class="feature-section">
|
<section id="oferta" class="feature-section" aria-labelledby="oferta-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center">
|
<div class="row justify-content-md-center">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="section-title text-center deco">
|
<div class="section-title text-center deco">
|
||||||
<span class="section-eyebrow">FitMe 3070</span>
|
<span class="section-eyebrow">FitMe 3070</span>
|
||||||
<h2>A Nossa Oferta</h2>
|
<h2 id="oferta-title">A Nossa Oferta</h2>
|
||||||
<p class="section-subtitle">Tudo o que precisas para evoluir, num só espaço.</p>
|
<p class="section-subtitle">Tudo o que precisas para evoluir, num só espaço.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +80,7 @@ if ($offer):
|
|||||||
<div class="ib-icon">
|
<div class="ib-icon">
|
||||||
<img loading="lazy" src="<?= site_img_url($o['o_img'], 'uploads/website/offer') ?>" alt="<?= htmlspecialchars((string) $o['o_title']) ?>">
|
<img loading="lazy" src="<?= site_img_url($o['o_img'], 'uploads/website/offer') ?>" alt="<?= htmlspecialchars((string) $o['o_title']) ?>">
|
||||||
</div>
|
</div>
|
||||||
<h4><?= htmlspecialchars((string) $o['o_title']) ?></h4>
|
<h3><?= htmlspecialchars((string) $o['o_title']) ?></h3>
|
||||||
<p><?= htmlspecialchars((string) $o['o_description']) ?></p>
|
<p><?= htmlspecialchars((string) $o['o_description']) ?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,13 +106,13 @@ $gallery_h2 = 'Conhece as nossas instalações';
|
|||||||
// ── Equipa ──────────────────────────────────────────────────────────────────────
|
// ── Equipa ──────────────────────────────────────────────────────────────────────
|
||||||
if ($team):
|
if ($team):
|
||||||
?>
|
?>
|
||||||
<section id="equipa" class="trainers-section">
|
<section id="equipa" class="trainers-section" aria-labelledby="equipa-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center mb-4">
|
<div class="row justify-content-md-center mb-4">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="section-title text-center deco">
|
<div class="section-title text-center deco">
|
||||||
<span class="section-eyebrow">Quem somos</span>
|
<span class="section-eyebrow">Quem somos</span>
|
||||||
<h2>Conhece os membros da equipa 3070</h2>
|
<h2 id="equipa-title">Conhece os membros da equipa 3070</h2>
|
||||||
<p class="section-subtitle">Profissionais dedicados a ajudar-te a alcançar os teus objetivos.</p>
|
<p class="section-subtitle">Profissionais dedicados a ajudar-te a alcançar os teus objetivos.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -137,7 +136,7 @@ if ($team):
|
|||||||
<div class="trainer-pic">
|
<div class="trainer-pic">
|
||||||
<img loading="lazy" src="<?= $t_img ?>" alt="<?= htmlspecialchars((string) $d['name']) ?>">
|
<img loading="lazy" src="<?= $t_img ?>" alt="<?= htmlspecialchars((string) $d['name']) ?>">
|
||||||
</div>
|
</div>
|
||||||
<h4><?= htmlspecialchars((string) $d['name']) ?></h4>
|
<h3><?= htmlspecialchars((string) $d['name']) ?></h3>
|
||||||
<?php if ($t_title !== ''): ?><p class="trainer-title"><?= htmlspecialchars($t_title) ?></p><?php endif; ?>
|
<?php if ($t_title !== ''): ?><p class="trainer-title"><?= htmlspecialchars($t_title) ?></p><?php endif; ?>
|
||||||
<?php if ($t_detail): ?>
|
<?php if ($t_detail): ?>
|
||||||
<div class="trainer-detail" id="<?= $t_id ?>">
|
<div class="trainer-detail" id="<?= $t_id ?>">
|
||||||
@@ -214,14 +213,14 @@ $today_map = [1=>'segunda', 2=>'terça', 3=>'quarta', 4=>'quinta', 5=>'sexta',
|
|||||||
$default_day = $today_map[(int) date('N')] ?? null;
|
$default_day = $today_map[(int) date('N')] ?? null;
|
||||||
if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0]; }
|
if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0]; }
|
||||||
?>
|
?>
|
||||||
<section id="horario" class="schedule-section" style="padding:60px 0;">
|
<section id="horario" class="schedule-section" style="padding:60px 0;" aria-labelledby="horario-title">
|
||||||
<div class="schedule fade-in">
|
<div class="schedule fade-in">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center mb-4">
|
<div class="row justify-content-md-center mb-4">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="section-title text-center deco">
|
<div class="section-title text-center deco">
|
||||||
<span class="section-eyebrow">Calendário</span>
|
<span class="section-eyebrow">Calendário</span>
|
||||||
<h2>Horário de Aulas</h2>
|
<h2 id="horario-title">Horário de Aulas</h2>
|
||||||
<p class="section-subtitle">Planeia a tua semana de treinos connosco.</p>
|
<p class="section-subtitle">Planeia a tua semana de treinos connosco.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mb-2">
|
<div class="text-center mb-2">
|
||||||
@@ -426,13 +425,13 @@ if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0
|
|||||||
// the request as a lead and emails the gym).
|
// the request as a lead and emails the gym).
|
||||||
if ($memberships):
|
if ($memberships):
|
||||||
?>
|
?>
|
||||||
<section id="mensalidades" class="pricing-section">
|
<section id="mensalidades" class="pricing-section" aria-labelledby="mensalidades-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center mb-4">
|
<div class="row justify-content-md-center mb-4">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="section-title text-center deco">
|
<div class="section-title text-center deco">
|
||||||
<span class="section-eyebrow">Mensalidades</span>
|
<span class="section-eyebrow">Mensalidades</span>
|
||||||
<h2>Escolhe o teu plano</h2>
|
<h2 id="mensalidades-title">Escolhe o teu plano</h2>
|
||||||
<p class="section-subtitle">Encontra a mensalidade que encaixa na tua rotina.</p>
|
<p class="section-subtitle">Encontra a mensalidade que encaixa na tua rotina.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -480,13 +479,13 @@ if ($reviews):
|
|||||||
return $out;
|
return $out;
|
||||||
};
|
};
|
||||||
?>
|
?>
|
||||||
<section id="reviews" class="reviews-section">
|
<section id="reviews" class="reviews-section" aria-labelledby="reviews-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center mb-4">
|
<div class="row justify-content-md-center mb-4">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<div class="section-title text-center deco">
|
<div class="section-title text-center deco">
|
||||||
<span class="section-eyebrow">Reviews</span>
|
<span class="section-eyebrow">Reviews</span>
|
||||||
<h2>O que dizem de nós</h2>
|
<h2 id="reviews-title">O que dizem de nós</h2>
|
||||||
<?php if ($reviews['rating'] !== null): ?>
|
<?php if ($reviews['rating'] !== null): ?>
|
||||||
<p class="reviews-summary">
|
<p class="reviews-summary">
|
||||||
<strong><?= number_format((float) $reviews['rating'], 1, ',', '') ?></strong>
|
<strong><?= number_format((float) $reviews['rating'], 1, ',', '') ?></strong>
|
||||||
@@ -539,7 +538,7 @@ if (isset($_GET['assunto'])) {
|
|||||||
$session = session();
|
$session = session();
|
||||||
?>
|
?>
|
||||||
<?php /* contacts-bg.jpg never existed — outside2.jpg is the current photo in img/contactos/ */ ?>
|
<?php /* contacts-bg.jpg never existed — outside2.jpg is the current photo in img/contactos/ */ ?>
|
||||||
<section id="contactos" class="contact-section set-bg" data-setbg="<?= base_url('site/assets/img/contactos/outside2.jpg') ?>">
|
<section id="contactos" class="contact-section set-bg" data-setbg="<?= base_url('site/assets/img/contactos/outside2.jpg') ?>" aria-labelledby="contactos-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<?php if (($_GET['agendar'] ?? '') === 'ok'): ?>
|
<?php if (($_GET['agendar'] ?? '') === 'ok'): ?>
|
||||||
<div class="alert alert-success text-center" role="alert">
|
<div class="alert alert-success text-center" role="alert">
|
||||||
@@ -552,9 +551,9 @@ $session = session();
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<h2 class="contact-title text-center text-md-left">Informações</h2>
|
<h2 id="contactos-title" class="contact-title text-center text-md-left">Informações</h2>
|
||||||
<div class="contact-info-warp text-center text-md-left">
|
<div class="contact-info-warp text-center text-md-left">
|
||||||
<h4>Localização</h4>
|
<h3>Localização</h3>
|
||||||
<div class="contact-info text-center text-md-left">
|
<div class="contact-info text-center text-md-left">
|
||||||
<i class="fas fa-map-marker-alt"></i>
|
<i class="fas fa-map-marker-alt"></i>
|
||||||
<div class="cf-text">
|
<div class="cf-text">
|
||||||
@@ -565,7 +564,7 @@ $session = session();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-info-warp text-center text-md-left">
|
<div class="contact-info-warp text-center text-md-left">
|
||||||
<h4>Telefone</h4>
|
<h3>Telefone</h3>
|
||||||
<div class="contact-info text-center text-md-left">
|
<div class="contact-info text-center text-md-left">
|
||||||
<i class="fas fa-phone-volume"></i>
|
<i class="fas fa-phone-volume"></i>
|
||||||
<div class="cf-text">
|
<div class="cf-text">
|
||||||
@@ -581,7 +580,7 @@ $session = session();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="contact-info-warp text-center text-md-left">
|
<div class="contact-info-warp text-center text-md-left">
|
||||||
<h4>E-mail</h4>
|
<h3>E-mail</h3>
|
||||||
<div class="contact-info">
|
<div class="contact-info">
|
||||||
<i class="fas fa-envelope"></i>
|
<i class="fas fa-envelope"></i>
|
||||||
<div class="cf-text">
|
<div class="cf-text">
|
||||||
@@ -607,8 +606,8 @@ $session = session();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<section id="contact-form">
|
<div id="contact-form">
|
||||||
<h2 class="contact-title text-center text-md-left">Envia-nos uma mensagem</h2>
|
<h3 class="contact-title text-center text-md-left">Envia-nos uma mensagem</h3>
|
||||||
<?php if (isset($_GET['enviado'])): ?>
|
<?php if (isset($_GET['enviado'])): ?>
|
||||||
<div class="alert alert-success" role="alert">
|
<div class="alert alert-success" role="alert">
|
||||||
Mensagem enviada com sucesso! Entraremos em contacto brevemente.
|
Mensagem enviada com sucesso! Entraremos em contacto brevemente.
|
||||||
@@ -639,7 +638,7 @@ $session = session();
|
|||||||
</label>
|
</label>
|
||||||
<button class="site-btn" id="btn_email" type="submit">Enviar Mensagem</button>
|
<button class="site-btn" id="btn_email" type="submit">Enviar Mensagem</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -649,31 +648,27 @@ $session = session();
|
|||||||
// ── Horário de Funcionamento ──────────────────────────────────────────────────
|
// ── Horário de Funcionamento ──────────────────────────────────────────────────
|
||||||
if ($whours):
|
if ($whours):
|
||||||
$work_hours_days = ['Segunda-Sexta'=>'segunda','Sábado'=>'sabado','Domingo/Feriados'=>'domingo'];
|
$work_hours_days = ['Segunda-Sexta'=>'segunda','Sábado'=>'sabado','Domingo/Feriados'=>'domingo'];
|
||||||
|
usort($whours, fn($x, $y) => strcmp((string) $x['open'], (string) $y['open'])); // morning before afternoon
|
||||||
?>
|
?>
|
||||||
<section id="workhours" class="workhours-section" style="padding:40px 0;">
|
<section id="workhours" class="workhours-section" aria-labelledby="workhours-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-md-center mb-4">
|
<div class="section-title text-center deco">
|
||||||
<div class="col-lg-8">
|
<span class="section-eyebrow">Visita-nos</span>
|
||||||
<div class="section-title text-center deco">
|
<h2 id="workhours-title">Horário de Funcionamento</h2>
|
||||||
<span class="section-eyebrow">Visita-nos</span>
|
|
||||||
<h2>Horário de Funcionamento</h2>
|
|
||||||
<p class="section-subtitle">Estamos abertos quando precisas de treinar.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-center">
|
<?php // Compact day / hours cards. A <dl> so the pairs read as data
|
||||||
|
// (label → value) for screen readers and search engines. ?>
|
||||||
|
<dl class="wh-grid">
|
||||||
<?php foreach ($work_hours_days as $key => $value): ?>
|
<?php foreach ($work_hours_days as $key => $value): ?>
|
||||||
<div class="col-md-4 text-center">
|
<div class="wh-day">
|
||||||
<a class="schedule_text rounded_frame_medium mt-3 schedule_frame"><?= $key ?></a>
|
<dt><?= htmlspecialchars($key) ?></dt>
|
||||||
<?php foreach($whours as $h): ?>
|
<?php $any = false; foreach ($whours as $h): if ($h['week_day'] == $value): $any = true; ?>
|
||||||
<?php if($h['week_day'] == $value): ?>
|
<dd><?= htmlspecialchars(substr($h['open'], 0, 5) . ' – ' . substr($h['close'], 0, 5)) ?></dd>
|
||||||
<div class="rounded_frame_grey mt-3">
|
|
||||||
<p><b><?= htmlspecialchars(substr($h['open'], 0, 5) . ' - ' . substr($h['close'], 0, 5)) ?></b></p>
|
|
||||||
</div>
|
|
||||||
<?php endif; endforeach; ?>
|
<?php endif; endforeach; ?>
|
||||||
|
<?php if (!$any): ?><dd class="wh-closed">Encerrado</dd><?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@@ -681,12 +676,12 @@ $work_hours_days = ['Segunda-Sexta'=>'segunda','Sábado'=>'sabado','Domingo/Feri
|
|||||||
<?php
|
<?php
|
||||||
// ── Personal Trainer CTA ────────────────────────────────────────────────────────
|
// ── Personal Trainer CTA ────────────────────────────────────────────────────────
|
||||||
?>
|
?>
|
||||||
<section class="classes-section" data-setbg="">
|
<section id="personal-trainer" class="classes-section" aria-labelledby="pt-title">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<h2>Precisas de um <span>Personal Trainer</span>?</h2>
|
<h2 id="pt-title">Precisas de um <span>Personal Trainer</span>?</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
@@ -814,6 +809,7 @@ if ($memberships):
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
// ── Newsletter + Footer ───────────────────────────────────────────────────────
|
// ── Footer ────────────────────────────────────────────────────────────────────
|
||||||
echo view('newsletter');
|
// Newsletter hidden on request (2026-09); the partial stays in
|
||||||
|
// site/includes/newsletter.php — re-enable with: echo view('newsletter');
|
||||||
echo view('footer');
|
echo view('footer');
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
// robots.txt and sitemap.xml, generated so they always carry this install's
|
||||||
|
// own base URL (the site moves between domains) and honour SEO_NOINDEX.
|
||||||
|
//
|
||||||
|
// Reached via .htaccess: ^robots\.txt$ → ?f=robots, ^sitemap\.xml$ → ?f=sitemap
|
||||||
|
require_once __DIR__ . '/../config/db.php';
|
||||||
|
require_once __DIR__ . '/../config/functions.php';
|
||||||
|
|
||||||
|
$file = (string) ($_GET['f'] ?? '');
|
||||||
|
|
||||||
|
if ($file === 'robots') {
|
||||||
|
header('Content-Type: text/plain; charset=utf-8');
|
||||||
|
echo "User-agent: *\n";
|
||||||
|
if (seo_noindex()) {
|
||||||
|
echo "Disallow: /\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
// Backoffice, endpoints and internals have nothing for a search engine.
|
||||||
|
foreach (['/views/', '/api/', '/shared/', '/config/', '/database/', '/includes/', '/templates/', '/cron.php'] as $p) {
|
||||||
|
echo "Disallow: {$p}\n";
|
||||||
|
}
|
||||||
|
echo "\nSitemap: " . base_url('sitemap.xml') . "\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file === 'sitemap') {
|
||||||
|
if (seo_noindex()) { http_response_code(404); exit; }
|
||||||
|
header('Content-Type: application/xml; charset=utf-8');
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||||
|
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||||
|
foreach (site_sitemap_urls($pdo) as $u) {
|
||||||
|
echo ' <url><loc>' . htmlspecialchars($u['loc'], ENT_XML1) . '</loc><priority>' . $u['priority'] . "</priority></url>\n";
|
||||||
|
}
|
||||||
|
echo "</urlset>\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
http_response_code(404);
|
||||||
Reference in new issue
Block a user