How to reuse code through controllers in Laravel

I am new to Laravel (relatively new to MVC concept in general) and have watched hours of tutorials and read many others, but there is a simple general problem that eludes me: what is the best way to reuse the same basic elements in a system (say a CMS ) through controllers?

Scenario:

I have a content management system and want to use a different controller for each type of function: eg. a message controller for managing messages, a custom controller for managing users, a menu controller for menu items, etc. Most guides recommend this type of workflow.

However, in the actual CMS interface, I have a lot of common elements that are dynamic (coming from the DB) but still need to be displayed on all controllers. For example, menu (originates from DB), current user data (username and corresponding buttons according to permissions), etc. Displaying it to the user (interface) is easy enough with Blade, but I can't figure out the best way to do it in the background.

For example, if each controller separately receives a menu from the database, this (lack of) code reuse is a nightmare. On the other hand, there is no central place where I can insert this code and feed it to the view on all controllers. I'm sure the Laravel devs have thought of this extremely common scenario. What is the best way to implement it?

+3


source to share


2 answers


This is exactly what View Composers is for!

View Composers allow you to register a callback that runs before a particular view is displayed. Typically you register them with a service provider . You can use an existing one AppServiceProvider

or create one for it ComposerServiceProvider

.

This would be a very simple example for a view named menu



public function boot(){
    View::composer('menu', function($view){
        $menu = DB::table('menu')->get();
        $view->with('menu', $menu);
    });
}

      

You can also specify a class containing composer logic. Read more about this in the docs

+4


source


You can have a View::share

variable in your base controller that extends other controllers like:

Base controller

protected $variable;

public function __construct() 
{
    $this->variable= Model::all();
    View::share('variable', $this->variable);
}

      

Then just use $this->variable

in other controllers that extend the base controller to get your variable.



Another thing you can try is register a singleton and use that approach instead

In some file that it loaded automatically or this namespace is automatically loaded

   App::before(function($request) 
       {
        App::singleton('variable', function(){
            $variable= Model::all();
            return $variable;
        });

      

Then use $variable= app('variable');

in your controllers.

+1


source







All Articles