feat: group settings into task-based tabs - #486
Merged
Conversation
General had grown large enough that whole features sat in the same flat list as small preferences, and the tabs people need when something has gone wrong are the ones hidden behind other settings. Regroup the settings into tabs by what someone came to the page to do: Editing, Running, Insights, Library, Interface and Advanced. A tab with nothing to show does not appear, so the free plugin shows four while Pro shows six, from one shared map. Storage is deliberately untouched. Call sites name a section when reading a setting, and the saved option is keyed by section, so moving fields between sections would break every read and orphan every existing install. Settings_Layout maps each tab to a list of [storage section, field] pairs; Setting_Field still receives the original section for its name attribute and value lookup, and only add_settings_field receives the tab. Saving from a new tab writes to the old section. Also here: - Long tabs are broken up by group headings, rendered by a heading-aware stand-in for do_settings_fields(). A heading whose fields are all absent is skipped with them. - Settings whose description named the control without saying what it was for have been reworded. - get_current_section() now falls back to the first registered tab. Naming a section as the default meant the page rendered empty the moment that section stopped existing. - The editor preview refresh is no longer keyed to a hardcoded section name. CodeMirror measures itself as zero-height while hidden, so the preview rendered blank on any tab not literally called 'editor'. Tab identifiers are repeated in the PHP layout, the SCSS $sections list and the JS. Worth consolidating if this is taken further.
ramiy
reviewed
Sep 1, 2026
Comment on lines
+75
to
+79
| 'insights' => [ | ||
| [ 'general', 'enable_performance_tracker' ], | ||
| [ 'general', 'enable_security_scan' ], | ||
| [ 'general', 'rescan_all_snippets' ], | ||
| ], |
Contributor
There was a problem hiding this comment.
what is that? it's not visible on the admin screen.
This was referenced Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposal, opened for discussion rather than to merge as-is. This is visible UI so it needs John's eye before it goes anywhere.
Settings exist in both editions, so per the branching policy this is a shared change: Core first, then sync into Pro.
Why
Settings have been accumulating in General for a while. On V4 it reaches seventeen fields, and several of them are whole features rather than preferences — minification, file-based execution, performance tracking, security scanning and revisions all sit in the same flat list as Hide Upgrade Notices.
The tabs people need when something has gone wrong are also the hidden ones: Version only appears after ticking a box inside Debug, which is a strange place to look when your site has just broken.
What this does
Groups the settings into tabs by what someone came to the page to do:
A tab with nothing to show does not appear. One shared map covers both editions: fields belonging to the other edition are simply absent, so free renders four tabs and Pro six, with no separate layout to keep in sync and no hollow tabs.
Long tabs are broken up by group headings. Settings whose description named the control without saying what it was for have been reworded — "Track Snippet Performance" is a label, "Measure how long each snippet takes to run, so you can find the slow one without guessing" is a reason to switch it on.
Storage is untouched, deliberately
This is the part worth reviewing closely. Call sites name a section when reading a setting, and the saved option is keyed by section, so physically moving fields between sections would break every read and orphan every existing install.
Settings_Layoutmaps each tab to a list of[ storage section, field id ]pairs.Setting_Fieldstill receives the original section for itsnameattribute and value lookup; onlyadd_settings_field()receives the tab. Nothing migrates, andget_setting( 'general', 'enable_flat_files' )keeps working untouched.Verified by hand: unticked a setting from the Running tab, saved, and it wrote to
general/. Stored sections afterwards were unchanged with no new keys.Three bugs found on the way
All the same underlying problem, tab identifiers hardcoded in several places:
get_current_section()defaulted to the literal'general'. Once that section stops existing, opening Settings from the menu renders a page with no settings on it. Now falls back to the first registered tab, which fixes this generally rather than for these six names.tabs.tsonly refreshed CodeMirror when the section was literally'editor'. CodeMirror measures itself as zero-height while its container is hidden, so the editor preview mounted and rendered blank on any other tab name.$sectionsinsettings.scssdrives the[data-active-tab]show/hide rules and is a hardcoded list, so new tabs rendered into the DOM but stayed invisible.Tab names now live in the PHP layout, the SCSS list and the JS. Consolidating that is the obvious follow-up.
Testing
phpcs,stylelintandeslintclean.Checked on a free install (WP 7.1 / PHP 8.5): no fatal, four tabs shown, Insights and Library correctly absent, group headings render, editor preview mounts at full height, saving round-trips to the original sections.
Also built and checked against V4 on a Pro dev site, where all six tabs populate.
Next
Once this lands, it syncs into Pro. There is a clickable mockup of the same idea with the reasoning written out, if that is easier to react to than a diff.