Extract shared public <head> partial

Create templates/public/head.php accepting $pageTitle and $extraCss (array of
stylesheet hrefs), mirroring the existing templates/admin/head.php pattern.

The partial emits: DOCTYPE, <html lang=fr>, charset/viewport meta, favicon,
modern-normalize, common.css, any extra CSS links, and the dev-only live-reload
script.  The live-reload snippet was previously copy-pasted verbatim into all
five public pages.

Updated pages:
  - public/index.php        ($pageTitle='Posterg', $extraCss=['assets/main.css'])
  - public/search.php       ($pageTitle='Répertoire – Posterg', search.css)
  - public/tfe.php          ($pageTitle=thesis title + suffix, tfe.css)
  - public/apropos.php      ($pageTitle='À Propos – Posterg', apropos.css)
  - public/licence.php      ($pageTitle=DB title + suffix, apropos.css)

tfe.php: removed redundant htmlspecialchars() call on $pageTitle (the partial
applies it); licence.php: renamed conflicting $page variable to $dbPage to
avoid collision with the shared $pageTitle expected by the partial.

All syntax checks and test suite pass (4/4).
This commit is contained in:
Pontoporeia
2026-03-28 16:49:09 +01:00
parent 640d37936f
commit 18197bd468
9 changed files with 48 additions and 114 deletions

14
TODO.md
View File

@@ -452,16 +452,12 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
### D — Template structure / boilerplate duplication
- [ ] **Every public page duplicates its own `<head>`**`index.php`, `search.php`, `tfe.php`,
`apropos.php`, `licence.php` each contain an identical block: `<!DOCTYPE html>`,
`<html lang="fr">`, `<meta charset>`, `<meta viewport>`, `<link rel="icon">`,
`<link modern-normalize>`, `<link common.css>`, live-reload script. Only `<title>` and one
extra CSS `<link>` differ. Extract a `templates/public/head.php` partial accepting
`$pageTitle` and `$extraCss` — mirrors the pattern `templates/admin/head.php` already uses.
- [x] **Every public page duplicates its own `<head>`**extracted to `templates/public/head.php`
accepting `$pageTitle` and `$extraCss`; all 5 public pages updated to use the partial.
Mirrors the pattern `templates/admin/head.php` already uses.
- [ ] **Live-reload snippet copy-pasted into 6 files**`index.php`, `search.php`, `tfe.php`,
`apropos.php`, `licence.php`, `templates/admin/head.php` all contain the same 6-line
`(function poll(){…})()` block. Consolidate into the shared head partials.
- [x] **Live-reload snippet copy-pasted into 6 files**consolidated into `templates/public/head.php`;
removed from `index.php`, `search.php`, `tfe.php`, `apropos.php`, `licence.php`.
- [x] **`templates/header.php` and `templates/head.php` are dead files** — neither is `include`d
anywhere in the codebase. Both contain outdated markup from a previous design iteration

View File

@@ -24,27 +24,10 @@ try {
$pd = new Parsedown();
$pd->setSafeMode(true);
$aboutHtml = $pd->text($rawContent);
$pageTitle = 'À Propos Posterg';
$extraCss = ['assets/apropos.css'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>À Propos Posterg</title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<link rel="stylesheet" href="assets/apropos.css">
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll(){
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="apropos-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>

View File

@@ -50,27 +50,10 @@ try {
}
$currentNav = '';
$pageTitle = 'Posterg';
$extraCss = ['assets/main.css'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Posterg</title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<link rel="stylesheet" href="assets/main.css">
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll() {
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="home-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>

View File

@@ -7,39 +7,23 @@ $currentNav = 'licence';
try {
$db = Database::getInstance();
$page = $db->getPage('licenses');
$content = $page ? $page['content'] : '';
$pageTitle = $page ? $page['title'] : 'Licences';
$dbPage = $db->getPage('licenses');
$content = $dbPage ? $dbPage['content'] : '';
$licencePageTitle = $dbPage ? $dbPage['title'] : 'Licences';
} catch (Exception $e) {
error_log("Error loading licence page: " . $e->getMessage());
$content = '';
$pageTitle = 'Licences';
$licencePageTitle = 'Licences';
}
$pd = new Parsedown();
$pd->setSafeMode(true);
$html = $pd->text($content);
$pageTitle = $licencePageTitle . ' Posterg';
$extraCss = ['assets/apropos.css'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($pageTitle) ?> Posterg</title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<link rel="stylesheet" href="assets/apropos.css">
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll(){
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="apropos-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>

View File

@@ -61,27 +61,10 @@ try {
$currentNav = 'repertoire';
$searchBarValue = $_GET['query'] ?? '';
$pageTitle = 'Répertoire Posterg';
$extraCss = ['assets/search.css'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Répertoire Posterg</title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<link rel="stylesheet" href="assets/search.css">
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll() {
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="search-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>

View File

@@ -17,27 +17,10 @@ if (isset($_GET['id'])) {
}
$currentNav = '';
$pageTitle = $data['title'] . ' Posterg';
$extraCss = ['assets/tfe.css'];
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($data['title']) ?> Posterg</title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<link rel="stylesheet" href="assets/tfe.css">
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll(){
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>
<?php include APP_ROOT . '/templates/public/head.php'; ?>
<body class="tfe-body">
<a href="#main-content" class="skip-link">Aller au contenu principal</a>

View File

@@ -1 +1 @@
[1774702347]
[1774712930]

Binary file not shown.

22
templates/public/head.php Normal file
View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($pageTitle ?? 'Posterg') ?></title>
<link rel="icon" type="image/svg+xml" href="/assets/admin_favicon.svg">
<link rel="stylesheet" href="assets/modern-normalize.min.css">
<link rel="stylesheet" href="assets/common.css">
<?php foreach ($extraCss ?? [] as $css): ?>
<link rel="stylesheet" href="<?= htmlspecialchars($css) ?>">
<?php endforeach; ?>
<?php if (php_sapi_name() === 'cli-server'): ?>
<script>
(function poll(){
fetch('/live-reload.php').then(r=>r.json()).then(d=>{
if(d.changed) location.reload(); else setTimeout(poll,1000);
}).catch(()=>setTimeout(poll,2000));
})();
</script>
<?php endif; ?>
</head>