partials.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. /**
  3. * Shared HTML fragments for the public site and the admin backoffice.
  4. * All pages sit directly in public/ or public/admin/, so asset paths are
  5. * passed as a relative $base ('' for public pages, '../' for admin pages).
  6. */
  7. declare(strict_types=1);
  8. function public_header(string $title, string $active = '', string $bodyClass = ''): void
  9. {
  10. $site = site_get();
  11. $name = $site['intro_title'] ?: config('site.name', 'Portfolio');
  12. ?><!DOCTYPE html>
  13. <html lang="en">
  14. <head>
  15. <meta charset="utf-8">
  16. <meta name="viewport" content="width=device-width, initial-scale=1">
  17. <title><?= e($title) ?></title>
  18. <link rel="stylesheet" href="assets/site.css">
  19. </head>
  20. <body class="<?= e($bodyClass) ?>">
  21. <header class="nav" id="nav">
  22. <a class="nav-brand" href="./"><?= e($name) ?></a>
  23. <nav class="nav-links">
  24. <a href="./" class="<?= $active === 'home' ? 'active' : '' ?>">Home</a>
  25. <a href="showreel.php" class="<?= $active === 'showreel' ? 'active' : '' ?>">Showreel</a>
  26. </nav>
  27. </header>
  28. <?php
  29. }
  30. function public_footer(): void
  31. {
  32. ?><footer class="footer">
  33. <span>&copy; <?= date('Y') ?> <?= e(site_get()['intro_title'] ?: config('site.name', '')) ?></span>
  34. </footer>
  35. <script src="assets/site.js"></script>
  36. </body>
  37. </html>
  38. <?php
  39. }
  40. function admin_header(string $title, string $active = ''): void
  41. {
  42. ?><!DOCTYPE html>
  43. <html lang="en">
  44. <head>
  45. <meta charset="utf-8">
  46. <meta name="viewport" content="width=device-width, initial-scale=1">
  47. <title><?= e($title) ?> · Admin</title>
  48. <link rel="stylesheet" href="../assets/site.css">
  49. </head>
  50. <body class="admin">
  51. <header class="admin-nav">
  52. <a class="nav-brand" href="index.php">Backoffice</a>
  53. <nav class="nav-links">
  54. <a href="frontpage.php" class="<?= $active === 'frontpage' ? 'active' : '' ?>">Front page</a>
  55. <a href="showreel.php" class="<?= $active === 'showreel' ? 'active' : '' ?>">Showreel</a>
  56. <a href="galleries.php" class="<?= $active === 'galleries' ? 'active' : '' ?>">Galleries</a>
  57. <a href="settings.php" class="<?= $active === 'settings' ? 'active' : '' ?>">Settings</a>
  58. <a href="../" target="_blank" rel="noopener">View site ↗</a>
  59. <a href="logout.php">Log out</a>
  60. </nav>
  61. </header>
  62. <main class="admin-main">
  63. <?php
  64. }
  65. function admin_footer(): void
  66. {
  67. ?></main>
  68. </body>
  69. </html>
  70. <?php
  71. }
  72. /** One-shot status message helpers (flash messages via session). */
  73. function flash_set(string $msg, string $kind = 'ok'): void
  74. {
  75. session_boot();
  76. $_SESSION['flash'] = ['msg' => $msg, 'kind' => $kind];
  77. }
  78. function flash_render(): void
  79. {
  80. session_boot();
  81. if (!empty($_SESSION['flash'])) {
  82. $f = $_SESSION['flash'];
  83. unset($_SESSION['flash']);
  84. echo '<div class="flash flash-' . e($f['kind']) . '">' . e($f['msg']) . '</div>';
  85. }
  86. }