v3.0.0.0
FlatlyPage
- <?php
- error_reporting(E_ALL);
- ini_set('display_errors', 0);
-
- header("X-Powered-By: FlatlyPage CMS");
- header("X-Content-Type-Options: nosniff");
- header("X-Frame-Options: SAMEORIGIN");
- header("X-XSS-Protection: 1; mode=block");
- header("Referrer-Policy: strict-origin-when-cross-origin");
-
- require_once __DIR__ . '/config.php';
- require_once __DIR__ . '/admin/publish-helpers.php';
-
- $slug = isset($_GET['slug']) ? sanitize($_GET['slug']) : '';
-
- define('CURRENT_PAGE', 'product');
- define('CURRENT_PAGE_SLUG', $slug);
-
- $lang_ok = flatly_init_front_lang();
-
- if (empty($slug)) {
- header('Location: ' . BASE_URL . flatly_lang_url(flatly_current_lang(), '/'));
- exit;
- }
-
- $page = null;
- $pages = $lang_ok ? get_all_products() : [];
- foreach ($pages as $p) {
- if ($p['slug'] === $slug) {
- $page = $p;
- break;
- }
- }
-
- if ($page && !is_page_published($page)) {
- $page = null;
- }
-
- if ($page) {
- $page_ref = flatly_split_lang_file_id((string) ($page['id'] ?? ('product-' . $slug)))[1];
- flatly_set_page_ref($page_ref);
- }
-
- $site_settings = get_site_settings();
- $page_title = $page['title'] ?? 'Error 404 - Page not found';
- $page_description = $page['description'] ?? '';
- $lang = isset($site_settings['site_language']) ? $site_settings['site_language'] : 'en';
-
- if ($page) {
- $page_index = $page['index'] ?? 'true';
- $page_follow = $page['follow'] ?? 'true';
- } else {
- $page_index = 'false';
- $page_follow = 'false';
- }
-
- $blocks = $page['blocks'] ?? [];
- $has_newsletter = false;
-
- foreach ($blocks as $block) {
- if (($block['type'] ?? '') === 'newsletter') {
- $has_newsletter = true;
- break;
- }
- }
-
- $nav_links = $site_settings['nav_links'] ?? [];
-
- $nav_buttons = $site_settings['nav_buttons'] ?? [];
- $footer = $site_settings['footer'] ?? [];
- $logo_text = $site_settings['logo_text'] ?? $site_settings['site_name'] ?? 'FlatlyPage';
- $logo_image = $site_settings['logo_image'] ?? '';
-
- $website_font = get_text_font($site_settings);
-
- $search_status_file = dirname(__FILE__) . '/data/search/search.txt';
- $show_search = false;
-
- if (file_exists($search_status_file)) {
- $status_content = trim(file_get_contents($search_status_file));
- if ($status_content === 'true') {
- $show_search = true;
- }
- }
- ?>
- <!-- Powered by FlatlyPage CMS -->
- <!DOCTYPE html>
- <html lang="<?php echo htmlspecialchars($lang); ?>" data-cms="flatlypage">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title><?= e($page_title) ?> - <?= e($site_settings['site_name']) ?></title>
- <meta name="description" content="<?= e($page_description) ?>">
- <meta name="generator" content="FlatlyPage CMS">
- <?= flatly_canonical_link() ?>
- <?= flatly_hreflang_links() ?>
- <?= flatly_language_detect_script() ?>
- <meta name="robots" content="<?= ($page_index === 'true' ? 'index' : 'noindex') ?>, <?= ($page_follow === 'true' ? 'follow' : 'nofollow') ?>">
- <?php if ($page && !empty($page['publish_enabled']) && !empty($page['publish_at_utc'])): ?>
- <meta property="article:published_time" content="<?= e((new DateTime($page['publish_at_utc'], new DateTimeZone('UTC')))->setTimezone(new DateTimeZone($page['publish_timezone'] ?? 'Europe/Warsaw'))->format(DateTime::ATOM)) ?>">
- <?php endif; ?>
- <?php if (!empty($site_settings['favicon'])): ?>
- <link rel="icon" href="<?= e($site_settings['favicon']) ?>">
- <?php endif; ?>
- <?= font_head_html(site_all_fonts($site_settings), [get_site_interface_font($site_settings), $website_font]) ?>
-
- <link rel="stylesheet" href="/css/styles.css?v=<?= filemtime(__DIR__ . '/css/styles.css') ?>">
-
- <?= theme_link_html() ?>
-
- <style>
- <?= site_fonts_css($site_settings) ?>
- </style>
-
- <script type="application/ld+json">
- {
- "@context": "https://schema.org",
- "@type": "WebSite",
- "name": "<?= e($site_settings['site_name'] ?? SITE_NAME) ?>",
- "url": "<?= e(SITE_URL) ?>",
- "description": "<?= e($page_description) ?>",
- "publisher": {
- "@type": "Organization",
- "name": "<?= e($logo_text) ?>"
- }
- }
- </script>
-
- <?= flatly_custom_html('head') ?>
- </head>
-
- <body>
- <?= flatly_custom_html('body_start') ?>
- <nav class="navbar">
- <div class="container navbar-inner">
- <a href="<?= e(flatly_home_url()) ?>" class="logo">
- <?php if (!empty($logo_image)): ?>
- <img src="<?= e($logo_image) ?>" alt="<?= e($logo_text) ?>">
- <?php endif; ?>
- <?= e($logo_text) ?>
- </a>
- <?php if (!empty($nav_links)): ?>
- <div class="nav-links">
- <?php foreach ($nav_links as $link): ?>
- <a href="<?= e($link['url'] ?? '#') ?>"><?= nav_icon_html($link['icon'] ?? '') ?><?= e($link['label'] ?? '') ?></a>
- <?php endforeach; ?>
- </div>
- <?php endif; ?>
-
- <?php if (!empty($nav_buttons) || $show_search): ?>
- <div class="nav-buttons">
- <?php if ($show_search): ?>
- <a href="/search.php" class="btn btn-search" title="Search" style="padding: 8px; display: inline-flex; align-items: center; margin-right: 5px;">
- <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
- <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
- </svg>
- </a>
- <?php endif; ?>
-
- <?php foreach ($nav_buttons as $btn): ?>
- <a href="<?= e($btn['url'] ?? '#') ?>" class="btn btn-<?= e($btn['style'] ?? 'ghost') ?>"><?= nav_icon_html($btn['icon'] ?? '') ?><?= e($btn['label'] ?? '') ?></a>
- <?php endforeach; ?>
- </div>
- <?php endif; ?>
-
- <?= flatly_custom_html('nav') ?>
- <button class="mobile-menu-btn" aria-label="Menu" onclick="document.querySelector('.mobile-nav').classList.toggle('active')">
- <svg width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M4 6h16M4 12h16M4 18h16" />
- </svg>
- </button>
- </div>
- </nav>
-
- <div class="mobile-nav">
- <?php if (!empty($nav_links)): ?>
- <?php foreach ($nav_links as $link): ?>
- <a href="<?= e($link['url'] ?? '#') ?>"><?= nav_icon_html($link['icon'] ?? '') ?><?= e($link['label'] ?? '') ?></a>
- <?php endforeach; ?>
- <?php endif; ?>
-
- <?php if (!empty($nav_buttons)): ?>
- <?php foreach ($nav_buttons as $btn): ?>
- <a href="<?= e($btn['url'] ?? '#') ?>" class="btn btn-<?= e($btn['style'] ?? 'ghost') ?>"><?= nav_icon_html($btn['icon'] ?? '') ?><?= e($btn['label'] ?? '') ?></a>
- <?php endforeach; ?>
- <?php endif; ?>
-
- <?php if ($show_search): ?>
- <a href="/search.php" class="btn btn-search" title="Search" style="padding: 8px; display: inline-flex; align-items: center; margin-right: 5px;">
- <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
- <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
- </svg>
- </a>
- <?php endif; ?>
- </div>
-
- <main>
- <?php if (!$page): ?>
- <section class="hero">
- <div class="hero-grid"></div>
- <div class="container hero-content" style="padding: 40px 0; text-align: center;">
- <h1 style="font-size: 3rem; color: var(--muted);">404</h1>
- <p style="font-size: 1.5rem; margin: 16px 0;">Page not found</p>
- <p style="color: var(--muted); margin-bottom: 32px;">Sorry, we couldn't find the page you're looking for.</p>
- <a href="<?= e(flatly_home_url()) ?>" class="btn btn-primary">Go back home</a>
- </div>
- </section>
-
- <?php else: ?>
- <?php $publish_display = format_publish_datetime($page, false); ?>
- <?php if ($publish_display): ?>
- <div class="container" style="padding-top: 24px;">
- <p class="page-publish-date" style="color: var(--muted); font-size: 0.875rem;">
- Published: <?= e($publish_display) ?>
- </p>
- </div>
- <?php endif; ?>
- <?php if (!empty($blocks)): ?>
- <?php foreach ($blocks as $block):
- echo apply_bbcode(render_block($block));
- endforeach; ?>
- <?php endif; ?>
- <?php endif; ?>
-
- </main>
-
- <footer class="footer">
- <div class="container">
- <div class="footer-grid">
- <div class="footer-brand">
- <h3>
- <?php if (!empty($logo_image)): ?>
- <img src="<?= e($logo_image) ?>" alt="<?= e($logo_text) ?>">
- <?php endif; ?>
- <?= e($logo_text) ?>
- </h3>
- <p><?= e($footer['brand_description'] ?? '') ?></p>
- <?php if (!empty($footer['social_links'])): ?>
- <div class="social-links">
- <?php foreach ($footer['social_links'] as $social): ?>
- <a href="<?= e($social['url'] ?? '#') ?>" aria-label="<?= e(ucfirst($social['platform'] ?? '')) ?>"><?= render_social_icon($social['platform'] ?? 'twitter') ?></a>
- <?php endforeach; ?>
- </div>
- <?php endif; ?>
- </div>
- <?php if (!empty($footer['columns'])): ?>
- <?php foreach ($footer['columns'] as $column): ?>
- <div class="footer-column">
- <h4><?= e($column['title'] ?? '') ?></h4>
- <?php if (!empty($column['links'])): ?>
- <ul>
- <?php foreach ($column['links'] as $link): ?>
- <li><a href="<?= e($link['url'] ?? '#') ?>"><?= e($link['label'] ?? '') ?></a></li>
- <?php endforeach; ?>
- </ul>
- <?php endif; ?>
- </div>
- <?php endforeach; ?>
- <?php endif; ?>
- </div>
- <div class="footer-bottom">
- <div style="flex: 1;">
- <p><?= e($footer['copyright'] ?? '© ' . date('Y') . ' ' . $logo_text . '. All rights reserved.') ?></p>
- <?php if (!empty($footer['bottom_links'])): ?>
- <div class="footer-legal">
- <?php foreach ($footer['bottom_links'] as $link): ?>
- <a href="<?= e($link['url'] ?? '#') ?>"><?= e($link['label'] ?? '') ?></a>
- <?php endforeach; ?>
- </div>
- <?php endif; ?>
- </div>
-
- <?= render_language_switcher() ?>
-
- <button class="theme-toggle" aria-label="Toggle theme" title="Toggle light/dark theme">
- <svg class="theme-icon-sun" viewBox="0 0 24 24" style="display: none;">
- <circle cx="12" cy="12" r="5" />
- <line x1="12" y1="1" x2="12" y2="3" />
- <line x1="12" y1="21" x2="12" y2="23" />
- <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
- <line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
- <line x1="1" y1="12" x2="3" y2="12" />
- <line x1="21" y1="12" x2="23" y2="12" />
- <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
- <line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
- </svg>
- <svg class="theme-icon-moon" viewBox="0 0 24 24" style="display: block;">
- <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
- </svg>
- </button>
- </div>
- </div>
- </footer>
-
- <script>
- const themeToggle = document.querySelector('.theme-toggle');
- const sunIcon = document.querySelector('.theme-icon-sun');
- const moonIcon = document.querySelector('.theme-icon-moon');
- const html = document.documentElement;
-
- function initTheme() {
- let theme = localStorage.getItem('theme');
- if (!theme) {
- const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
- theme = prefersDark ? 'dark' : 'light';
- }
- setTheme(theme);
- }
-
- function setTheme(theme) {
- if (theme === 'light') {
- html.setAttribute('data-theme', 'light');
- sunIcon.style.display = 'block';
- moonIcon.style.display = 'none';
- localStorage.setItem('theme', 'light');
- } else {
- html.removeAttribute('data-theme');
- sunIcon.style.display = 'none';
- moonIcon.style.display = 'block';
- localStorage.setItem('theme', 'dark');
- }
- }
-
- function toggleTheme() {
- const currentTheme = html.getAttribute('data-theme') || 'dark';
- const newTheme = currentTheme === 'light' ? 'dark' : 'light';
- setTheme(newTheme);
- }
-
- if (themeToggle) {
- themeToggle.addEventListener('click', toggleTheme);
- }
-
- initTheme();
-
- document.querySelectorAll('.mobile-nav a').forEach(link => {
- link.addEventListener('click', () => {
- document.querySelector('.mobile-nav').classList.remove('active');
- });
- });
- </script>
-
- <?php if ($has_newsletter): ?>
- <script src="/newsletter/newsletter-form.js?v=<?= date('YmdH') ?>"></script>
- <?php endif; ?>
- <?= flatly_custom_html('body_end') ?>
- <?= flatly_custom_js() ?>
- </body>
-
- </html>