7

I'm working on building a small CRUD app in Laravel 5. I have a few app wide settings such as "SiteTitle" and "BaseURL" I'd like to give my admins the ability to change from the UI. My whole app uses a base.blade.php template that gets extended to the different views+controllers, this is where these settings would most likely be used.

Something like:

<h1><a href="#">{{ $setting->SiteName }}</a></h1>

I have the settings stored in a database table that are tied to a Setting.php model.

I'd rather not everyone of my controller methods query the database for these settings to just pass them up to the template base.blade.php.

What's the best way of creating some type of global setting variable I can reuse throughout the app?

Thanks in advance!

Moose
  • 1,231
  • 4
  • 14
  • 22
  • possible duplicate of [Laravel: Where to store global arrays data and constants?](http://stackoverflow.com/questions/26854030/laravel-where-to-store-global-arrays-data-and-constants) – FuzzyTree Sep 23 '15 at 16:49
  • 1
    possible duplicate of [global variable for all controller and views](http://stackoverflow.com/questions/25189427/global-variable-for-all-controller-and-views) – Thomas Sep 23 '15 at 17:02

2 Answers2

16

You could create a service provider, say SettingsServiceProvider, that loads all the settings from the database and then caches them. Then on subsequent page loads, it could return cached setting values rather than querying the database, which you should be rightfully concerned about.

Something as simple as:

class SettingsServiceProvider extends ServiceProvider
{
    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('settings', function ($app) {
            return $app['cache']->remember('site.settings', 60, function () {
                return Setting::pluck('value', 'key')->toArray();
            });
        });
    }
}

Assuming your settings model is called Setting as per Laravel’s naming conventions. You can then access settings like so:

<h1>{{ array_get(app('settings'), 'site.name') }}</h1>

If you wanted a prettier way of accessing settings, you could create a helper function:

function setting($key)
{
    return array_get(app('settings'), $key);
}

Which would make usage like this:

<h1>{{ setting('site.name') }}</h1>

Almost emulating the config() helper function’s usage.

Stefan Teunissen
  • 402
  • 6
  • 19
Martin Bean
  • 38,379
  • 25
  • 128
  • 201
  • 3
    Very elegant solution, thank you! Keep in mind that if you start with an empty value, the cache set to 60 minutes will keep it empty even if your database has a newer value. To refresh the cache use `Cache::forget('site.settings'); in artisan tinker.` – raphael May 03 '16 at 12:57
  • @raphael You could add an observer to the `Setting` model that flushes the cache on save. – Martin Bean May 03 '16 at 16:21
  • In laravel 5.3 `lists()` method is depreciated . So, please use `pluck()` instead o f list. – Drudge Rajen Mar 23 '17 at 05:15
  • 1
    don't forget to load your service provider in config/app.php **App\Providers\SettingServiceProvider::class,** – stackMonk Sep 21 '17 at 07:41
1

If your app uses multiple controllers then you could define a parent controller that gets extended by all your other controllers. Within the parent controller's constructor you can retrieve the settings data and store it in a class property which will be available to all of the child controller classes. Your child controllers can simply pass this data to the view.

James
  • 11
  • 4