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.
view/parts/navigation.blade.php
), containing only the navigation created from the data provided by your view composer View::composer(your_view, your_composer)
@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.