A simple Laravel-style way to create breadcrumbs in Laravel 4.
composer require davejamesmiller/laravel-breadcrumbs ~2.2.0
This will update composer.json
and install it into the vendor/
directory.
(See the Packagist website for a list of available version numbers and development releases.)
'providers' => array(
// ...
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
),
And:
'aliases' => array(
// ...
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
),
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::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 v3-compatible unordered list will be rendered.
If you would like to change the template, first you need to generate a config file by running this command:
php artisan config:publish davejamesmiller/laravel-breadcrumbs
Then open app/config/packages/davejamesmiller/laravel-breadcrumbs/config.php
and edit this line:
'view' => 'laravel-breadcrumbs::bootstrap3',
The possible values are:
laravel-breadcrumbs::bootstrap3
(Twitter Bootstrap 3)laravel-breadcrumbs::bootstrap2
(Twitter Bootstrap 2)- A path to a custom template, e.g.
_partials.breadcrumbs
If you want to customise the HTML, create your own view file (e.g.
app/views/_partials/breadcrumbs.blade.php
) and alter the config to point to
that file (e.g. _partials.breadcrumbs
).
The view should be similar to this:
@if ($breadcrumbs)
<ul class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if (!$breadcrumb->last)
<li><a href="{{{ $breadcrumb->url }}}">{{{ $breadcrumb->title }}}</a></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
Finally, call Breadcrumbs::render()
in the view template for each page. You
can either pass the name of the breadcrumb to use (and parameters if needed):
{{ Breadcrumbs::render('home') }}
{{ Breadcrumbs::render('category', $category) }}
Or you can avoid the need to do this for every page by naming your breadcrumbs
the same as your routes. For example, if you have this in routes.php
:
Route::model('category', 'Category');
Route::get('/', ['uses' => 'HomeController@index', 'as' => 'home']);
Route::get('/category/{category}', ['uses' => 'CategoryController@show', 'as' => 'category']);
And in the layout you have this:
{{ Breadcrumbs::render() }}
Then on the homepage it will be the same as calling Breadcrumbs::render('home')
and on the category page it will be the same as calling
Breadcrumbs::render('category', $category)
.
The key here is the 'as'
parameter must match the breadcrumb name. The
parameters passed to the breadcrumbs callback will be the same as the ones
Laravel passes to the controller (see the Route
parameters section of the
Laravel documentation).
In the main page:
@extends('layout.name')
@section('breadcrumbs', Breadcrumbs::render('category', $category))
In the layout:
@yield('breadcrumbs')
<?= Breadcrumbs::render('category', $category) ?>
Or the long syntax if you prefer:
<?php echo 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
The second parameter to push()
is optional, so if you want a breadcrumb with
no URL you can do so:
$breadcrumbs->push('Sample');
The $breadcrumb->url
value will be null
.
The default Twitter Bootstrap templates provided render this with a CSS class of "active", the same as the last breadcrumb, because otherwise they default to black text not grey which doesn't look right.
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.
You can change the view at runtime by calling:
Breadcrumbs::setView('view.name');
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))) }}
If you call Breadcrumbs::render()
or Breadcrumbs::generate()
with no
parameters, it will use the current route name and parameters, as returned by
Laravel's Route::current()
method, by default.
You can override this by calling
Breadcrumbs::setCurrentRoute($name, $param1, $param2...)
or
Breadcrumbs::setCurrentRouteArray($name, $params)
.
If the breadcrumb requires multiple parameters, you would normally pass them like this:
Breadcrumbs::render('name', $param1, $param2, $param3);
Breadcrumbs::generate('name', $param1, $param2, $param3);
$breadcrumbs->parent('name', $param1, $param2, $param3);
If you want to pass an array of parameters instead you can use these methods:
Breadcrumbs::renderArray('name', $params);
Breadcrumbs::generateArray('name', $params);
$breadcrumbs->parentArray('name', $params);
By default an exception will be thrown if the breadcrumb doesn't exist, so you know to add it. If you want suppress this you can call the following methods instead:
Breadcrumbs::renderIfExists()
(returns an empty string)Breadcrumbs::renderArrayIfExists()
(returns an empty string)Breadcrumbs::generateIfExists()
(returns an empty array)Breadcrumbs::generateArrayIfExists()
(returns an empty array)
Alternatively you can call Breadcrumbs::exists('name')
, which returns a
boolean.
Breadcrumbs::register($name, $callback)
Breadcrumbs::exists()
(returns boolean)Breadcrumbs::exists($name)
(returns boolean)Breadcrumbs::generate()
(returns array)Breadcrumbs::generate($name)
(returns array)Breadcrumbs::generate($name, $param1, ...)
(returns array)Breadcrumbs::generateArray($name, $params)
(returns array)Breadcrumbs::generateIfExists()
(returns array)Breadcrumbs::generateIfExists($name)
(returns array)Breadcrumbs::generateIfExists($name, $param1, ...)
(returns array)Breadcrumbs::generateArrayIfExists($name, $params)
(returns array)Breadcrumbs::render()
(returns string)Breadcrumbs::render($name)
(returns string)Breadcrumbs::render($name, $param1, ...)
(returns string)Breadcrumbs::renderArray($name, $params)
(returns string)Breadcrumbs::renderIfExists()
(returns string)Breadcrumbs::renderIfExists($name)
(returns string)Breadcrumbs::renderIfExists($name, $param1, ...)
(returns string)Breadcrumbs::renderArrayIfExists($name, $params)
(returns string)Breadcrumbs::setCurrentRoute($name)
Breadcrumbs::setCurrentRoute($name, $param1, ...)
Breadcrumbs::setCurrentRouteArray($name, $params)
Breadcrumbs::clearCurrentRoute()
Breadcrumbs::setView($view)
Breadcrumbs::getView()
(returns string)
$breadcrumbs->push($title)
$breadcrumbs->push($title, $url)
$breadcrumbs->parent($name)
$breadcrumbs->parent($name, $param1, ...)
$breadcrumbs->parentArray($name, $params)
$breadcrumbs
(array), contains:$breadcrumb->title
(string)$breadcrumb->url
(string or null)$breadcrumb->first
(boolean)$breadcrumb->last
(boolean)
See the CHANGELOG for a list of changes and upgrade instructions.
Please submit all issues, help requests and feature requests using GitHub issues and I will try to help you.
Please try to isolate the problem as much as possible, and give as much detail as you can to help track down the problem (version number, PHP version, steps to reproduce, etc.).
Please also let me know if you have any suggestions for improving the documentation - especially if anything is unclear to you and could be explained better.
See the CONTRIBUTING file for details of how to contribute to Laravel Breadcrumbs.
This package is largely based on the Gretel plugin for Ruby on Rails, which I used for a while before discovering Laravel.
- Andrej Badin (Andreyco) - #24
- Stef Horner (tedslittlerobot) - #11
MIT License. See LICENSE.txt.
So far I've only found one other breadcrumb package for Laravel: