I\'m new to Laravel 4 and I\'m totally confused about it\'s models. I\'m trying to create a database-driven navigation menu for my project and all I know is I have to create
So after doing much more searching and reading from different sources this is what I came up with and it's working fine:
/app/models/Navigation.php
<?php
class Navigation extends Eloquent {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'navigation';
public function parent() {
return $this->hasOne('navigation', 'id', 'parent_id');
}
public function children() {
return $this->hasMany('navigation', 'parent_id', 'id');
}
public static function tree() {
return static::with(implode('.', array_fill(0, 4, 'children')))->where('parent_id', '=', NULL)->get();
}
}
/app/controllers/HomeController.php
<?php
class HomeController extends BaseController {
protected $layout = "layouts.main";
public function showWelcome()
{
$items = Navigation::tree();
$this->layout->content = View::make('layouts.home.index')->withItems($items);
}
}
/app/views/layouts/home/index.blade.php
<ul>
@foreach($items as $item)
<li>{{ $item->title }}
@foreach($item['children'] as $child)
<li>{{ $child->title }}</li>
@endforeach
</li>
@endforeach
</ul>
Laravel will not create menus for you, but it will help you write a clean code to do it.
Use your model to query your table and create the menu items:
<?php
class HomeController extends Controller {
public function index()
{
$items = Navigation::all();
return View::make('index')->withItems($items);
}
}
And in your view you will be able to
<ul>
@foreach($items as $item)
<li>{{ $item->title }}</li>
@endforeach
</ul>
Another possibility PHP, Composer and even Laravel gives you is to install a specific package to help you do things, this one is to ease the menu generation: https://github.com/anhsaker/laravel-menu.
EDIT
Looks like you need unlimited multi-level menus and you don't want to use packages, right?
Don't forget that Laravel and Laravel Blade are both PHP, so you can create classes in PHP to help you build things in Laravel, like:
class Menu {
public function build($collection)
{
// build your <li> $items
return $items;
}
}
Then your controller would look like:
<?php
class HomeController extends Controller {
public function index()
{
$items = with(new Menu)->build(Navigation::all());
return View::make('index')->withItems($items);
}
}
And in blade you'll just have to
<ul>
{{ $items }}
</ul>
You have to understand that those things you can't get out of the box, because they are out of the scope of a framework, you can perfectly get by using PHP,
Here's some PHP logic to build multi-level menus, but, of course, you'll have to adapt to your needs:http://forrst.com/posts/Flat_Array_Multi_HTML_UL-IKp.
For those like me visiting this article nearly 4 years later, I would say the new best solution is all in this video:
https://laracasts.com/series/laravel-5-fundamentals/episodes/25
View Composers
https://laravel.com/docs/5.4/views#view-composers
View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.