简体   繁体   中英

Laravel base controller methods

I'm learning how to use Laravel by writing a little test application. So far its going really well, and I'm excited by all the features of the framework. However, I keep hitting a wall when I try to apply a specific design pattern.

I've currently got a set up where I can set the html titles, keywords and description with default values in the base controller, and then optionally change them in the child controller that extends it:

Base controller

protected function setupLayout()
{
    $this->layout->title = 'Wow website';
    $this->layout->desc = 'Much technical';
    $this->layout->keys = 'so html, very javascript';

    $foot = View::make('mod.footerDefault');
    $this->layout->footer = $foot;
}

Child controller

public function getContact()
{
    $this->title = 'Contact page of contactness';
    // Could also override the desc and keys if desired,
    // but I'll just let them default here

    $data = 'wow';
    $view = View::make('main.home', $data)
        ->nest('vid', 'mod.video')
        ->nest('list', 'mod.list');

    $this->layout->content = $view;
}

This is all gravy, but what if I have an object that I've interacted with, such as a menu class, that needs to be recompiled into a string of HTML? Is there a method in laravel that is similar to the setupLayout() method which is called automatically, but each time the View::make method is invoked?

(More examples...just to illustrate)

Base controller

protected function setupLayout()
{
     $this->menu = newMenu();
     $this->menu->items[0] = ['contact-us', 'Contact us'];
     $this->menu->items[1] = ['about-us', 'About us'];
     $this->menuString = $this->menu->getString();
}

Child controller

public function getContact()
{
    $this->menu->addItem(['log-out', 'Log out']);
    // Now $this->menuString must be recalculated.
    // Ideally want to avoid having to call a method from the base controller
    // every time the child controller calls View::make

    $view = View::make('main.home')
    $this->layout->content = $view;
}

I know there is such a thing as view composers, but I dont think these are called on View::make().

I create my navigation/menu structure with a view composer.

  • Create a view composer providing the data for the view
  • Create a view for your navigation part ( view/parts/navigation.blade.php ), containing only the navigation created from the data provided by your view composer
  • Bind that composer to your navigation view with View::composer(your_view, your_composer)
  • include the navigation view into any other view or master layout with @include('parts.navigation')

This composer function is not called on every View::make() but on every make of a View that contains the included navigation part. And this is what you need.

Here is an how to how view composers work: http://culttt.com/2014/02/10/using-view-composers-laravel-4/

Heres how I maanged to get it working in the end:

The routes file (Will move this to a more appropriate place later):

    // NB: KoBsMenu is the name of the menu class

    App::before(function($request) {
        $menu = [
            'brand' => [
                'left' => 'asdf',
                'right' => ['floppy-save']
            ],
            'leftItems' => [
                'home' => [1, 'home', 'Home'],
                'factories' => [2, [
                    'aboutF' => [1, 'about-factories', [''], 'About factories'],
                    'factoryL' => [2, 'factory-life', 'Factory life'],
                    'uk' => [3, [
                        'leeds' => [1, 'leeds', 'Leeds'],
                        'reading' => [2, 'reading', 'Reading']
                    ], 'UK'],
                    'usa' => [4, [
                        'austin' => [1, 'austin', 'Austin'],
                        'kansas' => [2, 'kansas', 'Kansas']
                    ], 'USA']
                ], 'Factories', ['tower']],
            ...
        ];

        App::singleton('mainMenu', 'KoBsMenu');
        $KoBsMenu = App::make('mainMenu');
        $KoBsMenu->buildMenu($menu);
    });
    View::composer('*', function($view)
    {
        $KoBsMenu = App::make('mainMenu');
        $mainMenu = $KoBsMenu->getMenuHtml();
        $view->with('mainMenu', $mainMenu);
    });

Then in the base controller

$this->KoBsMenu = App::make('mainMenu');

Then I can add/remove menu items programatically in the main controller if desired.

$this->KoBsMenu->menu['leftItems']['testasfd'] = [1, 'bloh', [''], 'Bloh']; // Will be a public method ultimately

Then finally in the view:

{{ $mainMenu or '' }}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM