Replace every <img src="/assets/icons/..."> with <?= icon('name') ?>
across 26 template files. The PHP helper inlines the SVG markup into the
DOM so CSS color cascades naturally through fill="currentColor".
- Add src/icon.php helper: reads SVG file, sets width/height to 1em,
injects aria-hidden, supports optional CSS class
- Fix 12 icon SVGs that had hardcoded fill="#000000" or missing fill attr
- Replace search.svg with Phosphor fill-based magnifying glass
- Add explicit SVG sizes for admin header nav icons (16px/20px)
- Scope public search icon CSS to form[role=search]:not(.header-search-form)
to avoid breaking admin header layout; change stroke to fill
- Remove <img> filter: brightness(0) invert(1) hacks from admin.css
Unify the three public pages (à propos, charte, licence) onto a single
grid layout (.page-content) with sticky TOC sidebar, replacing the old
separate / / markup.
- Merge about.php, charte.php, licence.php templates into shared
.page-content / .content-section structure
- Add CommonMark HeadingPermalinkExtension for stable heading anchors
- Use SlugNormalizer for TOC links so they match rendered heading IDs
- Standardize link styling across content blocks: bold black, accent on
hover (consistent with global link style)
- Fix code block wrapping: use pre-wrap instead of pre, constrain grid
columns with min-width:0, auto scrollbar
- Fix apropos page grid placement: force content-section into column 2
so contacts and credits stay in the content area, not the sidebar
Also includes accumulated WIP changes:
- Header gradient: hardcoded purple-to-green (replaces CSS variables)
- Search placeholder font
- Duration field: replace minutes/sec/heures with h:m:s time inputs
- TFE file optional for formats 1,4,6 with client-side JS toggle
- Licence form: em-dash to hyphen, details/summary classes
- Pill search: block Enter key form submission when no results
- Draft autosave: remove CSRF rotation (broke concurrent FilePond uploads)
- Language pill: clear hints for excluded main languages
- Search results: gradient placeholder cards for items without covers
- TFE display: format durée values as XhYm instead of decimal
WCAG 3.3.1 (Error Identification): failing fields now get
aria-errormessage pointing to the flash-error container and
aria-invalid="true". WCAG 3.3.3 (Error Suggestion): <small>
hint text on inputs, selects, and file fields is now linked via
aria-describedby (always, not just on error).
Changes:
- text-field.php, select-field.php, checkbox-list.php: accept
$errorFieldName; add aria-errormessage/aria-invalid on match;
add id to <small> and aria-describedby on the control
- fieldset-tfe-info.php: aria-invalid on synopsis textarea
- fichiers-fragment.php: aria-describedby on cover, note
d'intention, TFE, annexes, and website inputs; aria-invalid
on format checkboxes when error matches 'formats'
- form.php: id="flash-error" + tabindex="-1" on flash-error
div; accept $errorFieldName from callers
- admin/add.php: set $errorFieldName, wire $withAutofocusFn
(was identity default)
- admin/edit.php: set $errorFieldName
- partage/index.php: consume autofocus field, wire autofocus
function, add App::flashAutofocus() in submit catch block
Also fixes WCAG standards issue: removed invalid 'required'
HTML attribute from <fieldset> elements in checkbox-list.php
and fichiers-fragment.php (only aria-required stays). Added
role="group" for explicit ARIA semantics.
- Identifiant: mise à jour automatique quand l'année change en back-office (updateThesis + ThesisEditController)
- Contact: hint enrichi (1 seul contact, formatage Instagram/Mastodon)
- Fichiers: TFE rendu optionnel pour Site web/Performance/Installation (note d'intention reste obligatoire)
1. note_intention: Delete old file only when a genuinely new upload arrives
(32-char hex file_id), not when the FilePond pool preserves an existing
file by sending its DB integer ID. Previously the DB integer ID
triggered $hasNewNote=true, which deleted the existing note_intention
from disk+DB, then handleFilePondSingleFile couldn't re-process it
because the regex requires a hex pattern. Same fix applied to cover.
2. All file deletions now use deleteThesisFileToTrash() which renames
files to tmp/_trash/ instead of unlinking. The trash preserves
original filenames prefixed with DB id for traceability. Skips
website URLs and PeerTube refs (no disk file).
3. Storage prefix changed from theses/ to documents/ to reflect that
the folder holds all document types (determined by file_type in DB).
MediaController visibility gate supports both prefixes for backward
compat with existing files.
4. File browser + relink feature for orphaned files:
- /admin/fragments/file-browser.php — HTMX tree browser for
storage/documents/ and storage/theses/
- /admin/actions/filepond/relink.php — POST endpoint that inserts
a thesis_files row pointing to existing on-disk file
- Per-pool "📂 Relier" buttons (edit mode only)
- JS: XamxamOpenFileBrowser / XamxamRelinkFile with FilePond integration
- CSS: .relink-modal dialog + .file-browser tree styles
* Move shared `fichiers-fragment.php` from `partage/` to `templates/partials/form/`
and update all include/require references
* `.gitignore`: exclude SQLite WAL/SHM journal files
* FilePond UI:
* change uploaded file block border state from yellow to green
* restyle image previews to use site light-theme colors
* Edit mode:
* remove custom existing-file preview list implementation
* preload existing files directly into FilePond pools
* include `cover` and `note_intention` assets in FilePond-managed state
* Remove obsolete upload progress bar UI and related JS includes
* Remove deprecated `Écriture` + `Image` format types from upload flow/configuration