mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
docs: frontend & template audit — add sections D–H to TODO.md
Analysed all public pages, CSS files, and template partials. Found: Template structure (D): - <head> boilerplate duplicated across 5 public pages (no shared partial exists) - Live-reload snippet copy-pasted into 6 files - templates/header.php and templates/head.php are dead/orphaned files - public/assets/icons.svg is a dead TrumboWYG sprite (never referenced, ~15 KB) - admin_favicon.svg used as public favicon (misleading naming) CSS (E): - html/body reset block repeated in 4 page stylesheets; belongs in common.css - @font-face missing font-display:swap (FOIT risk) - Search pagination is fully inline-styled; home page already has .pagination-btn classes - Multiple one-off inline styles across tfe.php, edit.php, index.php - .site-nav__right is a CSS duplicate of .site-nav__link - .site-nav__link--active applied in PHP but has no CSS rule (invisible active state) Template logic (F): - 429 rate-limit response is bare unstyled HTML - apropos.php contacts/credits hardcoded (require code deploy to change) - licence.php wastes half the viewport with an always-empty right column Accessibility (G): - <nav> has no aria-label; search <form> has no accessible name - No <meta name=description> on any public page - No Open Graph tags anywhere (blank previews when sharing thesis links) Minor (H): - thanks.php duplicates getThesisFiles() with a raw query - admin/index.php stats broken when filters are active (PHP array_filter on subset)
This commit is contained in:
115
TODO.md
115
TODO.md
@@ -447,3 +447,118 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
||||
- [ ] **`__wakeup()` singleton guard throws from a public method** — PHP 8.x deprecates
|
||||
throwing exceptions from `__wakeup`. Change to `trigger_error(…, E_USER_ERROR)` or implement
|
||||
`__serialize()`/`__unserialize()` that always throw.
|
||||
|
||||
---
|
||||
|
||||
## Refactor & Maintenance — Templates & Frontend (audit 2026-03-26)
|
||||
|
||||
### 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.
|
||||
|
||||
- [ ] **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.
|
||||
|
||||
- [ ] **`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
|
||||
(`lang="en"`, empty author meta, a broken nav with double-quoted `href` attributes inside
|
||||
`href`). Delete both to remove confusion.
|
||||
|
||||
- [ ] **`public/assets/icons.svg` is dead** — it is the full TrumboWYG editor icon sprite (40+
|
||||
symbols) referenced **nowhere** in the codebase. The only WYSIWYG editor in use (EasyMDE
|
||||
in `pages-edit.php`) loads from CDN. Delete `icons.svg` (~15 KB of noise).
|
||||
|
||||
- [ ] **`admin_favicon.svg` used as the public-facing favicon** — every public page links
|
||||
`/assets/admin_favicon.svg`. Rename or create a distinct `favicon.svg` so admin and public
|
||||
can diverge without naming confusion.
|
||||
|
||||
### E — CSS architecture
|
||||
|
||||
- [ ] **`html, body { margin:0; padding:0; height:100% }` repeated in 4 page stylesheets** —
|
||||
`main.css`, `search.css`, `tfe.css`, `apropos.css` all open with this identical block.
|
||||
Move it to `common.css` once; delete from the four files. Same for the body-level flex-column
|
||||
shell (`display:flex; flex-direction:column; background:var(--white)`) which only differs in
|
||||
the BEM class name applied to `<body>`.
|
||||
|
||||
- [ ] **No `font-display` on the `Combinedd.otf` custom font** — `common.css` declares `@font-face`
|
||||
with no `font-display` property; the browser blocks text rendering until the font loads (FOIT).
|
||||
Add `font-display: swap`. Also add a `<link rel="preload">` for the font file in the shared
|
||||
head partial once it exists.
|
||||
|
||||
- [ ] **Search results pagination is fully inline-styled** — `search.php` lines 159–164 apply
|
||||
`style="padding:.25rem .7rem;border:1px solid #ddd;…"` and hardcoded `#ddd`/`#666`. The home
|
||||
page (`index.php`) already has `.pagination-btn` / `.pagination-info` in `main.css`. Reuse
|
||||
those classes in `search.php` and remove the inline styles.
|
||||
|
||||
- [ ] **Scattered inline styles in templates** — notable instances that should become named classes:
|
||||
- `tfe.php` line 146: `style="align-items:start;"` → `.tfe-meta-item--top` in `tfe.css`
|
||||
- `tfe.php` lines 148, 170–172, 193: `font-style:italic`, `margin-top:1.5rem`,
|
||||
`font-size:.88rem;color:#666`, `color:#999;font-style:italic` → `.tfe-note-value`,
|
||||
`.tfe-back-link`, `.tfe-restricted` in `tfe.css`
|
||||
- `admin/edit.php`: multiple `style=` on `.admin-form-row` and banner preview → modifier
|
||||
classes in `admin.css`
|
||||
- `index.php` line 146: `style="padding:2rem;color:#666;"` → `.cards-empty` in `main.css`
|
||||
|
||||
- [ ] **`.site-nav__right` is a duplicate of `.site-nav__link`** — `common.css` defines both with
|
||||
identical declarations (font-size, letter-spacing, text-transform, color, opacity, transition).
|
||||
The only difference is DOM position. Merge `.site-nav__right` into `.site-nav__link`; let the
|
||||
flex layout position it via `margin-left:auto` or DOM order.
|
||||
|
||||
- [ ] **`.site-nav__link--active` is applied in `nav.php` but never defined in CSS** — the class
|
||||
is set conditionally but has no corresponding rule in `common.css`, so the active state is
|
||||
invisible. Add a visible style (e.g. `opacity:1; border-bottom:1px solid rgba(255,255,255,.6)`)
|
||||
or remove the conditional.
|
||||
|
||||
### F — Template logic / PHP in templates
|
||||
|
||||
- [ ] **Rate-limit 429 response in `search.php` emits unstyled bare HTML** — the early-exit block
|
||||
outputs `<!DOCTYPE html><html><body><h1>Trop de requêtes</h1>…` with no stylesheet, no lang,
|
||||
no viewport meta. Style it inline-minimally or redirect to a consistent `429.php` page (like
|
||||
`maintenance.php`).
|
||||
|
||||
- [ ] **`apropos.php` contacts and credits are hardcoded in the template** — names, roles, emails
|
||||
(Laurent Leprince, Xavier Gorgol, Brigitte Ledune) and credits text live in PHP/HTML and
|
||||
require a code deploy to change. Either move them into the `about` page Markdown (admin-
|
||||
editable) or extract to a config array so they are in one place.
|
||||
|
||||
- [ ] **`licence.php` wastes half the viewport with an always-empty right column** — the page
|
||||
reuses the two-column `.apropos-layout` but `<div class="apropos-right"></div>` is always
|
||||
empty. Add a `.apropos-layout--single` variant (or just `grid-template-columns:1fr` when
|
||||
the right child is empty) to use the full width for content.
|
||||
|
||||
### G — Accessibility & semantics
|
||||
|
||||
- [ ] **`<nav>` in `nav.php` has no `aria-label`** — pages have multiple landmark regions (main
|
||||
nav, search `<form>`, pagination). Add `aria-label="Navigation principale"` to the `<nav>`
|
||||
and `aria-label="Pagination"` to pagination wrappers so screen readers can distinguish them.
|
||||
|
||||
- [ ] **Search bar `<form>` has no accessible name** — `search-bar.php` has no `aria-label` on the
|
||||
`<form>` and no `<label>` for the input (only a placeholder). Add `aria-label="Recherche"` to
|
||||
the `<form>` element.
|
||||
|
||||
- [ ] **No `<meta name="description">` on any public page** — all public pages omit the description
|
||||
meta tag (the dead `templates/head.php` had `content=""`). Add per-page descriptions:
|
||||
site blurb for `index.php`, synopsis excerpt for `tfe.php`, page content intro for
|
||||
`apropos.php`/`licence.php`. Necessary for search indexing and link preview cards.
|
||||
|
||||
- [ ] **No Open Graph tags** — `tfe.php` is the ideal candidate for `og:title`, `og:description`
|
||||
(synopsis), `og:image` (banner or cover path through `/media.php`), `og:type=article`.
|
||||
Without them, sharing a thesis link on social media or messaging apps shows a blank preview.
|
||||
|
||||
### H — Minor / low-hanging fruit
|
||||
|
||||
- [ ] **`admin/thanks.php` duplicates `getThesisFiles()` with a raw PDO query** — lines 34–40
|
||||
manually prepare `SELECT … FROM thesis_files WHERE thesis_id = ?` instead of calling
|
||||
`$db->getThesisFiles($thesisId)` which already exists. Replace with the DB method.
|
||||
|
||||
- [ ] **`admin/index.php` stats computed via PHP `array_filter` on full result set** — "total",
|
||||
"publiés", "en attente" counts are derived by filtering the already-fetched `$theses` array
|
||||
in PHP. When a filter is active the stats reflect only filtered rows, which is misleading.
|
||||
Add `Database::getThesesStats(): array` returning three counts from SQL
|
||||
(`COUNT(*)`, `SUM(is_published)`, `SUM(1-is_published)`) so they always reflect the full DB.
|
||||
|
||||
Reference in New Issue
Block a user