Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Setting Module Laravel Package

idavoll/setting-module

A Laravel settings module for centralized, database-backed configuration management. Store and retrieve typed settings, organize values by group, and integrate modular packages through a simple, consistent API.

View on GitHub
Deep Wiki
Context7

Getting Started

This module is a dependency of the AsgardCMS ecosystem, not a general-purpose Laravel settings package. Treat it as part of AsgardCMS first, standalone package second.

  1. Confirm you are inside an AsgardCMS application. The module wires into AsgardCMS routing, admin menu registrations, the Modules loader, and its translation infrastructure. It has effectively zero value outside that stack.
  2. Install/verify via Composer. It is normally pulled in transitively by asgardcms/platform; install explicitly only if you are pinning versions:
    composer require idavoll/setting-module
    php artisan module:migrate Setting
    
  3. Check first-file touchpoints:
    • Modules/Setting/Providers/SettingServiceProvider.php — bindings, route/menu registration, config merge.
    • Modules/Setting/Contracts/Setting.php — the contract you will inject.
    • Modules/Setting/Repositories/SettingRepository.php — the Eloquent repo, the actual data layer.
    • Modules/Setting/Config/settings.php (if present) — any defaults/group definitions.
  4. Run the backend once. Log into backend/setting/settings (or /backend#setting) to confirm the admin form renders; this proves migrations, ACL seed, and menu registration all worked.
  5. First real use case — read a setting in a Blade view or controller:
    // app/Http/Controllers/HomeController.php
    use Modules\Setting\Contracts\Setting;
    
    public function __construct(private Setting $settings) {}
    
    public function index()
    {
        return view('home', [
            'siteName' => $this->settings->get('core::site-name'),
        ]);
    }
    
    If that returns the value you entered in the admin panel, the module is properly wired and you can build on it.

Implementation Patterns

1. Inject the contract, not the repository. The contract (Modules\Setting\Contracts\Setting) is the stable interface; the Eloquent repo is an implementation detail that may change between AsgardCMS majors. Constructor-inject for testability:

class MyService
{
    public function __construct(private \Modules\Setting\Contracts\Setting $settings) {}
}

2. The Setting facade for view helpers and one-liners. The facade is registered by the service provider. Use it in Blade and quick controller snippets:

<title>{{ Setting::get('core::site-name') }}</title>

3. Namespace your keys with the owning module. All built-in settings use the vendor::key form (core::site-name, core::template, core::locales). Follow this for your own modules — blog::per-page, shop::currency — so that:

  • Admin ACL grouping works,
  • You can bulk-load per-module settings,
  • You never collide with another module's page-size key.

4. Seed defaults from your module's ServiceProvider boot.

public function boot()
{
    if (! $this->app['setting.repository']->has('shop::currency')) {
        $this->app['setting.repository']->create([
            'name'       => 'shop::currency',
            'plainValue' => 'EUR',
            // value must be present too if the setting is translatable
        ]);
    }
}

Guard with has() so repeated boots don't overwrite admin edits.

5. Translatable settings. Set isTranslatable on the row (usually done through the admin UI or a seeder) and the module will store per-locale values as JSON and return the locale-appropriate string from get(). get('core::site-name') will transparently return the current-locale value, falling back to the default locale. Use plainValue (raw column) when you need something locale-independent, e.g. an API key.

6. Writing at runtime. set() updates the row and refreshes the cache:

Setting::set('shop::currency', 'USD');

Prefer routing all writes through the contract so cache invalidation and translation columns are handled consistently.

7. Wrapping settings in a config service. For anything nontrivial, expose a small typed wrapper rather than sprinkling Setting::get('shop::foo') everywhere — it gives you default handling and a single place to change cache strategy:

class ShopSettings
{
    public function __construct(private Setting $settings) {}
    public function currency(): string { return $this->settings->get('shop::currency', 'EUR'); }
    public function perPage(): int     { return (int) $this->settings->get('shop::per-page', 15); }
}

8. Admin integration. Register your setting group in the backend menu under the Setting module if you want a dedicated tab; the module's admin route prefix (backend/setting) can host additional screens. Reuse the existing update route/controller pattern rather than inventing new persistence — the module is the single source of truth for the settings table.

Gotchas and Tips

  • Version coupling. The Setting contract's method set and the exact repository binding name (setting.repository) have shifted between AsgardCMS 2.x, 3.x, and 4.x. Pin your AsgardCMS version in composer.json and read the module's own composer.json require block before upgrading. This package is unlikely to publish a migration guide for breaking changes.
  • plainValue vs value. get() returns the translated value; the raw column lives on plainValue. Mixing them up is the single most common bug — non-translatable settings store the same content in both, but translatable ones do not, and reading .value directly yields JSON.
  • Caching. The repository is typically wrapped in a cache decorator. Programmatic writes via Setting::set() invalidate it, but if you bypass the contract and hit the Eloquent model (Setting model) directly — or edit rows in the DB — you must flush the cache (call the repository's clearCache()/flush() or php artisan cache:clear). The DB-backed value and the cached value will otherwise disagree until the TTL expires.
  • Missing keys silently return null. Always pass a second default argument (get('core::site-name', config('app.name'))) rather than assuming the row exists — especially in fresh installs where your module's seeder hasn't run yet.
  • Namespacing collisions across modules. Two modules both writing page-size will stomp each other in the shared settings table. Always use module::key.
  • Admin ACL. The backend Setting screens are behind AsgardCMS permissions. If a user "cannot see settings," it's almost always the ACL seeder not having run — php artisan module:seed Setting — not a route issue.
  • Migrations are gated. module:migrate Setting no-ops if the module isn't registered in modules_statuses.json. If you see "table settings not found," check the module's enabled state before debugging the schema.
  • Translation rows. Translatable settings depend on AsgardCMS's translation tables being migrated. If get() returns the default locale for every locale, confirm the translations migration ran and the setting's isTranslatable flag is actually 1.
  • Extension point — custom repository. You can rebind Modules\Setting\Contracts\Setting in a service provider to decorate the module's implementation (e.g. add a Redis layer, or add typed getters). Do this only if you need to; the default caching is usually sufficient.
  • Debugging tip. When a setting "doesn't change," first hit SELECT name, plainValue, value, isTranslatable FROM settings WHERE name = '...' directly. If the row is correct, it's a cache problem. If it's wrong, you're writing through something other than the contract.
  • Abandonment risk. Zero stars and zero dependents on top of the AsgardCMS-only scope mean you should assume no upstream bug fixes. Keep a fork pinned in composer.json ("repositories" with a VCS entry) if you depend on it in production, and read the module source before assuming the facade, contract, or repository binding names above match your exact version.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo