A simple Laravel-style way to create breadcrumbs in Laravel 4.
composer require davejamesmiller/laravel-breadcrumbs dev-master
This will update composer.json
and install it into the vendor/
directory.
Note: dev-master
is the latest development version. See the
Packagist website
for a list of stable versions.
'providers' => array(
// ...
'DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider',
),
And:
'aliases' => array(
// ...
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs',
),
This registers the package with Laravel and creates an alias called
Breadcrumbs
.
Create a file called app/breadcrumbs.php
to put your breadcrumbs in. This file
will be loaded automatically.
It should look something like this - see the Defining breadcrumbs section below for an explanation.
<?php
//Breadcrumbs::setView('_partials/breadcrumbs');
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', route('home'));
});
Breadcrumbs::register('blog', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Blog', route('blog'));
});
Breadcrumbs::register('category', function($breadcrumbs, $category) {
$breadcrumbs->parent('blog');
foreach ($category->ancestors as $ancestor) {
$breadcrumbs->push($ancestor->title, route('category', $ancestor->id));
}
$breadcrumbs->push($category->title, route('category', $category->id));
});
Breadcrumbs::register('page', function($breadcrumbs, $page) {
$breadcrumbs->parent('category', $page->category);
$breadcrumbs->push($page->title, route('page', $page->id));
});
By default, a Twitter Bootstrap v2-compatible unordered list will be rendered.
A Twitter Bootstrap v3-compatible
list can be rendered by adding this line to app/breadcrumbs.php
:
Breadcrumbs::setView('breadcrumbs::bootstrap3');
If you want to customise the HTML, create your own view file (e.g.
app/views/_partials/breadcrumbs.blade.php
) like this:
@if ($breadcrumbs)
<ul class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if (!$breadcrumb->last)
<li>
<a href="{{{ $breadcrumb->url }}}">{{{ $breadcrumb->title }}}</a>
<span class="divider">/</span>
</li>
@else
<li class="active">
{{{ $breadcrumb->title }}}
</li>
@endif
@endforeach
</ul>
@endif
As you can see above it will receive an array called $breadcrumbs
. Each
breadcrumb is an object with the following keys:
title
- The title you set aboveurl
- The URL you set abovefirst
-true
for the first breadcrumb,false
otherwiselast
-true
for the last breadcrumb,false
otherwise
Then add this line to app/breadcrumbs.php
, adjusting the view name as
necessary:
Breadcrumbs::setView('_partials/breadcrumbs');
Finally, call Breadcrumbs::render()
in the view template for each page,
passing in the name of the page and any parameters you defined above.
For example, with Blade:
{{ Breadcrumbs::render('home') }}
or
{{ Breadcrumbs::render('category', $category) }}
Or you can assign them to a section to be used in the layout:
@section('breadcrumbs', Breadcrumbs::render('category', $category))
(Then in the layout you would call @yield('breadcrumbs')
.)
Or if you aren't using Blade you can use regular PHP instead:
<?= Breadcrumbs::render('category', $category) ?>
Breadcrumbs will usually correspond to actions or types of page. For each breadcrumb you specify a name, the breadcrumb title and the URL to link it to. Since these are likely to change dynamically, you do this in a closure, and you pass any variables you need into the closure.
The following examples should make it clear:
The most simple breadcrumb is probably going to be your homepage, which will look something like this:
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', route('home'));
});
As you can see, you simply call $breadcrumbs->push($title, $url)
inside the
closure.
For generating the URL, you can use any of the standard Laravel URL-generation methods, including:
url('path/to/route')
(URL::to()
)secure_url('path/to/route')
route('routename')
(URL::route()
)action('controller@action')
(URL::action()
)- Or just pass a string URL (
'http://www.example.com/'
)
This example would be rendered like this:
Home
This is another static page, but this has a parent link before it:
Breadcrumbs::register('blog', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Blog', route('blog'));
});
It would be rendered like this:
Home / Blog
This is a dynamically generated page pulled from the database:
Breadcrumbs::register('page', function($breadcrumbs, $page) {
$breadcrumbs->parent('blog');
$breadcrumbs->push($page->title, route('page', $page->id));
});
The $page
variable would simply be passed in from the view:
{{ Breadcrumbs::render('page', $page) }}
It would be rendered like this:
Home / Blog / Page Title
Tip: You can pass multiple parameters if necessary.
Finally if you have nested categories or other special requirements, you can
call $breadcrumbs->push()
multiple times:
Breadcrumbs::register('category', function($breadcrumbs, $category) {
$breadcrumbs->parent('blog');
foreach ($category->ancestors as $ancestor) {
$breadcrumbs->push($ancestor->title, route('category', $ancestor->id));
}
$breadcrumbs->push($category->title, route('category', $category->id));
});
Alternatively you could make a recursive function such as this:
Breadcrumbs::register('category', function($breadcrumbs, $category) {
if ($category->parent)
$breadcrumbs->parent('category', $category->parent);
else
$breadcrumbs->parent('blog');
$breadcrumbs->push($category->title, route('category', $category->slug));
});
Both would be rendered like this:
Home / Blog / Grandparent Category / Parent Category / Category Title
If you don't want to use app/breadcrumbs.php
, you can define them in
routes.php
, start/global.php
, or any other file as long as it's loaded by
Laravel.
If you need different views in different templates, you can call
Breadcrumbs::generate()
to get the $breadcrumbs
array and then load the view
manually:
@include('_partials/breadcrumbs2', array('breadcrumbs' => Breadcrumbs::generate('category', $category)))
or
{{ View::make('_partials/breadcrumbs2', array('breadcrumbs' => Breadcrumbs::generate('category', $category))) }}
In version 1.x you can pass an array into each of these methods and it is split up into several parameters:
Breadcrumbs::register('page', function($breadcrumbs, $param1, $param2)
{
$breadcrumbs->parent('somethingElse', array('paramA', 'paramB'))
$breadcrumbs->push($param1, $param2);
});
// Then this:
Breadcrumbs::render('page', array('param1', 'param2'));
Breadcrumbs::generate('page', array('param1', 'param2'));
// Is equivalent to this:
Breadcrumbs::render('page', 'param1', 'param2');
Breadcrumbs::generate('page', 'param1', 'param2');
// If you want to pass an array as the first parameter you have to do this:
Breadcrumbs::render('page', array(array('param1A', 'param1B'), 'param2'));
Breadcrumbs::generate('page', array(array('param1A', 'param1B'), 'param2'));
This means you can't pass an array as the first parameter unless you wrap all parameters in another array (issue #8).
In version 2.x (currently in development) this is split into two methods:
Breadcrumbs::register('page', function($breadcrumbs, $param1, $param2)
{
$breadcrumbs->parent('somethingElse', array('paramA', 'paramB'))
$breadcrumbs->push($param1, $param2);
});
// Now this:
Breadcrumbs::renderArray('page', array('param1', 'param2'));
Breadcrumbs::generateArray('page', array('param1', 'param2'));
// Is equivalent to this:
Breadcrumbs::render('page', 'param1', 'param2');
Breadcrumbs::generate('page', 'param1', 'param2');
// And this only passes a single parameter (an array) to the callback:
Breadcrumbs::render('page', array('param1A', 'param1B'));
Breadcrumbs::generate('page', array('param1A', 'param1B'));
Similarly generateArray()
and parentArray()
methods are available.
- Add
Breadcrumbs::active()
method for highlighting menu items
- Add Twitter Bootstrap v3 template (#7)
- Support for passing arrays into
render()
,generate()
andparent()
(#8) (note: not backwards-compatible)- Split
Breadcrumbs::render()
into two methods:render($name, $arg1, $arg2)
andrenderArray($name, $args)
- Split
Breadcrumbs::generate()
into two methods:generate($name, $arg1, $arg2)
andgenerateArray($name, $args)
- Split
$breadcrumbs->parent()
into two methods:parent($name, $arg1, $arg2)
andparentArray($name, $args)
- Split
- Fix for PHP 5.3 compatibility
- Initial release
This is largely based on the Gretel plugin for Ruby on Rails, which I used for a while before Laravel lured me back to PHP.
MIT License. See LICENSE.txt.
So far I've only found one other breadcrumb package for Laravel: