Guide

Managing modules

Modules are the unit of functionality in Mantle. This guide covers inspecting what is registered, changing state safely, and understanding what does and does not disappear when a module is switched off.

Inspect current state

List modules bash
wp eval 'foreach ( get_option( "mantle_modules", [] ) as $m ) { printf( "%-22s %-11s %s" . PHP_EOL, $m["slug"], $m["type"], ! empty( $m["active"] ) ? "active" : "inactive" ); }'
client_info            core        active
communication          functional  inactive
monitoring             functional  inactive
ai_chatbot             functional  inactive
welcome                core        active
maintenance            functional  inactive
security               functional  inactive
sso                    functional  inactive
optimizations          functional  inactive
convergence_cache      functional  inactive
user_management        functional  inactive
dashboard              core        active
site_code_snippets     functional  inactive
white-label            functional  inactive
plugin_sync            functional  active
linchpin_licenses      functional  active

That is real output from a development installation. The mantle_modules option is the source of truth for enabled state; the module classes are the source of truth for what exists.

Change module state

Terminal
curl -X POST \  --cookie "$COOKIE" \  -H "X-WP-Nonce: $NONCE" \  https://example.com/wp-json/mantle/v1/modules/monitoring
All three paths write the same mantle_modules option.

update_module_status() is deliberately conservative. It returns early — doing nothing at all — in three cases:

Reference

When update_module_status does nothing

3 fields
Unregistered module string
Module_Loader::has() returns false. A typo in the ID fails silently rather than erroring — white_label instead of white-label is the common case.
State already matches string
The requested state equals is_enabled(). This means calling it on a core module with true is a no-op, and with false is also a no-op.
Absent from the storable list string
The module ID is not present in the freshly built option list.

What disabling actually does

This is the part most worth internalising, because it is not simply "the module goes away".

Flow

Enabled versus disabled

7 relationships
Schema survives; behaviour does not.
Reference

Effect of disabling a module

5 fields
Settings keys string
Still in the schema, still readable, still returned by the settings REST route. Stored values are preserved and are not reported as orphaned.
Capability definitions string
Still listed by get_all_capabilities(), and still granted to roles by a capability sync. They are inert because the routes are gone.
REST routes string
Requests return 404 rest_no_route. The AI routes are an exception — they are controller-registered and always present.
Hooks and behaviour string
init() is never called, so nothing the module hooks takes effect.
Admin UI string
The module’s tab and panels are not rendered.

Because settings survive, disabling and re-enabling a module is non-destructive: configuration is exactly as it was.

Dependencies between modules

One dependency is enforced in code. Core\Modules::sanitize_module_settings() runs on every save of the mantle_modules option and forces ai_chatbot inactive whenever communication is inactive.

  1. Enable communication

    POST to /mantle/v1/modules/communication, or toggle it in the admin UI.

  2. Enable ai_chatbot

    Only now will it persist. Attempting it first appears to succeed but the sanitiser reverts it.

  3. Configure a provider

    The chat surface also requires Provider_Manager::is_configured() to return true, in addition to the mantle_access_chatbot capability.

Warning
Enabling ai_chatbot alone looks like it worked

The write succeeds and the response is a success, but the sanitiser sets active back to false before the option is stored. Re-read /mantle/v1/modules to confirm the state actually persisted.

Core\Modules::sanitize_module_settings()

Verify after a change

Confirm state and schema bash
wp eval 'echo \Mantle\Modules\Module_Loader::get( "monitoring" )->is_enabled() ? "enabled" : "disabled", PHP_EOL;'
wp mantle settings audit
disabled
Option: mantle
Schema keys: 102
Saved keys: 102
Missing schema keys: 0
Orphaned saved keys: 0

Success: Settings audit passed. Saved keys match the registered schema.

Note the key count does not drop when a module is disabled — further confirmation that schema registration is independent of module state.

See also

Was this helpful?