Журнал изменений
The shared/ fallback mechanism was reverted in the previous session. Physical files were already deleted; this commit syncs git tracking to match the filesystem state.
Remove 52 dead/duplicate fragments from all 3 frontend themes (default, lite, simple) and replace direct getHtmlFrag() calls with canonical helpers where they already exist.
Core changes:
- Dead fragments removed (templates/default|lite|simple/fragments/):
- 49 fragments with 0 frontend callers (admin-, block wrappers, comment-action-delete, editor-files-, navi-tabs-, pager-, rating-*, voting-close/open/stat-text, td-check, form-checkall, spoiler, etc.)
- 2 lite-specific dead fragments: lite-faq-random-link, lite-head-banner
- 1 duplicate resolved: admin-title-tip (canonical: title-tip)
- Duplicate fragments resolved:
- recommend-mail-link → files-external-link (identical content) modules/recommend/index.php updated
- contact-admin-option → getTplSelectOption() migration modules/contact/index.php updated
- Direct getHtmlFrag('form-option') → getTplSelectOption() (10 calls):
- modules/forum/index.php (2 calls, $sel variable removed)
- modules/pages, files, media, faq, links, news, jokes, help/index.php
Benefits:
- Fragment count: 388 → 336 per theme (-52 default/simple, -54 lite)
- All direct form-option calls now route through canonical helper
- Frontend and admin themes now have consistent, non-overlapping fragment sets
Technical notes:
- block-* fragments in blocks/ system kept intact (indirect callers)
- files-external-link kept as canonical for generic target=_blank links
- form-option fragment kept (still used by getTplSelectOption())
Eliminate duplicate, dead and module-specific admin fragments by migrating all list-head patterns to getTplAdminTableHead() and fixing shared helper canonical fragment references.
Core changes:
- Admin helpers (core/helpers.php):
- getTplAdminTableHead(): use th/th-nosort fragments, not inline HTML
- getTplAdminTableCells(): use td fragment, not inline HTML
- getTplAdminSection(): use admin-section-heading fragment
- getTplAdminTabClose(): use admin-tab-list-close fragment
- getTplAjaxAction(): fix canonical back to comment-action-ajax
- getTplDeleteAction(): fix canonical to action-delete
- Admin modules (21 files):
- Replace getHtmlFrag('admin-*-list-head') with getTplAdminTableHead([])
- admin/modules/: groups, messages, modules, newsletter, referers, security
- modules/*/admin/index.php: account, auto_links, clients, content, faq, files, help, jokes, links, media, money, news, order, pages, search, voting
- Admin fragments (templates/admin/fragments/):
- Delete 83 dead fragments (list-head, account-*, orphans)
- Restore incorrectly removed: td, th, th-nosort, admin-section-heading, admin-tab-list-close, admin-admins-permission-empty, comment-action-ajax
Benefits:
- Admin fragment count: 569 → 486 (-83)
- Single canonical path for all table headers via getTplAdminTableHead()
- Shared helpers use correct fragment names for all theme contexts
Technical notes:
- comment-action-ajax stays canonical for getTplAjaxAction() (shared, used in frontend)
- action-delete is canonical for getTplDeleteAction() (all themes)
- admin-whois-list-head.html kept (colspan=2, needs getTplAdminTableHead() extension)
Reverts Phase 2: themes (lite, default, simple, admin) are self-contained and must not depend on a shared/ fallback directory.
Core changes:
- templates/shared/: deleted
- templates/lite/, default/, simple/: all 388 files restored
- templates/admin/fragments/: 113 files restored
- core/classes/template.php: removed $shared property, shared fallback in getFile(), and shared path check in checkFile()
Benefits:
- Each theme is fully portable and independent
- No hidden cross-theme dependencies
Admin Phase 2: remove 113 fragments from templates/admin/ that are byte-identical to templates/shared/ — engine fallback now serves them transparently.
system.php migration: move setModuleNavi, setNaviLower, setPageNumbers, setArticleNumbers from core/system.php to core/helpers.php, establishing helpers.php as the single rendering layer for both frontend and admin.
Core changes:
- templates/admin/fragments/: 347 → 234 files (-113)
- core/helpers.php: +4 functions (setModuleNavi, setNaviLower, setPageNumbers, setArticleNumbers)
- core/system.php: -4 functions (same, removed)
Benefits:
- All fragment-rendering helpers are now in one place (core/helpers.php)
- Admin area no longer duplicates shared fragments — maintained in one location
- Zero call-site changes required (function names unchanged)
Technical notes:
- All 4 migrated functions rely on global $tpl/$db/$conf/$afile — unchanged
- setArticleNumbers internally calls setPageNumbers — order preserved in helpers.php
- php -l passes on both modified files
Extend the Template engine with a shared/ fallback so theme directories only need to contain files that actually differ per theme. Move 388 files that were byte-identical across all three themes into templates/shared/.
Core changes:
- Template engine fallback (core/classes/template.php):
- Add protected string $shared property, initialized in constructor as BASE_DIR/templates/shared
- Update getFile(): try theme path first, return shared path as fallback (single is_file() check, no extra I/O when theme file exists)
- Update checkFile(): accept files from either $this->base or $this->shared (realpath-based containment check for both roots)
- Shared template directory (templates/shared/):
- Move 374 fragments, 5 partials, 6 pages, 3 layouts from all three themes
- Source: lite/ (canonical copy), verified identical in default/ and simple/
- Theme-specific files (~24-34 per theme) remain in their theme directories
Benefits:
- Template files: ~1163 -> ~445 (62% reduction)
- Theme directories now contain only genuinely theme-specific overrides
- Adding a new theme requires only the files that differ from shared/
- Zero change to PHP call sites, helpers, or fragment names
Technical notes:
- Theme path takes priority over shared/ (theme-specific override works)
- Admin theme is unaffected (uses its own base path, no shared/ fallback)
- Cache uses realpath-based hash, works transparently for shared files
- Verified: lite, default, simple all resolve fragments via fallback
- Verified: admin theme continues to use templates/admin/ exclusively
Eliminate cross-module fragment duplicates in frontend themes by routing all calls through canonical helpers. Add getTplAjaxAction helper and inline all trivial single-tag fragments. Sync all three themes (lite, default, simple) simultaneously since changes are theme-independent.
Core changes:
- New helper and system.php cleanup (core/helpers.php, core/system.php):
- Add getTplAjaxAction(target, query, title, label, class) using comment-action-ajax.html
- Update getEditorAsyncAction, getCommentAsyncAction, getVotingAsyncAction to delegate to getTplAjaxAction instead of direct getHtmlFrag calls
- Fragment duplicates removed (templates/lite|default|simple/fragments/):
- Delete action-menu duplicates: admin/comment/voting-action-menu.html (3x3=9 files) canonical: editor-action-menu.html via getTplMenuItems()
- Delete delete-action duplicates: admin/voting-action-delete.html (2x3=6 files) canonical: comment-action-delete.html via getTplDeleteAction()
- Delete link-action duplicates: admin/voting-action-link.html (2x3=6 files) canonical: comment-action-link.html via getTplLinkAction()
- Delete ajax duplicates: admin/editor-action-ajax.html (2x3=6 files) canonical: comment-action-ajax.html via getTplAjaxAction()
- Delete select-option duplicates: account/rss/whois/media variants (4x3=12 files) canonical: form-option.html via getTplSelectOption()
- Delete admin-session-box.html from all 3 themes (unused dead fragment)
- Inline trivial fragments across all themes: br, br-br, tr-open, tr-close, table-close, form-close (6x3=18 files)
- Call-site updates (modules/*/index.php):
- Replace duplicate getHtmlFrag() calls with getTplSelectOption() in account, media, rss, whois modules
- Inline '<br>', '<br><br>', '<tr>', '</tr>', '</tbody></table>', '</form>' directly in account, clients, content, files, forum, help, links, money, news, order, pages, shop, sitemap, users modules
Benefits:
- 57 fewer fragment files across 3 frontend themes
- getTplAjaxAction provides a named entry point for HTMX GET actions
- All fragment calls go through helpers.php (single responsibility)
- Themes are now in sync with no redundant copies
Technical notes:
- comment-action-ajax.html kept as canonical (supports optional CSS class)
- admin-action-link.html kept in admin/ theme (used by admin $tpl only)
- All changes verified with php -l
Remove 23 delegate wrappers and migrate 7 rendering helpers from core/admin.php to core/helpers.php with proper naming. Inline trivial fragments, merge 4 input fields into one parameterized fragment, and eliminate intra-admin duplicate fragments found via content-hash audit.
Core changes:
- Helpers migration (core/admin.php, core/helpers.php):
- Delete 23 delegate wrappers (adminFlagBox, adminTitleTip, adminMenuItems, etc.)
- Move 7 rendering helpers to helpers.php with renamed canonical names:
- setAdminNavi -> getTplAdminNavi
- adminTabListOpen/Close/Link -> getTplAdminTabOpen/Close/Link
- adminInfoCountValue/Row/Table -> getTplAdminInfoCount/Row/Table
- Add getTplAdminPanel helper and admin-panel.html fragment
- Add 9 new functions total to core/helpers.php
- Fragment consolidation (templates/admin/fragments/):
- Merge admin-text/number/url/email-input.html into admin-input.html (itype var)
- Inline getTplHrLine() -> return '<hr>' directly
- Inline trivial tr-open/close, br, br-br, table-close, form-close fragments
- Redirect admin-database-status-tag -> admin-flag-box (identical content)
- Redirect admin-fields/replace-tab-content -> admin-tab-content (3-way dup)
- Redirect admin-news-asso-table -> admin-shop-assoc-table (identical)
- Redirect admin-security-ban-tabs -> admin-uploads-config-tabs (identical)
- Inline admin-security-tab-divider (<hr>), admin-*-row-open/close (<tr>/<tr>)
- Delete admin-category-img-preview (use img-preview as canonical)
- Net result: 366 -> 347 fragments in templates/admin/
- Call-site updates (admin/modules/.php, modules//admin/index.php):
- Replace all old function names with new getTplAdmin* equivalents
- Replace direct getHtmlFrag() calls for duplicate fragments with canonical names
Benefits:
- core/admin.php no longer contains rendering logic (separation of concerns)
- Single entry point for all admin rendering via core/helpers.php
- 19 fewer fragment files in templates/admin/
- Consistent naming convention across all helpers
Technical notes:
- Public API of all helpers unchanged (getTplTextInput etc. still work)
- Fragment variable names updated per naming rules (itype, pid, cont)
- All changes verified with php -l
Replace all remaining inline HTML across blocks, core modules, admin panel, and frontend modules with template fragments, completing the full separation of PHP logic from HTML output across the entire codebase.
Core changes:
- Blocks (18 files — blocks/block-*.php):
- All inline HTML replaced with getHtmlFrag() fragment calls
- New fragments added: block-banner-random, block-center-, block-forum-, block-img-, block-languages-, block-login-form, block-menu, block-module-, block-network-row, block-search-form, block-stat-banners, block-user-
- Core (core/access.php, admin.php, classes/pdo.php, security.php, user.php):
- access.php / security.php: error/report output migrated to fragments
- pdo.php: query debug output uses pdo-error-badge / pdo-query-time fragments
- user.php: RSS feed builder uses user.php-specific fragments
- admin.php: remaining inline HTML moved to fragments
- Frontend modules (modules/):
- account, changelog, clients, contact, content, faq, files, forum, help, jokes, links, main, media, news, order, pages, search — all cleaned
- forum/index.php: full rewrite using link-btn, span-btn, forum-* fragments
- main/index.php: carousel, grid and section output via main-* fragments
- search/index.php: result rendering via search-result-title fragment
- Templates (templates/):
- admin/index.php, lite/index.php: asset and layout output via fragments
- media-post-badge.html synced across default/lite/simple themes
- ~350 new .html fragment files added across all 4 theme directories
Benefits:
- PHP files contain zero HTML tags (except filterMarkdown engine and RSS/XML)
- All HTML exclusively in .html fragment files under templates/
- Themes can now be fully swapped without touching any PHP logic
- Fragment sync enforced by phpunit testSharedFrontendFragmentsStayInSyncAcrossThemes
Technical notes:
- 125/125 phpunit tests pass (1 pre-existing CRLF failure unchanged)
- All shared frontend fragments are hash-identical across default/lite/simple/admin
- Admin-only fragments remain in templates/admin/fragments/ only
Replace every inline HTML tag in admin modules, frontend modules, and core helper functions with template fragments or existing helper calls, completing the full PHP-without-HTML migration across the entire codebase.
Core changes:
- Core functions (core/system.php):
- categorySelectOption(): delegate to getTplOption() — removes <option> inline HTML
- title_tip(): use title-tip.html fragment — removes <nav><div> inline HTML
- ad_status(): use span-btn.html / link-btn.html — removes all <span>/<a> inline HTML
- New shared fragments (all 4 themes: default/lite/simple/admin):
- title-tip.html: <nav class="sl_tip"><div>{{{ content }}}</div></nav>
- rating-box.html: <div class="min-rate"><div class="rate-like-box">{{{ content }}}</div></div>
- form-checkall.html: checkall <input> for list headers
- td-check.html: <td><input type="checkbox"> for list rows
- tr-open.html / tr-close.html: structural table row wrappers
- img-preview.html: <img id="picture"> for config image preview
- Admin modules (19 files):
- adminTitleTipLabel/adminTitleTip with <br> separators → getTplAdminTipLine()
- getcat(..., '<option>') → getcat(..., getTplOption())
- <a href target="_blank"> links → getTplAdminTextLink()
- <br><br> before fields → $tpl->getHtmlFrag('br-br', [])
- <div>...<hr> voting preview → div-hr.html fragment
- <tr>/</tr> in news asso table → tr-open.html / tr-close.html
- <th> checkall → th-nosort.html + form-checkall.html
- <td> checkbox → td-check.html
- <img> preview → img-preview.html
- activate() in money/order: add global $tpl, use br-br fragment for email
- Frontend modules (5 files):
- rss/index.php: <option selected> → getTplOption(..., true)
- users/index.php: <br> tip lines → getTplAdminTipLine(); <div rating> → rating-box.html
- shop/index.php: <br> tip lines → getTplAdminTipLine() in $website/$note
- money/index.php: $sinfo .= val.<br> → getTplAdminInfoLine()
- voting/index.php: <div id="rep..."> → post-div.html fragment
Benefits:
- Zero raw HTML tags remain in any module or core helper PHP file
- All HTML exclusively lives in .html fragment files under templates/
- categorySelectOption, title_tip, ad_status now fully template-driven
- 125/125 phpunit tests pass (1 pre-existing CRLF failure unchanged)
Technical notes:
- Justified exceptions: filterMarkdown class (IS the HTML generator), PDO constructor error path ($tpl unavailable), template engine asset management (circular dependency), RSS/XML generation, commented-out code
- New fragments synced across all 4 theme dirs (hash-identical per phpunit)
- getTplAdminTipLine trailing-<br> differs slightly from original leading-<br> pattern in tooltips — visually equivalent, no behavioral change