nyoncode / wire-module-settings
Application settings for wire: typed key/value settings with a page to edit them.
Requires
- php: ^8.2
- illuminate/database: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- livewire/livewire: ^4.0
- nyoncode/laravel-package-toolkit: ^2.5.0
- nyoncode/wire-core: 2.0.0
- nyoncode/wire-forms: 2.0.0
- nyoncode/wire-panels: 2.0.0
- nyoncode/wire-table: 2.0.0
Requires (Dev)
- laravel/pint: ^1.29
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^4.0|^5.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
wire-module-settings
Typed application settings for the wire framework: a table, a cache, and a screen — with what is configurable left to the application.
composer require nyoncode/wire-module-settings php artisan wire-module-settings:install php artisan migrate
The one thing you write
A package that shipped its own list of settings would be guessing what an application needs, so a group is a class:
use NyonCode\WireModuleSettings\Contracts\SettingsGroup; final class BrandingSettings implements SettingsGroup { public static function group(): string { return 'branding'; } public static function label(): string { return __('Branding'); } public static function schema(): array { return [TextInput::make('company_name'), Toggle::make('dark_default')]; } }
// config/wire-module-settings.php 'groups' => [App\Settings\BrandingSettings::class],
Three optional contracts sit beside that one, each opt-in so a group that wants none of them stays exactly this long:
| Contract | What it adds |
|---|---|
DescribesSettingsGroup |
icon(), description(), sort() |
ProvidesSettingsDefaults |
defaults() — the values before anybody sets one |
GuardsSettingsGroup |
permission() — an ability this group alone requires |
A package can ship a tab
groups is the application's list. A package that ships a feature can ship the
tab that configures it, from its own provider:
SettingsRegistry::instance()->register(BillingSettings::class);
The application's list wins a collision and sorts first among ties, and
'except' => ['billing'] drops a contributed tab outright — a package-shipped
screen an application cannot remove is what makes people stop installing them.
Reading and writing
use NyonCode\WireModuleSettings\Support\Settings; Settings::get('company_name', 'Acme', 'branding'); // stored → declared default → 'Acme' Settings::set('dark_default', true, 'branding'); Settings::fill(['a' => 1, 'b' => 2], 'branding'); // one transaction Settings::has('queue', 'mail'); // stored, as opposed to defaulted Settings::remove('queue', 'mail'); Settings::all('branding');
SettingsSaved is dispatched after every write, which is the hook for anything
configured from a setting — a cached config to rebuild, a transport to
re-resolve.
What it guarantees
- Values keep their type. The column is JSON, so a boolean comes back a boolean and an array survives.
- A group is one cache entry, dropped on write — including a write made through the model from a seeder or a console command.
- Reads are safe before the table exists, and a read from before
migrateis never what the application answers afterwards. - A group saves whole or not at all.
- A group is a URL, so
settings/mailopens mail settings.
Full documentation: docs/modules/settings.md.