Журнал изменений

Официальный сайт SLAED CMS

Журнал изменений

Фильтр и поиск

Всего: 1369 Доступных коммитов | Отфильтровано: 1369 Коммиты | Страница: 1 из 137
Сегодня (08.11.2026)
Feature: Tables and section heads are one series on the site and in the panel, with one-word titles, icon statuses and an honest module name
Автор: Eduard Laas | Дата: 21:58 08.11.2026

The head of a section placed its filter beside the title until it wrapped into a ragged block, a lone action stood as a button beside the title, column titles ran to several words or cut forms, a status was an icon in one list and a word in the next, and a Node type was named as if it were a module of its own. One series now governs the head, the columns and the cells of every list of the site and the panel.

Core changes:

  1. Section head (partials/module-head.html, admin theme.css, docs/TEMPLATES.md):
  • The filter and the settings find are one block after the tabs; one or two fields stand beside the title once the content column is 960px wide, three or more always in a bar under the tabs
    • .sl-admin-content-inner is the container the head measures, so a folded menu counts
    • the bar lays its fields in aligned columns of a label and a control, three across, four as two by two, two under 900px of the column and one under 560px; the button closes the first line
  • The old flex rules of the subtitle and its narrow-screen overrides leave
  1. Action tabs (core/helpers.php, modules/forum/admin/index.php, forum lang and help, tests):
  • getTplAdminTabs() takes post: a tab named there carries data-sl-post and slaed.js posts its token
    • setTplAdminInfoPage() passes it on
  • The synchronisation of «Форум» is a tab on all three screens instead of a lone button; _SYNCHINF says so in six languages, the help describes the tab
  • The route probe reads the token of the tab, the test is renamed to theForumListReadsAndTheTabRepairs
  1. Column titles (lang, admin/lang, node, forum and users lang, every list, docs/TEMPLATES.md):
  • Every title of a list is one word, the cut forms of cutstr() leave the heads of categories, forum, voting and users
    • new one-word constants where the long one still serves a form: _SEC_ROLE, _GEOIP_BASE, _GEOIP_PATH, _MAIL_TRY, _NLRECIP, _SCHEDULER_NEXT, _FIELDS_ON, _ENDS, _VOTING_VOTES, _NODE_LOOK, _FORUM_LAST, _USERS_FROM
    • _SWORD, _SEARCHFIELDS, _FIELDS_KEY, _POINTS_LIMIT, _POINTS_PERIOD and _TVIEWS are one word where only a head reads them
    • _ADIR, _VIEW and _POINTS_SCOPE leave; the GeoIP path column no longer borrows the image directory constant
  • A centred title stands over the middle of its values: equal sides, and in a sortable table a lane for the mark on the right of the title and of every cell; a sortable title keeps 6px from its mark in every state of the sort
  • A title too long for its column ends in an ellipsis, slaed.js puts the whole title in its tip on hover
  • The column separator of the head reads --sl-text-subtle and shows in the light scheme
  1. Statuses, errors and options (table-cells.html, th.html, lite table.html and table-row.html, both theme.css, admin-ui.js, every list with a status):
  • The cell key stat draws one of four tones: is_on the green check, is_wait the clock, is_fail the red cross, none the grey dashed circle of off; text is its tip and its screen-reader name, the cell sorts by the tone
    • comments, modules, languages, voting, forum, categories, blocks, master, Node, newsletter campaigns and queue, the dead addresses, the journals of actions and logins, the scheduler, ratings, privat, GeoIP, the database optimise and repair, and the logins and materials of the cabinet move onto it
    • the lamp of a row turned in place keeps its sort key
  • A head with is_head_status or is_head_error shows its icon instead of the word, the options head shows a gear; status and error columns are sortable and as wide as their icon
  • The column tokens hold the width of their content: check and actions read the icon ladder, date 128px, id 42px, count 88px; the commit column of the changelog takes the count class
  1. Honest module name (core/system.php and every list or filter that names the module of a record):
  • getModuleTitle() names a Node type as the module and its type («Материалы - Новости») and another module by its name alone, never its key
  • comments, categories, search, favorites, voting, ratings, upload rules and the cabinet use it; the profile picker of a new Node type drops the key
  1. Help and docs (admin/info, modules/*/admin/info, docs/TEMPLATES.md, docs/VERSIONS.md):
  • The help of every changed list names its columns and describes the status icons and the honest module name
  • TEMPLATES records the head, the action tab, one-word titles, the four tones and the honest module name; VERSIONS states the breaking changes
  1. Panel spacing (admin theme.css):
  • .sl-box drops its bottom margin, the row under a list keeps 8px above and below it, the cockpit 8px below
  1. Audit baseline (tools/ui-audit-baseline.json, tools/ui-contrast.json):
  • The baseline is stored again and the contrast registry was regenerated by the rig after base.css changed

Benefits:

  • One look for every head, column and status of the system, readable without hovering and sortable by meaning
  • Service columns no wider than their content, filters that never wrap into a ragged block
  • No list names a Node type as a module of its own

Technical notes:

  • Breaking: module-head.html draws the filter after the tabs, _ADIR, _VIEW and _POINTS_SCOPE are gone, .sl-status-inactive is the grey off circle and the red cross is .sl-status-fail
  • The demo pages keep the old head markup by the decision of the owner
Feature: No loader of three dots is left in either theme, a waiting list only dims its rows
Автор: Eduard Laas | Дата: 17:04 08.11.2026

The three green dots over a list of the panel came back on every htmx request of the list - a tab, a filter, a page - after the four-dot loader of the live chart had left. The loader goes as a whole: the class, its keyframes, its markup in the list and the file manager, the dots of a site button under its request, and its six tokens in both themes, struck from the frozen API as a recorded exception.

Core changes:

  1. Lists of the panel (admin-list.html, admin-ui.js, admin theme.css):
  • The hidden .sl-list-busy mark leaves the canon list; setListBusy() only writes aria-busy
  • A request on its way dims the rows of tbody, as before; the positioning rules of the mark leave
    • .sl-table-shell lost the position the mark gave it; no element of the lists moved, measured in the browser
  1. File manager (file-manager-templates.html and theme.css of admin and lite):
  • The fm-busy template is the dimmed cover alone, without the dots
  • The cover drops the flex centring it kept for the dots and still fills its tile or row
  1. Site button (lite theme.css, plugins/system/slaed.js):
  • A button whose htmx request is on its way keeps its label and takes no repeat click; the dots and the transparent label leave
  • The comment of setPressBurst() says it lifts the button itself for its sparks
  1. Theme API (base.css of admin and lite, tools/ui-contract.php, tools/ui-audit-baseline.json):
  • .sl-loading, the keyframes sl-loading-dots and the tokens --sl-loading-dur, --sl-loading-width, --sl-loading-height, --sl-loading-dot-width, --sl-loading-dot-height and --sl-loading-dot-gap leave both themes
  • The contract records the fifth exception of the freeze and drops the components loading and loading-dot, with drift and drift-dot that had no token left since 2026-11-04
  • The baseline roster under api loses the six names, and the baseline is stored again
  1. Demo and docs (public/demo/admin, docs/VERSIONS.md):
  • The demo list dims without the mark, Э28 is described as it now works
  • The versions log states the breaking change

Benefits:

  • No motion on a list that loads in a fraction of a second
  • No dead token, class or rule left behind in either theme

Technical notes:

  • Breaking: a theme of its own that overrides the six --sl-loading-* tokens or styles .sl-loading is no longer read
  • No schema, URL or PHP API change
Fix: A value row holds the paragraphs of a text area, and the newsletter list builds its reset and add links
Автор: Eduard Laas | Дата: 17:04 08.11.2026

Follow-up of the fact rows: the value of field-value was a span, so the paragraphs of a text area stood inside an inline element; the campaign list read $afile without declaring it and built its reset and add links from nothing.

Core changes:

  1. Value row (fragments/field-value.html of admin and lite, docs/TEMPLATES.md):
  • The value of .sl-value-row is a div, which may carry the paragraphs of a text area
  • The Templates guide names the div value beside the span caption
  1. Newsletter campaign list (admin/modules/newsletter.php):
  • newsletter() declares $afile, read by reset_url and add_url of the list
  1. Node list (modules/node/index.php):
  • The empty state of setNodeList() breaks its long condition over two lines, as the branch under it

Benefits:

  • Valid markup for a multi-paragraph value in both themes
  • The reset and the add button of the campaign list lead to the panel page again

Technical notes:

  • No schema, URL or API change
  • Backward compatible: .sl-value-text keeps its class and its rules
Feature: A fact of a page is one row with a chip for its state on the site and in the panel, a window stands only on a board, and a button weighs by its role
Автор: Eduard Laas | Дата: 16:14 08.11.2026

The panel and the site told facts in four ways - alerts, sentences glued to a value, heading rows, windows round a single list. A fact is now a row of kv-list (panel) or field-value and the profile cards (site), its state a chip beside the value and the reason of a bad state a warning under the list; a window of a board no longer wraps a list or a page, and a post button carries the weight of its step.

Core changes:

  1. Facts of a page (kv-list.html, admin/modules/update.php, config.php, blocks.php):
  • kv-list takes an optional chip with a tone (success, warn, danger, neutral) after the value
    • On a page the list lines up with the rows of the form: two halves, the same padding and solid rule
    • Inside a board window it keeps its narrow form: value to the right, dashed rule, small text
  • The updater lists its facts with chips: check refused, no unpacker, rollback, self-check of the last run, staged package, refused archive, integrity; each sentence of a cause is a warning under the list
    • getUpdateWarn() escapes the words of the master or the archive once
    • The space a test needs is a meter, not an alert
  • Optimization lists cache folders by full path without a heading row
  • A block form drops the info alert with the absolute path; the block edit page names the block in a row with the chip of its kind
  • New and reworded UPDATE* constants in the six admin locales
  1. Facts on the site (modules/account/index.php, account-profile.html, lite theme.css):
  • The extra fields of the public profile are a fifth card among Profile and Personal; a text area stands under the cards as field-value rows in a wide panel, so its paragraphs stay whole
  • field-value draws a rule between two rows, a muted caption and a weighed short value; paragraphs of a text area keep the weight of text (both themes, the reason of the layout difference written into tools/ui-contract.php)
  1. Panel window and button weight (admin-list.html, helpers.php, post-button.html, database, newsletter, search, sitemap, monitor):
  • getTplAdminList() drops its pane option: a list draws no window, its tiles stand above the table
  • Database, newsletter, search and sitemap show their tiles without a window; sitemap names its address in a row
    • Database counts its tables in a tile; _TOTALSPACE and _TOTALFREE give way to _DB_TOTAL and _DBFREE
  • getTplPostButton() takes the look main, check or risk, which the updater uses; the setup, the layout field and the icon picker draw their buttons by the same weight
  • Monitor tiles and the demo use outline icons; tile icon width of the panel is 32px
  1. One empty face (empty.html, file-browser-props.html, file-manager.html, privat-view.html, core/admin.php, user.php):
  • An empty file manager, empty file properties and the blank private message pane use fragments/empty.html with the new is_pane variant; the file manager reset button carries its icon
  • _UPLOADS_EMPTY* and _UPLOADS_FAIL* give way to the shared EDITOR* words
  • The pager hides its "Page" caption visually and keeps it for a screen reader
  1. Documentation and tests (docs/TEMPLATES.md, admin/info, tests):
  • docs/TEMPLATES.md: sections Panel Window, Button Weight and Facts Of A Page
  • Help of update, config, blocks, database, newsletter, privat, search and sitemap describes the current page
  • SeriesPartsTest checks the chip and its escaping; PanelPartsTest checks that a list draws no window

Benefits:

  • One way to tell a fact, a state and its cause everywhere
  • Fewer alerts: an alert is a message or the permanent note of a page again
  • A list or a page reads as one table with its form

Technical notes:

  • getTplAdminList() no longer reads 'pane'; getUpdatePack() takes a third argument $look
  • The account profile part drops has_field/field and takes field_html
  • No schema or URL change
Feature: An empty list, search or section has one face on the site and in the panel, says why it is empty and offers the reset of a filter or a new entry
Автор: Eduard Laas | Дата: 00:33 08.11.2026

Nothing to show was told four ways: a grey line in the lists of the panel, a blue alert, a yellow warning on the search of the site, and blocks of their own in the files, the mailbox, the profile feed and the favorites. One fragment now draws it in both themes, in three kinds, while an alert is left to messages: saved, refused, failed.

Core changes:

  1. The fragment (public/templates/*/fragments/empty.html, assets/css/base.css, assets/css/theme.css):
  • One identical fragment of both themes: an icon, a title, an optional line and an optional button
    • is_found: "Ничего не найдено" with "Сбросить фильтр"; is_calm: "Всё проверено: очередь пуста." in a calm green
    • Without either: "Нет информации", with "Добавить" where the caller passes a form of a new entry
    • is_small for a block, a column or a tab; act_target swaps a part with htmx instead of a link
  • sl-empty replaces sl-fm-empty and sl-profile-empty; the new token --sl-empty-width, the component empty in tools/ui-contract.php, whose two allowlist entries now name the new selectors
  • The window of files keeps --sl-fm-empty-width for the line under its title; sl-list-calm is gone
  1. The lists of the panel (core/helpers.php, partials/admin-list.html and their callers):
  • getTplAdminList() draws the fragment from none_text, is_calm, reset_url and add_url
    • A caller no longer picks the words: it passes the address of the list without its filter when one is set
    • A type or a tab of a status is a place, not a condition: the trash of a Node type is empty, not "nothing found"
  • "Добавить" on an empty list of Node (draft and published only), polls, campaigns, groups and categories
  • The single alerts of config, groups, logs, master, search and the categories are the fragment
  • The file browser of the panel draws its empty catalogue and its failed list with the same face
  1. The site (modules/node, users, voting, sitemap, forum, search, changelog, account, core/user.php, core/system.php):
  • The lists of Node, users, polls, forum topics and the sitemap; the search without a hit offers the search page
  • A Node list empty under a letter, "new" or favorites offers the reset, in the archive of events as well; an empty type offers its form of a new entry to whom checkNodeFlow() allows it
  • The comments of a material, a poll that is gone from its block, the profile feed: the small kind
  • The mailbox, the favorites, "Мои материалы" and the logins of the cabinet: the fragment in place of the list, no longer an info note in the slot of the cabinet
  • The changelog says the fragment when no commit came and keeps the alert for an error of loading
  1. Documents, help and tests (docs/TEMPLATES.md, admin/info, modules/*/admin/info, tests):
  • docs/TEMPLATES.md, section Empty State: the keys, the three kinds, where a button stands, what is no empty state
  • The help of newsletter, privat, voting, changelog and account names the reset and the add button
  • AdminListRowTest holds reset_url on every list under a filter bar and is_calm on the queues; FileManagerCatalogTest and the profile feed of contract_probe.php read the new keys

Benefits:

  • One look and one wording for nothing to show, so an empty place no longer reads as a message or a warning
  • An empty result always offers the way back; an empty section offers the next step where the reader may take it
  • One rule in place of a ternary of texts in thirty callers

Technical notes:

  • Removed constants, all six locales: _UPLOADS_NOFIND, _NOMATCHES, _PRNOHIT, _FAVOR_NONE
  • The partial keys empty_alert, empty_title, empty_icon, empty_text, none_text (favorites) and is_empty (file list) give way to one array for the fragment
  • The value placeholder "Нет информации" in a cell or a card, the live filter of a picker and the narrow panes of the layout screen stay as they were
Вчера (07.11.2026)
Feature: Rows per page and page numbers come from one place, the general settings, with an own number of a module only on the site
Автор: Eduard Laas | Дата: 23:17 07.11.2026

Every module counted its pages its own way: six sizes of a page (10 to 100) and four windows of numbers (5, 8, 10 or every page), settings with seven names, numbers written into code and two settings nothing read. The standard is now one section of the general config that every list inherits, as "Use Global" of other systems does; a module of the site may keep its own number where its place needs one, the panel has one number for all its lists.

Core changes:

  1. The general numbers (config/global.php, admin/modules/config.php, core/helpers.php):
  • pager: rows 15 and span 8 for the site, arows 50 and aspan 10 for the panel, four fields of the general settings screen
  • getPageRows($own, $key) answers the own rows of a module, else the general one, capped by the own number of a visitor from the cabinet (getUserNews(), 3-20)
  • getPageSpan($own) answers aspan in the panel, the own span of a module or the general span on the site
  • getListLimit(int|Closure $total) takes the general arows; getTplAdminList() takes arows and aspan itself and loses the keys base and maxpg; getTplPager() and getPageNumbers() take the general numbers when none is passed
  1. The lists of the panel (admin/modules/.php, modules//admin/index.php, core/classes/comment.php, privat.php, mail.php):
  • comments, privat, search, voting, users, favorites, changelog, groups, logs, ratings, master, newsletter and the Node lists take the general rows and window; the own numbers 50, 25, 20 and 10 and the windows 8 and 10 leave
  • The pager of the language editor shows the general window in place of every page
  1. The lists of the site (core/user.php, modules/*/index.php, modules/changelog/common.php):
  • comments, privat, search, voting, forum and changelog read getPageRows() and getPageSpan() of their section
  • The members list, the logins and "My materials" of the cabinet take the general numbers in place of 50 and 20
  • The Node list caps the list.limit of its type by the own number of the visitor, which the hint of that setting always promised; the window is the general one in place of 8
  • The topics of the forum keep their own listnum (50), the private messages their own span (5)
  1. The settings of the modules (core/admin.php, the config forms of six modules, config/*.php):
  • getTplPagerFields() draws the two fields rows and span, empty for the general number shown as its placeholder; getPagerPost() reads them; both replace the same fields of six forms
  • anum, anump, num, nump, snum, snump, pnum and perpage leave the configs and the forms; favorites.num and favorites.nump, read by nothing, leave with them
  1. Texts, help and documents (admin/lang, modules/account/lang, modules/changelog/admin/lang, admin/info, modules/*/admin/info, docs/):
  • _C_33 to _C_36 name the four numbers plainly, _PAGER_OWN says that an empty field takes the general number, _ADM_ROWSDEF and _ADM_ROWSNOTE name the general default, _ACCOUNT_STORYNOTE names every list of the site; _SEARCHNUM and _CHLOG_PER_PAGE leave; six locales
  • The help of config, panel, comments, privat, account, changelog, search, forum and voting describes the fields
  • docs/TEMPLATES.md (Admin List Contract, Rows per page, Pager), POINTS.md, RATINGS.md, VERSIONS.md
  1. Tests (tests/Support/*.php, tests/Unit/AdminListRowTest.php, PointOwnersTest.php):
  • The probes of rows, comments, privat, search, account and changelog post and read the new keys
  • The list canon test defines the texts of the rows chip, which every paged list now draws

Benefits:

  • One place decides the density of all lists; a module states only what differs
  • The own number of a visitor works on every list of the site, not on the forum alone
  • 434 lines leave, 271 come

Technical notes:

  • Breaking: the config keys above are removed; a site updated by the merge of config/ gets pager, rows and span and keeps the old keys unread
  • config/local.php must be deleted after the files arrive, or the site runs on the cached old keys and the defaults in code
  • A Node type keeps list.limit as before; no URL, schema or API contract changes
Perf: The presentation pauses by scene and block, its running block wires repaint on a layer of their own, and the pulse strip sleeps between steps
Автор: Eduard Laas | Дата: 22:16 07.11.2026

A pass over the frame cost of /presentation: the half of a tall section below the window no longer runs, the dashes of the block scene no longer raster the whole scene every frame, and the pulse line stops redrawing once it reached its aim. The picture stays within the pixel tolerance of the rig on every touched part.

Core changes:

  1. The off-screen pause by part (public/plugins/presentation/presentation.js):
  • setOffScreen() watches each scene and block (.sl-pres-scene, a child of .sl-pres-body or of the hero) beside the sections, so data-sl-pres-off marks the part that left the window
    • an SVG pauses its SMIL while any part round it is off, under still motion as before
    • an arc in a part still off waits for that part and fills from zero when it first comes into view
  • The development screen ran the PDO packet of the section above it on left, a refused animation; it now stands
  1. The block wires on a layer (public/templates/lite/assets/css/presentation.css):
  • .sl-pres-blocks-stage > .sl-pres-wires takes will-change: transform: the dashes running by stroke-dashoffset repaint on their own layer instead of the scene under them
  • The map keeps its wires in the scene: its core stands on a half pixel and rastered 90 of 255 apart on a layer (owner, 2026-11-07)
  1. The pulse strip (public/plugins/presentation/presentation.js):
  • setPulse() sleeps by a timer until the next step once the largest move of a frame is under 0.005 of the scale, about 0.03 px; at 60 Hz the line never reaches it and draws every frame as before
  1. The rig and the documents (tools/frame-cost.mjs, docs/PERFORMANCE.md, docs/TEMPLATES.md):
  • States for every section of the presentation (pres-workbench, pres-runtime, pres-dev, pres-live, pres-dna, pres-archive, pres-showcase, pres-voices, pres-pulse) and the part blocks for the pixels
  • The pair of the pass, the forms measured and not taken, the memory of the new layer and the share of the cockpit lamp in PERFORMANCE.md; the laws of the part pause and of the running dash in TEMPLATES.md

Benefits:

  • System screen: GPU 119 -> 61 %, renderer 50 -> 48 % (medians of 5 rounds against HEAD)
  • Development screen: renderer 51 -> 35 %, layout 17 -> 11 ms/s
  • Guard screen: renderer 82 -> 78 %, style 69 -> 61 ms/s; top: script 13 -> 10 ms/s

Technical notes:

  • Pixels within 16 of 255 in both schemes on hero, system, blocks, guard, runtime, development; pipeline differs by 20 on 2 pixels in the light scheme, under its own noise of 27
  • The new layer costs 14 layers and about 9 MB of compositor resources; the raster scratch of Skia falls from about 170 to 130 MB; heap, nodes and listeners stand still over a minute
  • No markup, URL or template key changed
Feature: A Node type can be a listing of events, an author's publication can leave the site after a set time with «Мои материалы» to renew it, and the profiles events and jobs ship
Автор: Eduard Laas | Дата: 19:47 07.11.2026

Three things the Node types still lacked before 8.0: a dated listing with an archive, ads that do not stay forever, and two profiles built on them. The extension event keeps a start, an end and a place per material in a table of its own and orders the list of its type; workflow.lifetime ends an author's publication after a set number of days and the cabinet lets the author renew it.

Core changes:

  1. The extension event (core/classes/node/ext/event.php, core/classes/node/ext/load.php, core/classes/node/extension.php, core/classes/node/ext/support.php, core/classes/node/ext/sync.php, core/classes/node/query.php):
  • NodeEvent stores the start, an optional end and the place of a material in the new table _node_event
    • the list of its type shows the upcoming events, the nearest first; an event stays upcoming until its end, or without one until the end of the day it starts
    • the argument archive shows the past ones, the newest first, in place of the sort and the direction
  • The interface NodeExtension takes ten methods: getNodeScope() receives the list arguments, getNodeOrder() is new
    • NodeQuery::setNodeArgs() hands the arguments of the list to the extension of the single selected type; getExtOrder() and the column check RANK keep the order of the extension trusted
    • support and sync return no order and keep the order of their type
  • The display mode event is in NodeQuery::MODES and belongs to the type of that extension alone (EXTMODES)
  1. The lifetime of a publication (core/classes/node/service.php, core/classes/node/query.php, config/node.php, modules/node/admin/index.php, modules/node/admin/lang/*.php, modules/node/admin/info/ru.md):
  • The key workflow.lifetime, days from 0 to NodeQuery::LIFEMAX (3650), checked with the workflow section; 0 keeps the old behaviour and is the default of config/node.php
  • NodeService sets the end of a material one lifetime after its publication when an author who is no moderator publishes it directly, or when a moderator approves it from «На проверке», each only while no end is set
    • a moderator's own material keeps the end the moderator gives
    • an edit of a type without scheduling keeps the stored end
  • NodeService::updateNodeTerm() renews a published material of the signed-in author from the clock of the database, a repeat sets the same end, never a sum
  • The form of a type has the field «Срок показа, дней»; the help describes it
  1. The cabinet screen «Мои материалы» (modules/account/index.php, modules/account/lang/*.php, core/user.php, core/system.php, core/classes/route.php):
  • materials() lists the author's published materials of active types with a lifetime, shown and expired, with their end, through NodeQuery::getNodeTermList()
  • renew() is a POST with the token through checkSitePost('account') and calls updateNodeTerm()
  • getUserNavItems() adds the item while an active type has a lifetime; getIconName() knows renew and terms; Route::OPS of account carries materials and renew
  1. The forms, the public module and the lite theme (modules/node/index.php, modules/node/admin/index.php, modules/node/lang/*.php,public/templates/lite/partials/node/head.html, public/templates/lite/partials/node/event/view.html, public/templates/lite/fragments/node/event/card.html, public/templates/lite/assets/css/theme.css):
  • The list of an event type reads archive, keeps it in the pager, the canonical address and the sort links, and the header shows the switch «Архив»
  • The forms of the panel and the site show the start, the end and the place; a refused form of the panel names a changed event field among the differences
  • The mode event draws the start as a calendar leaf on the card and the page
  1. The profiles (modules/node/profiles/.json, lang/.php, tools/node-profile.php):
  • events: the extension event with a cover and a gallery of up to 20 images, categories, comments, favorites, the home page, pinning and moderated submissions
  • jobs: salary, city, employment (full-time, part-time, remote), e-mail and address, a cover for the logo and the switches of board
  • board and jobs take workflow.lifetime 30; every other profile carries lifetime 0; seven constants in six languages
  • The load profile fills _node_event for event types
  1. The schema (storage/update/sql/table.sql, storage/update/sql/table_update6_3.sql):
  • CREATE TABLE _node_event (nid, starts, ends, place) with the key starts, a cascade from _nodes and the check that an end lies after the start; the update creates it and converts its collation
  1. Tests and documentation (tests/Unit/NodeEventTest.php, tests/Unit/NodeTest.php, tests/Unit/RequestWatchTest.php, tests/Support/_probe.php, docs/NODE.md, docs/VERSIONS.md):
  • NodeEventTest checks the extension, the writes and reads through NodeService and NodeQuery, the routes and the statement budget of the list
  • NodeServiceTest checks the publication, the approval, the moderator's own material and the renewal; NodeProfileTest and the installation probe check the sixteen profiles through a real installation, an event written through the panel included
  • docs/NODE.md describes the extension event, the lifetime, «Author's materials» and the import of an older file

Benefits:

  • A calendar of events and classifieds that expire come with the installation, without a module of their own
  • The order of a list stays in the query: an extension gives one trusted column, never a sort key of the visitor

Technical notes:

  • New table _node_event: a stand that has the code runs its CREATE TABLE from table.sql with its prefix, and rebuilds config/local.php for the new key of config/node.php
  • A profile file without workflow.lifetime imports with 0 and stays format version 1
  • Breaking: the interface NodeExtension changes getNodeScope() and gains getNodeOrder(); the factory is closed, so only the extensions of the core implement it
Feature: The look is one system: a field keeps one height, a form sends its file through the door of the window, the changelog and the forums of the panel are canon lists, and the site menu is a drawer on a phone
Автор: Eduard Laas | Дата: 15:32 07.11.2026

The run of the panel and the site in a real browser found small classes, sizes and lists that each had a look of their own. This change moves them onto the shared parts of the two themes: one height for a field, one copy button for code, one file door, one list canon, one segmented switch and one drawer. The type form of Node becomes tabs of one form, and config/points.php ships in the shape the panel writes.

Core changes:

  1. The changelog in the panel (modules/changelog/admin/index.php, modules/changelog/common.php, modules/changelog/index.php, modules/changelog/admin/lang/*.php, modules/changelog/admin/info/ru.md):
  • changelog() draws a table of getTplAdminList(), one row per commit: hash, title, author, changes and files (with statistics on a local Git), and date as a moment
    • the "i" of a row holds the body through $prs->filterDoc(), the e-mail and the per-file +/- lines; the search word is marked by filterTextHighlight() in the title and the body
    • the filter is fragments/list-filter.html in the tab head (word, author, file except for GitHub, date from/to); the pager reads num and the per-page choice through getListLimit(), with perpage as the base
    • an error of loading or an empty result goes to none_text (_NONE_FOUND under a filter, else _NO_INFO)
  • rendpage() is gone; the panel no longer groups by date and no longer makes the canonical redirect
  • chlogCanonicalRedirect() drops its $base argument and serves only the site
  • The help describes the table, its columns, the filter, the pager and "Группировать по дате" acting on the site alone
  1. The forums in the panel (modules/forum/admin/index.php, modules/forum/admin/info/ru.md):
  • forum() builds its list with getTplAdminList() instead of a bare table in a box: the description sits in the "i" of the row, the status is a lamp, every column sorts, and the view switch and key tip of the canon stand above it
  1. Node in the panel (modules/node/admin/index.php, modules/node/admin/lang/*.php, modules/node/admin/info/ru.md):
  • add() opens the form of the first type the user moderates right away; a select "Тип" (list-filter, is_now) in the tab head switches the type, which replaces the page of links that listed the types
  • getNodeTypeRows() becomes getNodeTypeTabs(): the type form is six runtime sub-tabs of one form (_GENPREF, _LIST, _NODE_FEATURES, _NODE_FLOW, _NODE_ROLES, _NODE_INTEG), and the form carries is_valid
    • each on/off setting (alphabet, every feature and integration, guestok, report, canlink, active of a role) is a Yes/No radio group of getTplRadioGroup() with its own caption, in place of a checkbox labelled "Да"
    • the sort direction has its own row (_NODE_ORDDIR new); minimum and maximum of a role are two labelled rows
    • each resource role is a partials/toggle-form-block.html block with its key in the cap, in place of the repeat fragment; _NODE_ROLEOPTS is gone
  • The profile of a new type is a select "Профиль" in the tab head with an empty choice, in place of a row of links
  • import() takes the file through getFormFileField()
  • The help describes the "Добавить" type selector, the tabs of the type form, the profile selector and the role blocks
  1. The file door of an ordinary form (core/helpers.php, public/templates/{admin,lite}/fragments/file-field.html, public/plugins/system/slaed.js, admin/modules/update.php, lang/*.php):
  • getFormFileField() prints fragments/file-field.html with is_form: a button names the action by _FILEPICK, a chip shows the name and size of the picked file, a cross clears it
    • the form door carries data-sl-file-form and no data-editor, prints no path or address carrier, and keeps a required file field out of sight (sl-visually-hidden, tabindex -1), so the browser refusal points at the door
    • setFileDoors() and setFileDoor() of slaed.js open the browser picker, show the name and size, clear the field and return the focus to the button
  • "Загрузить архив" of update is now a pane of its own (fragment pane, icon cloud-upload) and takes the door
  • getTplUserSearchInput() no longer marks its input as required
  1. The drawer menu of the site on a phone (public/plugins/system/slaed.js, public/templates/admin/assets/js/admin-ui.js, public/templates/lite/partials/site-header.html, public/templates/lite/assets/css/theme.css, lang/*.php):
  • setDrawer() moves from admin-ui.js into slaed.js and finds its menu by the aria-controls of the toggle, so one drawer serves #sl-menu of the panel and #hmenu of lite
    • the page goes inert while the drawer is open; Esc, the scrim, the cross or a window opened from the menu close it, and it closes once the toggle is hidden; the focus returns to the toggle
  • The header of lite gets the toggle sl-menu-btn with _MENU, the scrim sl-menu-scrim, and #hmenu as a nav with the cross sl-menu-close; below 900 px the menu and the search form one column of the drawer, above it the bar is unchanged
  1. Sizes and small classes of both themes (public/templates/{admin,lite}/assets/css/{base,theme}.css, public/templates/{admin,lite}/fragments/code-block.html, public/templates/admin/partials/{layout-screen,statistic-cockpit,toggle-form-block}.html, admin/modules/statistic.php, admin/info/fields/ru.md):
  • base.css of admin gives every one-line input and single select the height --sl-size-control
  • The copy button of a code head and of the link window of the builder is .sl-code-copy in both themes, a quiet square of --sl-size-chip, larger on a touch screen, in place of the borrowed .sl-modal-act
  • "Сейчас" and "Вчера" of the statistic cockpit are a plain sl-seg with its knob (rail stat-day); the server sets the active cell from is_now and admin-ui.js toggles sl-is-active with aria-pressed; .sl-cockpit-set is gone
  • partials/toggle-form-block.html puts the name with the + toggle in a cap and its rows under it at the full width of the box; the side panel of the builder keeps them stacked; the help of the additional fields follows
  • A list filter whose only fields are is_now selects shows its OK button only without scripts (@media (scripting: enabled))
  • The chips of the private messages take --sl-size-chip, their bulk bar field --sl-size-control
  • The changelog CSS of the admin theme is removed
  1. Points config (config/points.php, docs/POINTS.md):
  • config/points.php ships in the shape setConfigFile() writes: actions before active, one key per line, so an unchanged save of the panel leaves the file as it is
  1. Tests (tests/Support/config_probe.php, tests/Support/route_probe.php, tests/Unit/{ConfigFileTest,EditorWindowTest,PointTest,AdminSecretTest,ListPickTest}.php):
  • getProbeShipped() finds every setConfigFile('<name>.php') of admin, modules and core, saves each shipped file unchanged and reports any file that moves, ignoring the header year; anUnchangedSaveKeepsEveryShippedFile checks it
  • anOrdinaryFormSendsItsFileThroughTheSameDoor checks the form door in both themes, getFormFileField(), _FILEPICK in six locales, update and Node import on the builder, and setFileDoors() started by slaed.js
  • PointTest expects the key order actions, active
  • route_probe and aDelegatedAdministratorWritesNoSecret: a changelog post of a delegated administrator that names the GitHub fields is refused whole, and the same form without them saves perpage and keeps the token and the source
  • ListPickTest: a comment names the clear form by its op
  1. UI tools (tools/ui-contract.php, tools/ui-shots.json, tools/ui-contrast.json, tools/ui-audit-baseline.json):
  • ui-contract drops pmf-filter, the exceptions of the admin changelog classes and of fragments/changelog-commit.html, and adds the theme differences of .sl-menu-btn, .sl-menu-btn .bi and the 900 px .sl-menu-close
  • ui-shots captures drawer-open on the front page (optional step)
  • The contrast list and the audit baseline are regenerated
  1. Docs (docs/TEMPLATES.md, docs/WINDOW.md, docs/UPDATE.md, docs/VERSIONS.md):
  • TEMPLATES: the toggle form block, the is_now select of a list filter, the drawer of a phone, the screen switch as the plain sl-seg
  • WINDOW: .sl-modal-act only for window actions and .sl-code-copy for code; the form door of getFormFileField()
  • UPDATE: the changelog*.html templates and the changelog CSS stay only in lite
  • VERSIONS: the sections of 2026-11-05 and 2026-11-06, including this change under "The look is one system"

Benefits:

  • One field height, one copy button, one file door, one list canon and one drawer across both themes, so a fix lands in one place
  • The changelog and the forums of the panel sort, switch views and page like every other list
  • A shipped config the panel writes no longer changes on its first unchanged save

Technical notes:

  • No database change
  • Removed templates: admin partials/changelog.html, partials/changelog-body.html and fragments/changelog-commit.html, changelog-date-header.html, changelog-stats.html
  • Breaking for a custom theme: the tokens --sl-pmf-filter-height (lite) and --sl-changelog-width, --sl-changelog-body-border, --sl-changelog-files-height, --sl-changelog-stat-width (admin) and the class .sl-cockpit-set are gone; the admin theme has no .sl-changelog-* rules
  • The admin changelog list pages by num instead of page, and its filter no longer redirects to a canonical address
  • New constants: _FILEPICK and _MENU in lang/.php, _NODE_ORDDIR in modules/node/admin/lang/.php
  • Removed constants: _NODE_ROLEOPTS; _CHLOG_FILTER, _CHLOG_SEARCH_PH, _CHLOG_AUTHOR_PH, _CHLOG_FILE_PH, _CHLOG_FILTER_BTN, _CHLOG_RESET_BTN, _CHLOG_TOTAL, _CHLOG_FILTERED, _CHLOG_PAGE, _CHLOG_COMMITS, _CHLOG_COMMITS_REPO, _CHLOG_ERR_NO_COMMITS of the changelog admin
  • The on/off settings of the Node type form now post 1 or 0 from a radio group under the same names
  • getNodeTypeRows() is replaced by getNodeTypeTabs(); setDrawer() leaves admin-ui.js for slaed.js
  • config/points.php changes only its layout and key order; its values are the same
Fix: The load profile of Node runs again and measures a delete and a list page by the code of today
Автор: Eduard Laas | Дата: 15:31 07.11.2026

php tools/node-profile.php stopped at "Invalid node input: name" before measuring anything, and two of its limits had fallen behind the code. The full run of 100000 materials in fourteen types now passes without a failure.

Core changes:

  1. The scratch configuration (tools/node-profile.php):
  • setProfileConfig() drops the types the committed config/node.php names, with their fields, upload rules and rating rules, as deleteSetupTypes() of setup.php drops them before the profiles are imported
    • the committed config names the types of the stand, so every profile met its name taken in checkNewName()
  1. The budgets (tools/node-profile.php, docs/NODE.md, tests/Unit/NodeServiceTest.php):
  • A physical delete costs six Node statements: getNodeHead() reads the head with the name of the type and then the type, before the locks of type, material and resources and the DELETE; PBUDGET 'delete' and the table of docs/NODE.md say 6, as the description of the delete there already listed
  • A row of a list page passes six reads, not four: the two paths of NodeQuery::getPathSql() joined the page on 2026-10-14, after the bound was written; getProfileBound() and the formula in docs/NODE.md take 6 x page size
  • The comment of NodeServiceTest names six Node statements of a delete

Benefits:

  • The load profile of Node can be run again before the release
  • Its limits fail on a real regression, not on the code that was accepted

Technical notes:

  • No change of the core, the database or a URL; the tool runs by hand only
  • Result: list docs 488 of 550 rows, list media 1100 of 1178, delete news 6 of 6 statements, no budget overrun and no full scan
Хотите опробовать SLAED CMS в действии?
Идеи и предложения
Обратная связь
Подтверждение

Поделиться
QR-код

Предварительный просмотр