The multisite release. Minn runs on a WordPress network now. A chevron beside the site name moves you between the sites you belong to, and the palette knows them by name. If you run the network, a fourth sidebar group appears: every site with its state and members, the network settings worth revisiting, the accounts and who administers them, and plugin and theme activation for the whole network from Extensions. The rules WordPress leaves to its own screens are enforced here on the server: the main site is never offered deletion, nobody revokes their own network administrator status or the last one on the network, and a site administrator's view stops at their own site. That last point drove a security pass across the release. Several plugins keep one table for an entire network, and Minn was reading them with a single site's permission; those, the shared debug log, and everywhere Minn writes or runs code now ask for the permission the data deserves.
Added
-
A Network area for the people who run the whole network. Network administrators get a Sites view: every site on the network with its address, member count and state, filters for public, archived, spam and deleted sites, and search. From a site's row you can open it in Minn, visit it, archive or restore it, mark it as spam or clear that, and delete it. Adding a site takes an address, a title and the email of someone who already has an account. The main site of the network is never offered archive or deletion, nor is the site you are working in, and every one of these refusals is enforced on the server rather than only hidden in the interface. Site administrators do not see any of it. Network-wide settings and account creation stay in Network Admin, one click away.
-
The network settings you actually revisit. Registration (who may sign up, and whether new sites and accounts email you), uploads (storage per site, the largest single file, which file types are allowed), whether site administrators may create accounts and manage plugins, and where network mail goes. The rest of the network settings screen, the welcome emails and reserved names and language defaults, stays in Network Admin behind a link, the same way Minn treats a single site's settings long tail.
-
Turn a plugin on everywhere, or offer a theme to every site. Network administrators can activate a plugin across the whole network from its card in Extensions, and withdraw it again, without leaving for Network Admin. Themes get the matching control: offer one to every site, or stop offering it. These are separate from a single site's own switches, so turning a plugin off network-wide leaves sites that chose it for themselves alone, and withdrawing a theme never changes the theme a site is already using. Minn will not deactivate itself network-wide from inside itself.
-
Network accounts, with the safety rails WordPress leaves to the screen. The Network area lists every account on the network with the number of sites it belongs to, and marks the network administrators. You can promote someone or take that status away, but never your own (that would lock you out of the network) and never the last one standing. Where the list of network administrators is fixed in wp-config.php, Minn says so instead of offering buttons that would do nothing. Creating and deleting accounts stays in Network Admin, because deleting a network account removes that person's posts from every site and only WordPress's own flow offers to reassign them first.
-
Move between sites on a network without leaving Minn. A chevron beside the site name opens a compact switcher with an autofocused search field and no more than five fuzzy-matched sites at a time. It searches site names and addresses across the full set you can use, so
team1findsTeam 1and even a shorthand liketm10reachesTeam 10beyond the initial menu cap; arrow keys and Enter work without leaving the field. Network administrators get a link to Network Admin from the same menu. The command palette carries the sites too, so ⌘K and a site's name is enough. Nothing appears when you belong to a single site, or when the site is not part of a network. -
Users on a multisite subsite now work the way the network intends. A site administrator sees the whole site's user list again (it used to collapse to just their own account), changes roles from the row menu, adds an existing network account to the site by email or username with a role, and removes a member from the site without touching their network account or other memberships. Deleting accounts stays a Network Admin job, and network administrators are off limits: their rows offer no role or removal controls, and the server refuses such requests no matter where they come from.
-
Core updates finish the job on a network. After updating WordPress on a multisite network, every site's database migration now runs as part of the update, the way Network Admin's Upgrade Network does; before, only the site you updated from migrated, and the rest waited for someone to open each dashboard. The update status check also notices a half-finished network walk and completes it.
-
Translations join the rest of the updates. WordPress keeps language packs apart from plugin, theme and core updates, so Minn could tell you everything was current while WordPress itself was still offering Update Translations. Waiting translations now appear in the Updates list, count toward the update badge, and go in with everything else when you update. They install in one step, the way the WordPress screen does it, and only for someone allowed to install languages.
Fixed
- Links that carry a whole address work again. Where a plugin's row action links straight to an address the item supplies, rather than building one around it, the address was being escaped as though it were a fragment of a longer link. The result was a dead link back to the current site with the real destination stuck on the end. This affected the Performance Lab settings links, and would have affected the new per-site links in the network Sites list.
- Network-activated plugins read as what they are. On a multisite network, a plugin activated for the whole network showed in Extensions as Inactive with a live switch, and clicking it tried to activate a plugin that was already running. Those plugins now show a Network active label with no switch, count as active in the filters, and their menu drops the activate and delete entries; network-wide changes belong to Network Admin.
- Security and backup histories stay inside the right hands on a network. Several plugins keep one network-wide table that Minn read with a single site's permission: Wordfence's login log, Solid Security's lockouts, Duplicator's backup packages, and Limit Login Attempts in its network mode. A site administrator could see, and in some cases act on, other sites' data. Each now requires network permission on a network, matching where those plugins put their own screens.
- The System page no longer offers logs it will not serve. On a network, the shared debug log is readable only with network permissions, but the Debug card still showed every log source to a site administrator, whose clicks then failed. The card now lists only what the viewer may actually open.
- Minn's address now works across a whole multisite network. Activating Minn network-wide only taught the main site the /minn-admin/ address; every other site on the network answered Not Found until its rewrite rules were rebuilt by hand. Each site now repairs its own rules the first time Minn loads there. Deactivating had a mirror problem on any site, multisite or not: the address quietly kept working and showed the homepage. Deactivation now removes the route cleanly, network-wide.
- A capability check could be pointed at the wrong thing. Two places asked "may you do this?" about one item and then acted on another, because the question and the answer read the request differently. On WPCode, sending the snippet type in the web address rather than the body skipped the check that decides who may write PHP, so someone trusted only with markup could turn a snippet into code the site runs. On the user routes, a request could ask about your own account while writing to somebody else's, so any signed in visitor could change an administrator's Minn language or appearance. Both now resolve the target once and act on that.
- Snippets that run as code now need the capability that implies. Custom CSS and JS quietly ran non-privileged code through an HTML filter, which does nothing to JavaScript, and then wrapped it in a script tag anyway. JavaScript and HTML snippets now require the unfiltered HTML capability, as do stylesheets that load in the admin or on the login screen, and a stylesheet cannot be retyped into JavaScript to get around it. Editing ordinary front end CSS is unchanged. Header Footer Code Manager already refused those writes, but activating or deleting an existing snippet skipped the same check, and both now take it.
- Form entries stay with the person who owns the form. The Everest Forms list showed every author's entries, including the submitted answers, to anyone who could see entries at all. It now follows the same own and others rule the plugin applies everywhere else, and so do the form list and the entry counts.
- Shared logs are no longer treated as this site's own. On a network, wp-content holds one debug log for every site on it, and the viewer could read and empty it with a single site's permissions. It now asks for network permissions there, matching the database browser. The viewer also stopped falling back to the server's own PHP error log, which on shared hosting belongs to other people's sites entirely.
- A network's security history stays inside each site. The All-In-One Security activity log is one table shared by every site on a network, and Minn read all of it. A site administrator could see other sites' sign in attempts, usernames and addresses. It is now scoped per site, the way the plugin itself scopes it.
- Unpublished titles stay unpublished. The field naming the post a media item belongs to was readable without signing in, which revealed the titles of drafts, pending and scheduled posts through the media list.
- The dashboard no longer shows a Contributor more than the dashboard should. Stepping through the activity chart listed the names of people whose comments were still awaiting moderation, to roles that have no comment screen at all. The registered user count and the site's visitor and referrer figures were on the same footing, where WordPress and every analytics plugin ask for more. Each is now held to the permission it belongs to.
- A site that forbids editing code from the dashboard is now believed. Setting DISALLOW_FILE_EDIT stops WordPress letting anyone reach PHP on disk, and Minn did not consult it. The wp-config editor, PHP snippets and JavaScript snippets now decline on such a site and say why. Ordinary stylesheet editing is untouched.
- Notice buttons cannot point off the site. A notice from another plugin could offer a link that looked like a local Dismiss button but belonged to somebody else's server, and clicking it sent that server a token and your address. Links are now checked against the site they claim to be on.
- Credentials no longer linger next to the site. Changing a debug setting left behind a permanent readable copy of wp-config.php, database password and security keys included, beside the original. The copy now exists only for the moment of the change and is removed as soon as the new file is confirmed written.
- Form estates stay with their owner. Fluent Forms listed every form's name and submission volume to a manager assigned to one of them, and WPForms could lose its scoping altogether on a site with many forms.
- Every snippet that runs code now follows the same rule. A site that sets DISALLOW_FILE_EDIT is telling WordPress that nobody reaches PHP from the dashboard, and Minn already declined to write WPCode PHP snippets there. Code Snippets sat in the same Snippets view and still offered to author and switch on new PHP. It declines now too. Turning an existing snippet off, deleting one, and the link out to the plugin's own screen all keep working, because stopping code from running is never the direction that needs guarding.
- Smaller hardening. Image addresses are escaped for stylesheets rather than for HTML, so an unusual media URL cannot append its own styling to the page. The updater's check that a download belongs to this project now has to match from the start of the address rather than anywhere in it. The admin bridge page escapes its redirect properly. Turning on a Performance Lab feature asks for the permission that installing a plugin actually needs.