Skip to content

tedslittlerobot/laravel-breadcrumbs

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laravel Breadcrumbs

A simple Laravel-style way to create breadcrumbs in Laravel 4.

Installation

1. Install with Composer

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.

2. Add to app/config/app.php

    '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.

Usage

1. Define breadcrumbs in app/breadcrumbs.php

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));
});

2. Choose/create a template to renders the breadcrumbs

Twitter Bootstrap 2

By default, a Twitter Bootstrap v2-compatible unordered list will be rendered.

Twitter Bootstrap 3

A Twitter Bootstrap v3-compatible list can be rendered by adding this line to app/breadcrumbs.php:

Breadcrumbs::setView('breadcrumbs::bootstrap3');

Custom template

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 above
  • url - The URL you set above
  • first - true for the first breadcrumb, false otherwise
  • last - 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');

3. Output the breadcrumbs in your view

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) ?>

Defining breadcrumbs

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:

Static pages

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

Parent links

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

Dynamic titles and links

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.

Nested categories

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

Advanced usage

Defining breadcrumbs in a different file

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.

Switching views dynamically

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))) }}

Passing arrays into render(), generate() and parent()

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.

Changelog

Work in progress

  • Add Breadcrumbs::active() method for highlighting menu items

Development (master branch)

  • Add Twitter Bootstrap v3 template (#7)
  • Support for passing arrays into render(), generate() and parent() (#8) (note: not backwards-compatible)
    • Split Breadcrumbs::render() into two methods: render($name, $arg1, $arg2) and renderArray($name, $args)
    • Split Breadcrumbs::generate() into two methods: generate($name, $arg1, $arg2) and generateArray($name, $args)
    • Split $breadcrumbs->parent() into two methods: parent($name, $arg1, $arg2) and parentArray($name, $args)

1.0.1

  • Fix for PHP 5.3 compatibility

1.0.0

  • Initial release

Thanks to

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.

License

MIT License. See LICENSE.txt.

Alternatives

So far I've only found one other breadcrumb package for Laravel:

About

A simple Laravel-style way to create breadcrumbs in Laravel 4.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%