Журнал изменений
Rename the Magistral webfont from Magistral-Book.woff2 to magistral.woff2 and update the @font-face src plus the PERFORMANCE.md caching example to match. Same binary, lowercase/simpler name.
Core changes:
- Font asset (templates/lite/assets/css):
- Rename fonts/Magistral-Book.woff2 to fonts/magistral.woff2
- base.css @font-face src updated to fonts/magistral.woff2
- Docs (docs/PERFORMANCE.md):
- Update font caching-caveat example to magistral.woff2
Technical notes:
- Byte-identical file (26808 bytes); no remaining refs to old name
Move hardcoded & and hand-built HTMX markup out of PHP: URL producers now pass a raw & URL as data, and fragments escape it once at the output boundary via {{ }}. Removes the last inconsistency where URL-bearing HTMX attributes still followed the legacy escape-at-source + markup-in-PHP pattern.
Core changes:
- Link/tab/button fragments (templates/{lite,admin}/fragments):
- tabs-link.html: add hx_get/hx_target/hx_swap block, URL escaped via {{ }}
button.html: add hx-post block (hx_post/hx_include/hx_target/hx_swap/ hx_on_click/hx_on_after), URL escaped; JS validation stays raw passthrough
- link fragment already had is_htmx (hx-get="{{ href }}") — reused as-is
- PHP producers now emit data, not markup:
- core/admin.php: upload file links use is_htmx + hx_target (drops & blob)
- admin/modules/uploads.php: upload tabs pass raw hx_get/hx_target
- core/user.php: comment/PM submit forms pass raw hx_post + hx_* fields
- Docs:
- Remove docs/PROMPT_HREF_AMPERSAND.md (task complete)
Benefits:
- Single escape at the sink; & structurally impossible
- Unified hx_* field vocabulary across link/tabs-link/button fragments
- Removes duplicated URL (href + hand-built hx-get) in upload links
Technical notes:
- getSafe() = htmlspecialchars(ENT_QUOTES|ENT_SUBSTITUTE, UTF-8)
- Verified live: comment form, admin upload tabs — single &, zero &
- Additive change; legacy link_attr/input_attr passthrough kept for other uses
Track the Magistral-Book.woff2 asset referenced by the base.css @font-face declaration, completing the font migration whose base.css update and legacy WOFF2 removal landed in the previous commit.
URLs are now treated as data: every producer emits a raw & and the template layer escapes exactly once at the output boundary via {{ href }}. This removes the previous mix of producer-side & encoding and raw {{{ }}} output and eliminates latent single/double-escape inconsistencies across the site.
Core changes:
- URL producers to raw & (blocks, modules, admin/modules, core):
- Front-end SEO links built via getSeoUrl() (raw &, SEO-friendly URLs under rewrite)
- Admin afile.php?..., htmx go=...&op=... tails, absolute/redirect URLs to raw &
- getQueryString() always emits raw & (dropped the obsolete $html parameter)
- Template output boundaries (81 flips, lite + admin fragments/partials):
- href/src/action/hx-get/hx-post URL attributes: {{{ x }}} to {{ x }}
- Kept raw ({{{ }}}): _html and _attr blobs, inline-JS onclick (reset_url, reload_query)
- Removed runtime URL pre-encoders exposed by the boundary flip:
$alink session-monitor URL, RSS source href, and files-admin download href no longer wrapped in htmlspecialchars() (the boundary now escapes)
- domain() html_entity_decode()s stored referer URLs before building the link
Benefits:
- Single source of truth for escaping; no more & risk
- Redirects/Location and htmx keep a raw &; HTML output is uniformly &
- Blocks now honor rewrite / SEO-friendly URLs like the modules do
Technical notes:
Left untouched: parser entity decoders, config/* content cache, setup legacy HTML echoes, sitemap XML content encoder
Pre-existing/out-of-scope: _referer stores double-encoded anchor data; config.replace link URLs are stored with a bare &
Verified: php -l (85 files), phpunit 8/8, guest + admin real-HTTP render with zero app-generated &
Remove legacy raster icons from the admin and lite themes in favour of Bootstrap Icons, add the bootstrap-icon fragment, and normalize admin and module handlers, config, and styles across the board.
Add the breadcrumb variant galleries under demo/ and a task prompt for the site-wide URL escaping migration (escape at the HTML output boundary, keep getSeoUrl raw).
Rewrite getTplCategoryTrail as an ordered root-to-current walk, dropping the legacy nested-anchor markup and adding a cycle guard. Rich mode renders text crumbs via the new category-crumb fragment; each crumb takes its category tone (ordern % 6) through the shared sl-cat-tone map and reveals it on hover with a sliding underline and a nudging separator. Plain mode keeps flat links for the head banner. Crumb hrefs are escaped at the template boundary for valid ampersands.
Rework the admin sidebar counter block into a data-driven table with a single row helper, switch to COUNT queries, wire sidebar dials, and bring helper names and comments in line with the project rules.
Core changes:
- Sidebar counters (core/admin.php):
- Replace the repeated per-module blocks with a grouped table and loop
- Add getAdminCountRow() using SELECT COUNT(id) instead of materializing rows
- Emit the unified sl-chip badge for counts
- Remove the dead album block
- Naming and comments (core/admin.php, admin/modules/monitor.php):
- Rename admininfo() to getAdminInfo() and db_version() to getDbVersion()
- Migrate call sites
- Add missing function comments, drop in-body comments and blank lines
- Sidebar dials (admin/index.php):
- Build the dial action list once for both grid cards and list rows
- Docs (docs/PERFORMANCE.md):
- Sync the counter reference to the new function name
Benefits:
- Fewer and lighter count queries per admin render
- Less duplication and no dead code
- Naming and comments compliant with the project rules
Technical notes:
- No storage or template contract changes
- Backward compatibility is preserved
Introduce round dial action buttons on the left module list, a shared chip vocabulary aligned with the lite theme, and a borderless module-head icon. Template and CSS layer only.
Core changes:
- Sidebar dial (templates/admin/fragments/*.html):
- Extract the dial markup into a shared fragments/dial.html
- Reuse it from menu-grid-item and menu-list-item
- Unified chips (templates/admin/assets/css/theme.css, fragments/inline-badge.html):
- Add .sl-chip base with .sl-chip-success and .sl-chip-warn tones
- Add chip_tone support to the inline-badge fragment
- Drop the legacy sidebar count-value pill styling
- Module-head icon (assets/css/base.css, theme.css):
- Add the --sl-size-icon-lg token (28px)
- Render the head icon as a bare 28px glyph without frame or background
Benefits:
- One chip vocabulary shared with the lite theme
- Quicker access to module actions from the sidebar
- Less bespoke CSS
Technical notes:
- No PHP or storage changes
- Backward compatibility is preserved
Rename lite theme size variables to semantic icon, chip, control, navigation, display, and forum tokens. The update keeps demo and error pages aligned with the theme token names.
Core changes:
- Lite design tokens (templates/lite/assets/css/base.css, templates/lite/assets/css/theme.css):
Replaced generic numeric size variables with semantic token names
- Icon sizes now use sl-size-icon-* tokens
- Navigation and control sizes now use sl-size-nav-control and sl-size-control
- Display and forum dimensions use dedicated semantic tokens
- Demo and error surfaces (demo/*.html, error.html):
- Updated embedded CSS references to the renamed semantic tokens
- Kept layout dimensions and visual behavior equivalent
Benefits:
- Improves token readability and maintainability
- Aligns lite and demo surfaces with the admin token naming direction
- Reduces reliance on generic numeric CSS custom properties
Technical notes:
- No storage changes
- HTML structure and runtime contracts are unchanged
- Backward compatibility is preserved for rendered behavior