Журнал изменений
Implements the forum wishlist batch for 6.3: admin lists get grouped drag-and-drop ordering and sl-dial action fans, free (infly) blocks become usable again through content and template tags, and publications gain an intro visibility setting with noindex for letter lists.
Core changes:
- Blocks admin list (core/admin.php, admin/modules/blocks.php):
getAdminBlockList() rewritten: rows grouped by position with collapsible sl-panel-toggle headers, drag handle plus order number in one column
- free (infly/flyfix) blocks form a trailing group with accent chips
- legacy prev/next self-join query replaced by a single plain select
updateAdminBlockOrder() now persists a full group order from one POST (ids list) with a CSRF token check the old swap endpoint lacked
RSS feed select in the add form used value "0" for the custom option, which filterUrl() turned into http://0 and wiped the block content
- Categories admin list (core/admin.php, admin/modules/categories.php):
getAdminCategoryList() rewritten as an indented tree (tree-node fragment) grouped by module with collapsible headers and drag ordering among siblings; subtrees travel with their parent
publication counters consolidated into one GROUP BY query per module (page dropped from 92 to 14 queries), child counts computed in memory
- new change() handler toggles category status from the action fan
- module filter defaults to the new "All modules" option (_ALLMODULES)
- Free block revival (core/classes/parser.php, core/classes/template.php):
Parser::filterFreeBlocks() resolves [block=id] tags in trusted content only ($safe === false), guarded against nesting, block content recursion (Parser::$freeoff during the getBlocks() cache build) and admin context
Template::filterFree()/getFree() compile {% freeblock id %} in theme templates through the same getBlocks() engine and guards
both entry points honour status, expiry, language, view rights and flyfix module rules; unavailable blocks render as empty output
Dial action fans replace hover popover menus in every admin list (30 files across admin/modules and modules/*/admin):
- dial.html gains link_attr (htmx) and onclick_attr (confirm) support
consistent icon vocabulary: power, pencil, trash, eye, check2 and context icons (play-fill, unlock, eraser, database-add/dash/up, ...)
actions cell anchors the absolute fan via td.sl-col-actions position so checkbox-trailing tables (news, comments, shop) work too
- broken delete confirm in the groups list fixed (bare onclick value)
- Publications intro setting and liste noindex:
news/pages full view honours new intro config flag (default on) to hide the teaser text when a body text exists (_C_INTRO admin label)
- getSeoRoute() marks op=liste as noindex, follow without canonical
- Shared infrastructure (templates/admin, plugins-free):
generic drag attributes (data-sl-drag-id/group/scope/parent, drag-url, drag-target) unify the admin-ui.js engine for blocks and categories
- collapsible group rows persist per key in localStorage
getTplMoveControls(), move-controls.html and _BLOCKUP/_BLOCKDOWN constants removed with the last arrow consumers
Benefits:
- reordering is one gesture instead of repeated full page reloads
- action menus no longer cover neighbouring rows
- free blocks work again and are safe by construction
- categories page is 6x lighter on the database
Technical notes:
new language constants (_C_INTRO, _INFLYINFO, _DRAGSORT, _CATDRAGSORT, _ALLMODULES) added to all six admin locales
module help files (admin/info/blocks, admin/info/categories) rewritten for the new UI; TEMPLATES.md and ARCHITECTURE.md document the tags
backward compatibility: legacy blocks()/{%BLOCKS%} call styles remain unsupported; [block=id] and {% freeblock id %} replace them
Updates the documentation to match the implemented theme consolidation, hardened validation suite, and SEO semantics work.
Core changes:
- Templates guide (docs/TEMPLATES.md):
Independent theme packages: no cross-theme includes, assets, fallback, or shared files; matching filenames stay theme-local
div variant contract: is_searchbox, is_menu_grid, branch order, and the untouched generic content/rows modes
- Theme-local asset URLs via the explicitly passed theme variable
- Test guide (docs/TESTS.md):
Theme independence audits, non-zero reference counters, and the mixed-separator regression cases
- Theme-aware CSS usage audit and its informational unused report
- CSS token-stream verification and browser route matrices
- SEO HTTP audit workflow
Reference docs (docs/ARCHITECTURE.md, docs/PARSER.md, docs/EDITORS.md, docs/VERSIONS.md):
- Aligned with the SEO pipeline helpers and current template flow
Benefits:
- Documentation matches the shipped code and test suite
- Future theme work has explicit contracts to follow
Technical notes:
- Documentation only; no runtime changes
Adds a safe server-side SEO pipeline that builds titles, meta, Open Graph, JSON-LD structured data, and breadcrumb trails from explicit page facts across all frontend modules.
Core changes:
SEO core (core/system.php, core/helpers.php, core/security.php, core/user.php, core/classes/parser.php):
filterSeoText, getSeoTitle, getSeoJson/getSeoJsonItems, setSeoJsonVars, getSeoGraph, getSeoSchema, and getSeoBreadcrumbSchema build normalized, safely encoded head data
Structured data is re-encoded from decoded values, never rendered as raw template strings
Module coverage (modules/*, admin/modules/config.php, index.php, config/global.php):
Frontend modules pass explicit titles, descriptions, and schema facts through setHead
Legacy hardcoded JSON-LD template blocks removed from the default config; stale social profile link dropped
Templates (templates/lite fragments and partials, templates/admin/fragments/head-title.html, templates/lite/fragments/head-title.html):
Dedicated head-title fragment and semantic markup adjustments for cards, tables, titles, navigation, and category views
- Language constants (lang/.php, admin/lang/.php):
- SEO-related constants synchronized across all six languages
Verification (tests/SeoSemanticsValidationTest.php, tools/seo-audit.php, tests/Unit/ParserFixturesTest.php, tests/Unit/ViewBridgeSmokeTest.php, tests/Unit/PasswordHashTest.php, phpstan.neon, setup/index.php):
New semantics validation suite and a curl-based CLI audit for route-level schema types and indexability
- Minor code style cleanup applied by php-cs-fixer
Benefits:
Search engines receive consistent, escaped structured data built from one pipeline instead of per-template JSON strings
- Route matrix is auditable via tools/seo-audit.php
Technical notes:
JSON-LD encoding strips HTML-significant characters to keep script contexts safe
- Backward compatible: no routes, database, or module APIs changed
Applies the shared formatting conventions to the lite stylesheets and merges proven duplicate adjacent rules, keeping computed styles and cascade order intact.
Core changes:
- Formatting (templates/lite/assets/css/base.css, theme.css):
2-space indentation, one property per line, normalized section comments
Data URI lines kept atomic; no reordering of sections or responsive blocks
- Consolidation:
- Adjacent equivalent rules merged within one at-rule context
Six classes (sl-b-i-1..4, sl-b-icon, sl-big-sl-icons) removed together with their sl-advantage markup; zero source references remain
Benefits:
- Consistent stylesheet layout aligned with the admin theme process
- Dead advantage-section styles no longer ship to every page
Technical notes:
- Theme-aware usage audit reports 441 defined classes for lite
- Seasonal, parser, gallery, and JS state classes preserved
- No custom property values synchronized with the admin theme
Replaces the block-list-item fragment with a composition of the existing link and list-item fragments and removes the unused lite searchbox partial.
BREAKING: templates/lite/partials/searchbox.html is removed. External modules that rendered this partial by name must ship their own template. Removal confirmed by the project owner.
Core changes:
Block emitters (blocks/pages.php, news.php, faq.php, jokes.php, auto_links.php, files.php):
Build the anchor via getHtmlFrag('link') with escaped href, title, and label
- Wrap it as trusted content_html in getHtmlFrag('list-item')
auto_links uses the semantic is_blank flag instead of a raw target_attr string, which also adds rel="noopener noreferrer"
- Fragment removal (templates/lite/fragments/block-list-item.html):
- Deleted after zero-reference search across PHP and HTML
Benefits:
- One fragment contract for links instead of a parallel copy
- Stronger target security for external auto_links entries
Technical notes:
List markup of all six blocks verified; escaping boundaries unchanged
- No admin files touched by this change
Removes the hardcoded templates/lite image paths from the main slider so a replacement frontend theme resolves its own slide assets.
Core changes:
- Slider partial (templates/lite/partials/main-slider.html):
- Four slide image URLs now use templates/{{ theme }}/images/slide/
- Filenames, alt texts, and dimensions unchanged
- Emitter (modules/main/index.php):
Pass 'theme' => getTheme() and is_home explicitly to the partial
- getHtmlPart() only receives the passed data array and does not
inject page-level variables
Benefits:
- Theme replacement no longer breaks slider image URLs
- Runtime HTML no longer hardcodes its own theme directory
Technical notes:
- All four slide URLs verified HTTP 200 on the live page
- Guarded by the new hardcoded-theme-path test assertion
Reformats the admin theme stylesheets to the shared conventions and merges proven duplicate adjacent rules without changing any computed style.
Core changes:
- Formatting (templates/admin/assets/css/base.css, theme.css):
2-space indentation, one property per line, one blank line between blocks
- Section comments normalized to the / Name: scope / shape
- No rule reordering, no selector or value changes
- Consolidation:
Adjacent rules with identical declaration sets merged within the same at-rule context only
- No moves between base.css and theme.css, no cross-media merges
Benefits:
- Consistent, diff-friendly stylesheet layout
- Fewer duplicate declarations with cascade behavior preserved
Technical notes:
Theme-aware usage audit reports 361 defined classes, 8 static-only unknowns kept as informational
- No property values or selectors removed without emitter evidence
Replaces the single-purpose menu-grid and searchbox partials with semantic variants of the existing admin div partial while keeping the rendered DOM and CSS classes identical.
Core changes:
- Variant branches (templates/admin/partials/div.html):
Branch order: is_searchbox, is_menu_grid, generic content_html, generic rows
- is_searchbox renders sl-searchbox only for non-empty trusted
content_html; empty input renders nothing
- is_menu_grid always renders the sl-menu-grid wrapper, matching
the removed menu-grid partial
Existing generic content and rows/sl-div-grid contracts are untouched
- Call-site migration:
- 2 menu-grid calls in admin/index.php
17 searchbox calls across 11 admin PHP files migrated to div + is_searchbox with renderer-produced content_html
menu-grid.html and searchbox.html removed after zero-reference search; the dead rows_html slot of menu-grid was not carried over
- Bridge tests (tests/Unit/AdminSearchboxBridgeFlowTest.php):
Cover happy path, missing theme, raw trusted markup, empty content, empty and filled menu grid, and regression of both generic div modes
Benefits:
- Two fewer single-purpose partials without any DOM change
- PHP keeps passing semantic flags instead of CSS class strings
Technical notes:
- No visual or route changes; dashboard and module list DOM verified
- Backward compatible: same classes and wrappers are emitted
Fixes the Windows path defect that silently turned the template reference scan into a no-op and replaces cross-theme byte-equality checks with per-theme runtime contracts.
Core changes:
- Reference validator hardening (tests/TemplateValidationTest.php):
Normalize base path and file paths to forward slashes before computing repository-relative paths
- Mixed Windows/POSIX separators previously left absolute paths,
so anchored patterns matched nothing and zero references were
checked while the test stayed green
Require non-zero counters for found, classified, and include/extends/component references
Discover installed frontend themes dynamically instead of the hardcoded default/simple/lite list
Forbid cross-theme includes, cross-theme asset references, hardcoded own-theme directory paths, and symbolic links
Drop testSharedFrontendFragmentsStayInSyncAcrossThemes in favor of testThemeRuntimeContractsAreIndependent
- Theme-aware CSS usage audit (tests/Unit/AdminCssClassUsageTest.php):
- Report admin and lite independently
Scan theme HTML, theme hooks, PHP emitters, and shared JS state classes so chart, sort, and seasonal classes are no longer false positives
Keep the unused list informational; removal still requires a full emitter audit
Benefits:
The reference scan now actually validates template targets on Windows and POSIX alike
- Themes can evolve independently without byte-equality coupling
Technical notes:
Regression cases cover mixed-separator paths and emitter classification
- No runtime code changed in this commit
The reserved .sl-but-red button variant gets its first consumer: form submits that destroy data render red, while inline delete links keep their DelCheck-confirmed link styling as agreed.
Core changes:
- Button fragment (templates/admin/fragments/button.html):
New is_danger semantic flag maps to sl-but-red in both the button and input variants
- Search admin (modules/search/admin/index.php):
The search-index clear form (the only destructive form submit in the admin, verified by scanning hidden op values and form action URLs) passes is_danger
Benefits:
- Destructive submits are visually distinct from save/confirm actions
- The variant contract is a semantic flag; PHP passes no CSS classes
Technical notes:
- Intended visible change confined to the search index clear form
- Verified live: the submit renders the danger gradient; php -l clean