mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
CSS: .site-search → header form[role="search"],
.site-search__icon → header form[role="search"] svg,
.site-search__input → header form[role="search"] input,
.site-search__input::placeholder → header form[role="search"] input::placeholder
HTML: Removed class="site-search", class="site-search__icon", and
class="site-search__input" from header.php and search-bar.php.
The form already uses role="search" and contains a single svg + input,
so the semantic selectors are unambiguous.
8.8 KiB
8.8 KiB
TODO
Template Simplification — Remove Custom Classes Where Semantic HTML Suffices
CSS class audit: replace with semantic selectors
admin.css: Replace.admin-mainwith.admin-body main— only one<main>per pageadmin.css: Replace.admin-page-titlewith.admin-body main > h1— always the firsth1in<main>admin.css: Replace.admin-alert/.admin-alert--error/.admin-alert--successwith[role="alert"]or.admin-body main > .alertusingdata-type="error|success"attribute instead of modifier classesadmin.css: Replace.admin-form-rowwith.admin-body form > divor.admin-body form > .row— form rows are always direct<div>children of<form>admin.css: Replace.admin-labelwith.admin-body form label— every label in admin formsadmin.css: Replace.admin-input/.admin-select/.admin-textareawith.admin-body form input[type="text"],.admin-body form select,.admin-body form textarea— leverage native element selectorsadmin.css: Replace.admin-hintwith.admin-body form small— use<small>instead of<p class="admin-hint">admin.css: Replace.admin-tablewith.admin-body table— only one table per admin pageadmin.css: Replace.admin-fieldset/.admin-fieldset-legendwith.admin-body fieldset/.admin-body legendmain.css: Replace.card__captionwith.home-body .cards-container li por targetli > a > pdirectlymain.css: Replace.card__mediawith.home-body figure— already uses<figure>elementstfe.css: Replace.tfe-meta-listselectors witharticle dl,article dt,article dd— already using<dl>inside<article>tfe.css: Replace.tfe-media-blockwithaside figure— already wrapped in<figure>inside<aside>tfe.css: Replace.tfe-file-captionwithaside figcaption— native<figcaption>elementsearch.css: Replace.repertoire-col > h2styling — already targetssection > h2, can use.repertoire-index section > h2common.css: Replace.site-search__iconwithheader form[role="search"] svgcommon.css: Replace.site-search__inputwithheader form[role="search"] inputcommon.css: Replace.site-searchwithheader form[role="search"]system.php: Move inline<style>block tosystem.css(already in TODO, reinforced here)
Template HTML changes to match
- In all admin templates, replace
<p class="admin-hint">with<small>elements - In
tfe.php, removeclass="tfe-meta-list"— target viaarticle dl - In
tfe.php, removeclass="tfe-media-block"— target viaaside figure - In
tfe.php, removeclass="tfe-file-caption"— target viaaside figcaption - In
index.php, removeclass="card__caption"— target viali > a > p - In
search-bar.phpandheader.php, removeclass="site-search",class="site-search__icon"andclass="site-search__input"
PHP Components (Reusable Partials/Includes)
PHP has no component system, but include/require with variable scoping works as partials. These are already used (head.php, header.php, footer.php, flash-messages.php). New partials to extract:
Form field partials — templates/partials/form/
text-field.php— accepts$name,$label,$value,$required,$placeholder,$hint; renders the<div>…<label>…<input>…<small>pattern used ~15 times acrossadd.phpandedit.phpselect-field.php— accepts$name,$label,$options[],$selected,$required; renders<div>…<label>…<select>…</div>pattern used ~6 timescheckbox-list.php— accepts$name,$label,$options[],$checked[]; renders the checkbox group pattern (languages, formats) used ~4 times acrossadd.phpandedit.phpfile-field.php— accepts$name,$label,$accept,$hint,$multiple; renders file input pattern used 3 timesjury-fieldset.php— the entire jury composition fieldset + JS is duplicated verbatim betweenadd.phpandedit.php; extract into one partial accepting$juryPresident,$juryPromoteur,$juryPromoteurExt,$juryLecteurs[]
Shared UI partials — templates/partials/
pagination.php— pagination nav is duplicated betweenindex.phpandsearch.phpwith minor variations; unify into one partial accepting$page,$totalPages,$baseParams[]status-badge.php— the published/pending badge + access badge pattern is repeated inindex.phpadmin table rows; extract into a partialadmin-alert.php— rename/mergeflash-messages.phpto also handle the 3 different legacy flash key patterns ($_SESSION['error'],$_SESSION['admin_error'],$_SESSION['edit_error'], etc.) that pages still consume manually instead of viaApp::consumeFlash()
System Page Caching — Database-Backed Status Cache
Problem
The admin system page (/admin/system.php) runs expensive operations on every load:
systemctlsubprocess calls (~4 checks × ~100ms each)curlHTTP self-check (~200-500ms)disk_total_space()/disk_free_space()(fast but unnecessary per-request)- Log file
tail+filesize+filemtime(I/O bound) - Nginx config file reading
Solution: system_cache table + background refresh
- Add
system_cachetable to schema:CREATE TABLE system_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at INTEGER NOT NULL)— stores JSON-encoded status snapshots keyed by section - Add migration
storage/migrations/007_system_cache.sqlto create the table - Add
SystemCacheclass (src/SystemCache.php) with methods:get(string $key, int $maxAgeSec = 60): ?array— returns cached JSON data if fresh, null if staleset(string $key, array $data): void— upserts cache rowisStale(string $key, int $maxAgeSec = 60): bool
- Refactor
system.phpstatus section to:- Check
SystemCache::get('system_status', 120)— 2-minute TTL - If cache hit → render from cache, show "mis en cache il y a X sec" label
- If cache miss → run checks, store in cache, render
- Add
?refresh=1GET param to force-bypass cache
- Check
- Refactor
system.phplog sections to not cache (logs should always be live) but avoid re-reading on every tab switch — only read the active tab's log - Cache disk info separately with 5-minute TTL:
SystemCache::get('disk_info', 300) - Cache PHP info separately with 1-hour TTL:
SystemCache::get('php_info', 3600)— PHP config doesn't change at runtime
In Progress (from previous plan)
- Extract
SearchController— most complex public page (§2 step 4) - Extract
SystemController— biggest single-file win, 500→8 lines (§2 step 3, §5) - Extract
ThesisEditController— merges edit.php + actions/edit.php, deduplicate jury fieldset (§2 step 5) - Extract remaining controllers one by one (§2 step 6)
- Consolidate action handlers into controller methods (§4)
- Introduce pagination partial
templates/partials/pagination.php(§6) - Introduce admin form partials: select-field, checkbox-list, jury-fieldset (§6)
- Unify flash message keys project-wide to
_flash_error/_flash_success(§7) - Move OG tag construction into controller logic (§8)
- Extract inline CSS/JS from
system.phpinto separate assets (§5)
Completed
- Create
src/App.php— boot, adminGuard, verifyCsrf, rotateCsrf, redirect, flash, consumeFlash, render - Auto-load
App.phpfromconfig/bootstrap.php - Create
templates/partials/flash-messages.php— unified flash partial with legacy key drain - Merge public and admin head/nav templates into unified
templates/head.phpandtemplates/header.phptemplates/head.php— outputs<!DOCTYPE html>…</head><body class="…">, reads$bodyClass,$isAdmin; handles admin title suffix, admin.css prepend, and OG tag suppression internallytemplates/header.php— outputs<header>…</header>with public nav + search bar or admin nav depending on$isAdmin- Deleted:
templates/public/head.php,templates/admin/head.php,templates/nav.php,templates/admin/nav.php - All 11 admin pages and 5 public pages updated to set
$bodyClass/$isAdminand include new templates
- Replace nav/header BEM custom classes with semantic HTML targeting in CSS
common.css:.site-nav→header nav,.site-nav__logo→header nav > a, etc.admin.css:.admin-nav→.admin-body header nav, logout via[data-nav-logout]attribute
- PHP vs Flask architecture analysis (
ANALYSIS_PHP_VS_FLASK.md) - Refactoring recommendations for controller/template separation (
REFACTORING_RECOMMENDATIONS.md)