├── .coveralls.yml ├── test.sh ├── config └── breadcrumbs.php ├── tests ├── fixtures │ ├── CustomServiceProvider.html │ ├── DependantServiceProvider.html │ ├── integration.html │ ├── bootstrap3.html │ └── bootstrap2.html ├── unit │ ├── FacadeTest.php │ ├── ViewTest.php │ ├── CurrentRouteTest.php │ ├── GeneratorTest.php │ └── ManagerTest.php ├── integration │ ├── CustomServiceProviderTest.php │ ├── DependantServiceProviderTest.php │ ├── DependantServiceProviderErrorTest.php │ └── IntegrationTest.php └── TestCase.php ├── src ├── Exception.php ├── Facade.php ├── View.php ├── CurrentRoute.php ├── Generator.php ├── ServiceProvider.php └── Manager.php ├── test-coverage.sh ├── phpunit.php ├── docs ├── .editorconfig ├── _static │ └── custom.css ├── index.rst ├── license.rst ├── thanks.rst ├── output.rst ├── templates.rst ├── start.rst ├── defining.rst ├── advanced.rst ├── api.rst ├── contributing.rst ├── routing.rst ├── conf.py └── changelog.rst ├── .editorconfig ├── .gitignore ├── views ├── bootstrap3.blade.php └── bootstrap2.blade.php ├── .travis.yml ├── RELEASE-CHECKLIST.md ├── composer.json ├── phpunit.xml ├── README.md └── CONTRIBUTING.rst /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | cd $(dirname $0) 4 | 5 | vendor/bin/phpunit "$@" 6 | -------------------------------------------------------------------------------- /config/breadcrumbs.php: -------------------------------------------------------------------------------- 1 | 'breadcrumbs::bootstrap3', 6 | 7 | ]; 8 | -------------------------------------------------------------------------------- /tests/fixtures/CustomServiceProvider.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/Exception.php: -------------------------------------------------------------------------------- 1 | 2 |
  • Home
  • 3 | 4 | -------------------------------------------------------------------------------- /test-coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | cd $(dirname $0) 4 | 5 | php -d xdebug.coverage_enable=On vendor/bin/phpunit --coverage-html test-coverage "$@" 6 | -------------------------------------------------------------------------------- /phpunit.php: -------------------------------------------------------------------------------- 1 | 2 |
  • Home
  • 3 |
  • Sample Category
  • 4 |
  • Sample Post
  • 5 | 6 | -------------------------------------------------------------------------------- /tests/fixtures/bootstrap3.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /docs/.editorconfig: -------------------------------------------------------------------------------- 1 | # 4 space indents in ReST because that's what we want for most code examples 2 | # and if we use tabs it defaults to 8 (and isn't easy to change) 3 | # http://stackoverflow.com/questions/1686837 4 | [*] 5 | indent_size = 4 6 | indent_style = space 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = tab 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.yml] 14 | indent_size = 2 15 | indent_style = space 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # PHP packages 2 | /vendor 3 | composer.phar 4 | composer.lock 5 | 6 | # Compiled documentation (run `grunt docs` for HTML; `grunt pdfdocs` for PDF) 7 | /docs-html/ 8 | /docs-pdf/ 9 | 10 | # Test coverage output 11 | /test-coverage/ 12 | 13 | # Operating system files 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /tests/unit/FacadeTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf('DaveJamesMiller\Breadcrumbs\Manager', Breadcrumbs::getFacadeRoot()); 8 | $this->assertSame($this->app['breadcrumbs'], Breadcrumbs::getFacadeRoot()); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /views/bootstrap3.blade.php: -------------------------------------------------------------------------------- 1 | @if ($breadcrumbs) 2 | 11 | @endif 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 5.5 6 | - 5.4 7 | - hhvm 8 | 9 | install: 10 | - composer self-update # https://github.com/phpspec/prophecy/issues/149 11 | - travis_retry composer install --no-interaction --prefer-source 12 | 13 | script: 14 | - phpunit --coverage-clover build/logs/clover.xml 15 | 16 | after_script: 17 | - php vendor/bin/coveralls -v 18 | -------------------------------------------------------------------------------- /src/Facade.php: -------------------------------------------------------------------------------- 1 | 2 |
  • 3 | Home 4 | / 5 |
  • 6 |
  • 7 | Not a link 8 | / 9 |
  • 10 |
  • 11 | Blog & < > 12 | / 13 |
  • 14 |
  • 15 | Sample Post 16 |
  • 17 | 18 | -------------------------------------------------------------------------------- /RELEASE-CHECKLIST.md: -------------------------------------------------------------------------------- 1 | # Release Checklist 2 | 3 | - [ ] Ensure the documentation is up to date, particularly the changelog 4 | - [ ] Merge the `develop` branch into the `master` branch (`git checkout master; git merge develop`) 5 | - [ ] Push the code changes to GitHub (`git push`) 6 | - [ ] Double-check the [Travis CI results](https://travis-ci.org/davejamesmiller/laravel-breadcrumbs) 7 | - [ ] Tag the release (`git tag 1.2.3`) 8 | - [ ] Push the tag (`git push --tag`) 9 | -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* Make sections stand out more */ 2 | h2 { 3 | border-top: 1px solid #e1e4e5; 4 | padding-top: 24px; 5 | } 6 | 7 | h1 + .section > h2:first-child { 8 | border-top: none; 9 | padding-top: 0; 10 | } 11 | 12 | /* Changelog styles */ 13 | .changelog-date { 14 | font-size: 70%; 15 | } 16 | 17 | .changelog-future { 18 | color: #b65a5a; 19 | font-size: 70%; 20 | font-style: italic; 21 | font-weight: bold; 22 | } 23 | 24 | .strikethrough { 25 | text-decoration: line-through; 26 | } 27 | -------------------------------------------------------------------------------- /src/View.php: -------------------------------------------------------------------------------- 1 | factory = $factory; 12 | } 13 | 14 | public function render($view, $breadcrumbs) 15 | { 16 | if (!$view) 17 | throw new Exception('Breadcrumbs view not specified (check the view in config/breadcrumbs.php, and ensure DaveJamesMiller\Breadcrumbs\ServiceProvider is loaded before any dependants in config/app.php)'); 18 | 19 | return $this->factory->make($view, compact('breadcrumbs'))->render(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /views/bootstrap2.blade.php: -------------------------------------------------------------------------------- 1 | @if ($breadcrumbs) 2 | 22 | @endif 23 | -------------------------------------------------------------------------------- /tests/integration/CustomServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/CustomServiceProvider.html', $html); 16 | } 17 | 18 | } 19 | 20 | class CustomServiceProvider extends DaveJamesMiller\Breadcrumbs\ServiceProvider { 21 | 22 | public function registerBreadcrumbs() 23 | { 24 | Breadcrumbs::register('home', function($breadcrumbs) { 25 | $breadcrumbs->push('Home', '/'); 26 | }); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 'DaveJamesMiller\Breadcrumbs\Facade' 16 | ]; 17 | } 18 | 19 | public function setUp() 20 | { 21 | parent::setUp(); 22 | 23 | $this->loadServiceProvider(); 24 | } 25 | 26 | protected function loadServiceProvider() 27 | { 28 | // Need to trigger register() to test the views 29 | $this->app->make('breadcrumbs'); 30 | } 31 | 32 | public function tearDown() 33 | { 34 | $this->addToAssertionCount(Mockery::getContainer()->mockery_getExpectationCount()); 35 | 36 | Mockery::close(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "davejamesmiller/laravel-breadcrumbs", 3 | "description": "A simple Laravel-style way to create breadcrumbs in Laravel 4+.", 4 | "keywords": [ 5 | "laravel" 6 | ], 7 | "homepage": "http://laravel-breadcrumbs.davejamesmiller.com", 8 | "authors": [ 9 | { 10 | "name": "Dave James Miller", 11 | "email": "dave@davejamesmiller.com", 12 | "homepage": "http://davejamesmiller.com/" 13 | } 14 | ], 15 | "license": "MIT License", 16 | "require": { 17 | "php": ">=5.4.0", 18 | "illuminate/support": "5.*", 19 | "illuminate/view": "5.*" 20 | }, 21 | "require-dev": { 22 | "mockery/mockery": "0.9.*", 23 | "orchestra/testbench": "3.0.*", 24 | "phpunit/phpunit": "4.*", 25 | "satooshi/php-coveralls": "0.6.*" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "DaveJamesMiller\\Breadcrumbs\\": "src/" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/integration/DependantServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/DependantServiceProvider.html', $html); 22 | } 23 | 24 | } 25 | 26 | class DependantServiceProvider extends Illuminate\Support\ServiceProvider { 27 | 28 | public function register() 29 | { 30 | } 31 | 32 | public function boot() 33 | { 34 | Breadcrumbs::register('home', function($breadcrumbs) { 35 | $breadcrumbs->push('Home', '/'); 36 | }); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/integration/DependantServiceProviderErrorTest.php: -------------------------------------------------------------------------------- 1 | push('Home', '/'); 40 | }); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | 22 | tests/unit/ 23 | tests/integration/ 24 | 25 | 26 | 27 | 28 | 29 | 30 | src/ 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/CurrentRoute.php: -------------------------------------------------------------------------------- 1 | router = $router; 13 | } 14 | 15 | public function get() 16 | { 17 | if ($this->route) 18 | return $this->route; 19 | 20 | $route = $this->router->current(); 21 | 22 | if (is_null($route)) 23 | return ['', []]; 24 | 25 | $name = $route->getName(); 26 | 27 | if (is_null($name)) { 28 | $uri = head($route->methods()) . ' /' . $route->uri(); 29 | throw new Exception("The current route ($uri) is not named - please check routes.php for an \"as\" parameter"); 30 | } 31 | 32 | $params = array_values($route->parameters()); 33 | 34 | return [$name, $params]; 35 | } 36 | 37 | public function set($name, $params) 38 | { 39 | $this->route = [$name, $params]; 40 | } 41 | 42 | public function clear() 43 | { 44 | $this->route = null; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Laravel Breadcrumbs 3 3 | ################################################################################ 4 | 5 | .. Link to the online documentation 6 | 7 | .. only:: local and html 8 | 9 | .. admonition:: Local Documentation 10 | :class: warning 11 | 12 | `Read the documentation online >> `_ 13 | 14 | 15 | .. Introduction 16 | 17 | A simple Laravel-style way to create breadcrumbs in `Laravel 5 `_. 18 | 19 | 20 | ================================================================================ 21 | Table of Contents 22 | ================================================================================ 23 | 24 | .. toctree:: 25 | start 26 | defining 27 | templates 28 | output 29 | routing 30 | advanced 31 | api 32 | contributing 33 | changelog 34 | thanks 35 | license 36 | » GitHub 37 | » Packagist 38 | -------------------------------------------------------------------------------- /tests/unit/ViewTest.php: -------------------------------------------------------------------------------- 1 | view = app('DaveJamesMiller\Breadcrumbs\View'); 10 | 11 | $this->breadcrumbs = [ 12 | (object) [ 13 | 'title' => 'Home', 14 | 'url' => '/', 15 | 'first' => true, 16 | 'last' => false, 17 | ], 18 | (object) [ 19 | 'title' => 'Not a link', 20 | 'url' => null, // Test non-links 21 | 'first' => false, 22 | 'last' => false, 23 | ], 24 | (object) [ 25 | 'title' => 'Blog & < >', // Test HTML escaping 26 | 'url' => '/blog', 27 | 'first' => false, 28 | 'last' => false, 29 | ], 30 | (object) [ 31 | 'title' => 'Sample Post', 32 | 'url' => '/blog/123', 33 | 'first' => false, 34 | 'last' => true, 35 | ], 36 | ]; 37 | } 38 | 39 | public function testBootstrap2() 40 | { 41 | $html = $this->view->render('breadcrumbs::bootstrap2', $this->breadcrumbs); 42 | $this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/bootstrap2.html', $html); 43 | } 44 | 45 | public function testBootstrap3() 46 | { 47 | $html = $this->view->render('breadcrumbs::bootstrap3', $this->breadcrumbs); 48 | $this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/bootstrap3.html', $html); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /docs/license.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | License 3 | ################################################################################ 4 | 5 | `The MIT License (MIT) `_ 6 | 7 | **Copyright © 2013-2015 Dave James Miller** 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /src/Generator.php: -------------------------------------------------------------------------------- 1 | breadcrumbs = []; 11 | $this->callbacks = $callbacks; 12 | 13 | $this->call($name, $params); 14 | return $this->toArray(); 15 | } 16 | 17 | protected function call($name, $params) 18 | { 19 | if (!isset($this->callbacks[$name])) 20 | throw new Exception("Breadcrumb not found with name \"{$name}\""); 21 | 22 | array_unshift($params, $this); 23 | 24 | call_user_func_array($this->callbacks[$name], $params); 25 | } 26 | 27 | public function parent($name) 28 | { 29 | $params = array_slice(func_get_args(), 1); 30 | 31 | $this->call($name, $params); 32 | } 33 | 34 | public function parentArray($name, $params = []) 35 | { 36 | $this->call($name, $params); 37 | } 38 | 39 | public function push($title, $url = null, array $data = []) 40 | { 41 | $this->breadcrumbs[] = (object) array_merge($data, [ 42 | 'title' => $title, 43 | 'url' => $url, 44 | // These will be altered later where necessary: 45 | 'first' => false, 46 | 'last' => false, 47 | ]); 48 | } 49 | 50 | public function toArray() 51 | { 52 | $breadcrumbs = $this->breadcrumbs; 53 | 54 | // Add first & last indicators 55 | if ($breadcrumbs) { 56 | $breadcrumbs[0]->first = true; 57 | $breadcrumbs[count($breadcrumbs) - 1]->last = true; 58 | } 59 | 60 | return $breadcrumbs; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /docs/thanks.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Thanks to 3 | ################################################################################ 4 | 5 | This package is largely based on the `Gretel `_ plugin for Ruby on Rails, which I used for a while before discovering Laravel. 6 | 7 | And of course it would be nothing without `Laravel `_ itself! 8 | 9 | ================================================================================ 10 | Contributors 11 | ================================================================================ 12 | 13 | - Christian Thomas (`christian-thomas `_) - 14 | `#62 `_ 15 | - Miloš Levačić (`levacic `_) - 16 | `#56 `_ 17 | - Ricky Wiens (`rickywiens `_) - 18 | `#41 `_ 19 | - Boris Glumpler (`shabushabu `_) - 20 | `#28 `_ 21 | - Andrej Badin (`Andreyco `_) - 22 | `#24 `_ 23 | - Stef Horner (`tedslittlerobot `_) - 24 | `#11 `_ 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Breadcrumbs 3 2 | [![Latest Stable Version](https://poser.pugx.org/davejamesmiller/laravel-breadcrumbs/v/stable.png)](https://packagist.org/packages/davejamesmiller/laravel-breadcrumbs) 3 | [![Total Downloads](https://img.shields.io/packagist/dt/davejamesmiller/laravel-breadcrumbs.svg?style=flat)](https://packagist.org/packages/davejamesmiller/laravel-breadcrumbs) 4 | [![Reference Status](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/reference_badge.svg?style=flat)](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/references)
    5 | [![Build Status](https://img.shields.io/travis/davejamesmiller/laravel-breadcrumbs/master.svg?style=flat)](https://travis-ci.org/davejamesmiller/laravel-breadcrumbs) 6 | [![Coverage Status](https://img.shields.io/coveralls/davejamesmiller/laravel-breadcrumbs.png)](https://coveralls.io/r/davejamesmiller/laravel-breadcrumbs) 7 | [![Dependency Status](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/badge.svg)](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs) 8 | 9 | A simple Laravel-style way to create breadcrumbs in [Laravel 5](http://laravel.com/). 10 | 11 | **[Documentation >>](http://laravel-breadcrumbs.davejamesmiller.com/)** 12 | 13 | [MIT License](docs/license.rst) 14 | 15 | -------------------------------------------------------------------------------- 16 | 17 | **Not working?** Before opening a support request, please read this and make sure you include the information requested: 18 | 19 | [Support & Contribution Guidelines](CONTRIBUTING.rst) 20 | 21 | -------------------------------------------------------------------------------- 22 | 23 | *For Laravel 4.0 to 4.2 please use the [2.x version](https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.x) of Laravel Breadcrumbs.* 24 | -------------------------------------------------------------------------------- /docs/output.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Outputting Breadcrumbs 3 | ################################################################################ 4 | 5 | Call ``Breadcrumbs::render()`` in the view template for each page, passing it the name of the breadcrumb to use and any additional parameters. 6 | 7 | .. only:: html 8 | 9 | .. contents:: 10 | :local: 11 | 12 | 13 | ================================================================================ 14 | With Blade 15 | ================================================================================ 16 | 17 | In the page (e.g. ``resources/views/home.blade.php``): 18 | 19 | .. code-block:: html+php 20 | 21 | {!! Breadcrumbs::render('home') !!} 22 | 23 | Or with a parameter: 24 | 25 | .. code-block:: html+php 26 | 27 | {!! Breadcrumbs::render('category', $category) !!} 28 | 29 | 30 | ================================================================================ 31 | With Blade layouts and @section 32 | ================================================================================ 33 | 34 | In the page (e.g. ``resources/views/home.blade.php``): 35 | 36 | .. code-block:: html+php 37 | 38 | @extends('layout.name') 39 | 40 | @section('breadcrumbs', Breadcrumbs::render('home')) 41 | 42 | In the layout (e.g. ``resources/views/app.blade.php``): 43 | 44 | .. code-block:: html+php 45 | 46 | @yield('breadcrumbs') 47 | 48 | 49 | ================================================================================ 50 | Pure PHP (without Blade) 51 | ================================================================================ 52 | 53 | In the page (e.g. ``resources/views/home.php``): 54 | 55 | .. code-block:: html+php 56 | 57 | 58 | 59 | Or use the long-hand syntax if you prefer: 60 | 61 | .. code-block:: html+php 62 | 63 | 64 | -------------------------------------------------------------------------------- /tests/integration/IntegrationTest.php: -------------------------------------------------------------------------------- 1 | push('Home', '/'); 11 | }); 12 | 13 | Breadcrumbs::register('category', function($breadcrumbs, $category) { 14 | $breadcrumbs->parent('home'); 15 | $breadcrumbs->push($category->title, '/category/' . $category->id); 16 | }); 17 | 18 | Breadcrumbs::register('post', function($breadcrumbs, $post) { 19 | $breadcrumbs->parent('category', $post->category); 20 | $breadcrumbs->push($post->title, '/blog/' . $post->id); 21 | }); 22 | 23 | $this->post = (object) [ 24 | 'id' => 123, 25 | 'title' => 'Sample Post', 26 | 'category' => (object) [ 27 | 'id' => 456, 28 | 'title' => 'Sample Category', 29 | ], 30 | ]; 31 | } 32 | 33 | public function testGenerate() 34 | { 35 | $breadcrumbs = Breadcrumbs::generate('post', $this->post); 36 | 37 | $this->assertCount(3, $breadcrumbs); 38 | 39 | $this->assertSame('Home', $breadcrumbs[0]->title); 40 | $this->assertSame('/', $breadcrumbs[0]->url); 41 | $this->assertTrue($breadcrumbs[0]->first); 42 | $this->assertFalse($breadcrumbs[0]->last); 43 | 44 | $this->assertSame('Sample Category', $breadcrumbs[1]->title); 45 | $this->assertSame('/category/456', $breadcrumbs[1]->url); 46 | $this->assertFalse($breadcrumbs[1]->first); 47 | $this->assertFalse($breadcrumbs[1]->last); 48 | 49 | $this->assertSame('Sample Post', $breadcrumbs[2]->title); 50 | $this->assertSame('/blog/123', $breadcrumbs[2]->url); 51 | $this->assertFalse($breadcrumbs[2]->first); 52 | $this->assertTrue($breadcrumbs[2]->last); 53 | } 54 | 55 | public function testRender() 56 | { 57 | $html = Breadcrumbs::render('post', $this->post); 58 | $this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/integration.html', $html); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | app['breadcrumbs'] = $this->app->share(function($app) 35 | { 36 | $breadcrumbs = $this->app->make('DaveJamesMiller\Breadcrumbs\Manager'); 37 | 38 | $viewPath = __DIR__ . '/../views/'; 39 | 40 | $this->loadViewsFrom($viewPath, 'breadcrumbs'); 41 | $this->loadViewsFrom($viewPath, 'laravel-breadcrumbs'); // Backwards-compatibility with 2.x 42 | 43 | $breadcrumbs->setView($app['config']['breadcrumbs.view']); 44 | 45 | return $breadcrumbs; 46 | }); 47 | } 48 | 49 | /** 50 | * Bootstrap the application events. 51 | * 52 | * @return void 53 | */ 54 | public function boot() 55 | { 56 | $configFile = __DIR__ . '/../config/breadcrumbs.php'; 57 | 58 | $this->mergeConfigFrom($configFile, 'breadcrumbs'); 59 | 60 | $this->publishes([ 61 | $configFile => config_path('breadcrumbs.php') 62 | ]); 63 | 64 | $this->registerBreadcrumbs(); 65 | } 66 | 67 | // This method can be overridden in a child class 68 | public function registerBreadcrumbs() 69 | { 70 | // Load the app breadcrumbs if they're in app/Http/breadcrumbs.php 71 | if (file_exists($file = $this->app['path'].'/Http/breadcrumbs.php')) 72 | { 73 | require $file; 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /tests/unit/CurrentRouteTest.php: -------------------------------------------------------------------------------- 1 | currentRoute = app('DaveJamesMiller\Breadcrumbs\CurrentRoute'); 13 | } 14 | 15 | public function testNamedRoute() 16 | { 17 | Route::get('/sample', ['as' => 'sampleroute', function() 18 | { 19 | $this->assertSame(['sampleroute', []], $this->currentRoute->get()); 20 | }]); 21 | 22 | $this->call('GET', '/sample'); 23 | } 24 | 25 | public function testNamedRouteWithParameters() 26 | { 27 | $object = new stdClass; 28 | 29 | Route::bind('object', function() use ($object) { 30 | return $object; 31 | }); 32 | 33 | Route::get('/sample/{text}/{object}', ['as' => 'sampleroute', function() use ($object) 34 | { 35 | $this->assertSame(['sampleroute', ['blah', $object]], $this->currentRoute->get()); 36 | }]); 37 | 38 | $this->call('GET', '/sample/blah/object'); 39 | } 40 | 41 | /** 42 | * @expectedException DaveJamesMiller\Breadcrumbs\Exception 43 | * @expectedExceptionMessage The current route (GET /sample/unnamed) is not named - please check routes.php for an "as" parameter 44 | */ 45 | public function testUnnamedRoute() 46 | { 47 | Route::get('/sample/unnamed', function() 48 | { 49 | $this->assertSame(['sample', []], $this->currentRoute->get()); 50 | }); 51 | 52 | $this->call('GET', '/sample/unnamed'); 53 | } 54 | 55 | public function testSet() 56 | { 57 | $this->currentRoute->set('custom', [1, 'blah']); 58 | 59 | Route::get('/sample', ['as' => 'sampleroute', function() 60 | { 61 | $this->assertSame(['custom', [1, 'blah']], $this->currentRoute->get()); 62 | }]); 63 | 64 | $this->call('GET', '/sample'); 65 | } 66 | 67 | public function testClear() 68 | { 69 | $this->currentRoute->set('custom', [1, 'blah']); 70 | $this->currentRoute->clear(); 71 | 72 | Route::get('/sample', ['as' => 'sampleroute', function() 73 | { 74 | $this->assertSame(['sampleroute', []], $this->currentRoute->get()); 75 | }]); 76 | 77 | $this->call('GET', '/sample'); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /docs/templates.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Custom Templates 3 | ################################################################################ 4 | 5 | .. only:: html 6 | 7 | .. contents:: 8 | :local: 9 | 10 | 11 | ================================================================================ 12 | Create a view 13 | ================================================================================ 14 | 15 | To customise the HTML, create your own view file (e.g. ``resources/views/_partials/breadcrumbs.blade.php``) like this: 16 | 17 | .. code-block:: html+php 18 | 19 | @if ($breadcrumbs) 20 | 29 | @endif 30 | 31 | (See the `views/ directory `_ for the built-in templates.) 32 | 33 | 34 | .. _view-data: 35 | 36 | ---------------------------------------- 37 | View data 38 | ---------------------------------------- 39 | 40 | The view will receive an array called ``$breadcrumbs``. 41 | 42 | Each breadcrumb is an object with the following keys: 43 | 44 | - ``title`` - The title you set above 45 | - ``url`` - The URL you set above 46 | - ``first`` - ``true`` for the first breadcrumb (top level), ``false`` otherwise 47 | - ``last`` - ``true`` for the last breadcrumb (current page), ``false`` otherwise 48 | - Additional keys for each item in ``$data`` (see :ref:`custom-data`) 49 | 50 | 51 | ================================================================================ 52 | Update the config 53 | ================================================================================ 54 | 55 | Then update your config file (``config/breadcrumbs.php``) with the custom view name, e.g.: 56 | 57 | .. code-block:: php 58 | 59 | 'view' => '_partials/breadcrumbs', 60 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Support & Contribution Guidelines 3 | ################################################################################ 4 | 5 | .. This file is for GitHub (https://github.com/blog/1184-contributing-guidelines) 6 | 7 | Please submit support requests, bug reports, feature requests and pull requests using `GitHub issues `_. 8 | 9 | All **support requests / bug reports** should include the following: 10 | 11 | - The complete error message, including file & line numbers 12 | - Steps to reproduce the problem 13 | - Laravel Breadcrumbs version 14 | - Laravel version 15 | - PHP version 16 | 17 | You should also include copies of the following where appropriate: 18 | 19 | - ``app/Http/breadcrumbs.php`` 20 | - ``config/breadcrumbs.php`` (if used) 21 | - The view or layout that outputs the breadcrumbs 22 | - The custom breadcrumbs template (if applicable) 23 | - The ``providers`` and ``aliases`` sections of ``config/app.php`` (Note: **not the Encryption Key section** which should be kept private) -- in case there's a conflict with another package 24 | - Any other relevant files 25 | 26 | **Note:** Don't be afraid to go into the Laravel Breadcrumbs code and use ``var_dump()`` (or ``print_r()``) to see what's happening and try to fix your own problems! A pull request or detailed bug report is much more likely to get attention than a vague error report. Also make sure you read the `documentation `_ carefully. 27 | 28 | Any **feature requests / pull requests** should include details of what you are trying to achieve (use case) to explain why your request should be implemented. 29 | 30 | .. This text is also in docs/contributing.rst 31 | If you want to submit a **bug fix**, please make your changes in a new branch, then open a `pull request `_. (The `Contributing page of the docs `_ may help you to get started if you've not done this before.) 32 | 33 | .. This text is also in docs/contributing.rst 34 | If you want to submit a **new feature**, it's usually best to open an `issue `_ to discuss the idea first -- to make sure it will be accepted before spending too much time on it. (Of course you can go ahead and develop it first if you prefer!) Please be sure to update the documentation as well. 35 | 36 | If you have any suggestions for improving the **documentation** -- especially if anything is unclear to you and could be explained better -- please let me know. (Or just edit it yourself and make a pull request.) 37 | -------------------------------------------------------------------------------- /src/Manager.php: -------------------------------------------------------------------------------- 1 | generator = $generator; 16 | $this->currentRoute = $currentRoute; 17 | $this->view = $view; 18 | } 19 | 20 | public function register($name, $callback) 21 | { 22 | if (isset($this->callbacks[$name])) 23 | throw new Exception("Breadcrumb name \"{$name}\" has already been registered"); 24 | $this->callbacks[$name] = $callback; 25 | } 26 | 27 | public function exists($name = null) 28 | { 29 | if (is_null($name)) { 30 | try { 31 | list($name) = $this->currentRoute->get(); 32 | } catch (Exception $e) { 33 | return false; 34 | } 35 | } 36 | 37 | return isset($this->callbacks[$name]); 38 | } 39 | 40 | public function generate($name = null) 41 | { 42 | if (is_null($name)) 43 | list($name, $params) = $this->currentRoute->get(); 44 | else 45 | $params = array_slice(func_get_args(), 1); 46 | 47 | return $this->generator->generate($this->callbacks, $name, $params); 48 | } 49 | 50 | public function generateArray($name, $params = []) 51 | { 52 | return $this->generator->generate($this->callbacks, $name, $params); 53 | } 54 | 55 | public function generateIfExists($name = null) 56 | { 57 | if (is_null($name)) 58 | list($name, $params) = $this->currentRoute->get(); 59 | else 60 | $params = array_slice(func_get_args(), 1); 61 | 62 | if (!$this->exists($name)) 63 | return []; 64 | 65 | return $this->generator->generate($this->callbacks, $name, $params); 66 | } 67 | 68 | public function generateIfExistsArray($name, $params = []) 69 | { 70 | if (!$this->exists($name)) 71 | return []; 72 | 73 | return $this->generator->generate($this->callbacks, $name, $params); 74 | } 75 | 76 | /** 77 | * @deprecated Since 3.0.0 78 | * @see generateIfExistsArray 79 | */ 80 | public function generateArrayIfExists() 81 | { 82 | return call_user_func_array([$this, 'generateIfExistsArray'], func_get_args()); 83 | } 84 | 85 | public function render($name = null) 86 | { 87 | if (is_null($name)) 88 | list($name, $params) = $this->currentRoute->get(); 89 | else 90 | $params = array_slice(func_get_args(), 1); 91 | 92 | $breadcrumbs = $this->generator->generate($this->callbacks, $name, $params); 93 | 94 | return $this->view->render($this->viewName, $breadcrumbs); 95 | } 96 | 97 | public function renderArray($name, $params = []) 98 | { 99 | $breadcrumbs = $this->generator->generate($this->callbacks, $name, $params); 100 | 101 | return $this->view->render($this->viewName, $breadcrumbs); 102 | } 103 | 104 | public function renderIfExists($name = null) 105 | { 106 | if (is_null($name)) 107 | list($name, $params) = $this->currentRoute->get(); 108 | else 109 | $params = array_slice(func_get_args(), 1); 110 | 111 | if (!$this->exists($name)) 112 | return ''; 113 | 114 | $breadcrumbs = $this->generator->generate($this->callbacks, $name, $params); 115 | 116 | return $this->view->render($this->viewName, $breadcrumbs); 117 | } 118 | 119 | public function renderIfExistsArray($name, $params = []) 120 | { 121 | if (!$this->exists($name)) 122 | return ''; 123 | 124 | $breadcrumbs = $this->generator->generate($this->callbacks, $name, $params); 125 | 126 | return $this->view->render($this->viewName, $breadcrumbs); 127 | } 128 | 129 | /** 130 | * @deprecated Since 3.0.0 131 | * @see renderIfExistsArray 132 | */ 133 | public function renderArrayIfExists() 134 | { 135 | return call_user_func_array([$this, 'renderIfExistsArray'], func_get_args()); 136 | } 137 | 138 | public function setCurrentRoute($name) 139 | { 140 | $params = array_slice(func_get_args(), 1); 141 | 142 | $this->currentRoute->set($name, $params); 143 | } 144 | 145 | public function setCurrentRouteArray($name, $params = []) 146 | { 147 | $this->currentRoute->set($name, $params); 148 | } 149 | 150 | public function clearCurrentRoute() 151 | { 152 | $this->currentRoute->clear(); 153 | } 154 | 155 | public function setView($view) 156 | { 157 | $this->viewName = $view; 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /docs/start.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Getting Started 3 | ################################################################################ 4 | 5 | .. only:: html 6 | 7 | .. contents:: 8 | :local: 9 | 10 | 11 | ================================================================================ 12 | 1. Install Laravel Breadcrumbs 13 | ================================================================================ 14 | 15 | .. note:: 16 | 17 | Laravel 5.0 or above is required -- use the `2.x version `_ for Laravel 4. 18 | 19 | 20 | ---------------------------------------- 21 | Install with Composer 22 | ---------------------------------------- 23 | 24 | Run this at the command line: 25 | 26 | .. code-block:: bash 27 | 28 | $ composer require davejamesmiller/laravel-breadcrumbs 29 | 30 | This will both update ``composer.json`` and install the package into the ``vendor/`` directory. 31 | 32 | 33 | ---------------------------------------- 34 | Add to ``config/app.php`` 35 | ---------------------------------------- 36 | 37 | Add the service provider to ``providers``: 38 | 39 | .. code-block:: php 40 | 41 | 'providers' => [ 42 | // ... 43 | 'DaveJamesMiller\Breadcrumbs\ServiceProvider', 44 | ], 45 | 46 | And add the facade to ``aliases``: 47 | 48 | .. code-block:: php 49 | 50 | 'aliases' => [ 51 | // ... 52 | 'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade', 53 | ], 54 | 55 | 56 | ================================================================================ 57 | 2. Define your breadcrumbs 58 | ================================================================================ 59 | 60 | Create a file called ``app/Http/breadcrumbs.php`` that looks like this: 61 | 62 | .. code-block:: php 63 | 64 | push('Home', route('home')); 70 | }); 71 | 72 | // Home > About 73 | Breadcrumbs::register('about', function($breadcrumbs) 74 | { 75 | $breadcrumbs->parent('home'); 76 | $breadcrumbs->push('About', route('about')); 77 | }); 78 | 79 | // Home > Blog 80 | Breadcrumbs::register('blog', function($breadcrumbs) 81 | { 82 | $breadcrumbs->parent('home'); 83 | $breadcrumbs->push('Blog', route('blog')); 84 | }); 85 | 86 | // Home > Blog > [Category] 87 | Breadcrumbs::register('category', function($breadcrumbs, $category) 88 | { 89 | $breadcrumbs->parent('blog'); 90 | $breadcrumbs->push($category->title, route('category', $category->id)); 91 | }); 92 | 93 | // Home > Blog > [Category] > [Page] 94 | Breadcrumbs::register('page', function($breadcrumbs, $page) 95 | { 96 | $breadcrumbs->parent('category', $page->category); 97 | $breadcrumbs->push($page->title, route('page', $page->id)); 98 | }); 99 | 100 | See the :doc:`defining` section for more details. 101 | 102 | 103 | .. _choose-template: 104 | 105 | ================================================================================ 106 | 3. Choose a template 107 | ================================================================================ 108 | 109 | By default a `Bootstrap `_-compatible ordered list will be rendered, so if you're using Bootstrap 3 you can skip this step. 110 | 111 | First initialise the config file by running this command: 112 | 113 | .. code-block:: bash 114 | 115 | $ php artisan vendor:publish 116 | 117 | Then open ``config/breadcrumbs.php`` and edit this line: 118 | 119 | .. code-block:: php 120 | 121 | 'view' => 'breadcrumbs::bootstrap3', 122 | 123 | The possible values are: 124 | 125 | - `Bootstrap 3 `_: ``breadcrumbs::bootstrap3`` 126 | - `Bootstrap 2 `_: ``breadcrumbs::bootstrap2`` 127 | - The path to a custom view: e.g. ``_partials/breadcrumbs`` 128 | 129 | See the :doc:`templates` section for more details. 130 | 131 | 132 | ================================================================================ 133 | 4. Output the breadcrumbs 134 | ================================================================================ 135 | 136 | Finally, call ``Breadcrumbs::render()`` in the view template for each page, passing it the name of the breadcrumb to use and any additional parameters -- for example: 137 | 138 | .. code-block:: html+php 139 | 140 | {!! Breadcrumbs::render('home') !!} 141 | 142 | {!! Breadcrumbs::render('category', $category) !!} 143 | 144 | See the :doc:`output` section for other output options, and see :doc:`routing` for a way to link breadcrumb names to route names automatically. 145 | -------------------------------------------------------------------------------- /docs/defining.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Defining Breadcrumbs 3 | ################################################################################ 4 | 5 | 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. 6 | 7 | The following examples should make it clear: 8 | 9 | .. only:: html 10 | 11 | .. contents:: 12 | :local: 13 | 14 | 15 | ================================================================================ 16 | Static pages 17 | ================================================================================ 18 | 19 | The most simple breadcrumb is probably going to be your homepage, which will look something like this: 20 | 21 | .. code-block:: php 22 | 23 | Breadcrumbs::register('home', function($breadcrumbs) { 24 | $breadcrumbs->push('Home', route('home')); 25 | }); 26 | 27 | As you can see, you simply call ``$breadcrumbs->push($title, $url)`` inside the closure. 28 | 29 | For generating the URL, you can use any of the standard Laravel URL-generation methods, including: 30 | 31 | - ``url('path/to/route')`` (``URL::to()``) 32 | - ``secure_url('path/to/route')`` 33 | - ``route('routename')`` (``URL::route()``) 34 | - ``action('controller@action')`` (``URL::action()``) 35 | - Or just pass a string URL (``'http://www.example.com/'``) 36 | 37 | This example would be rendered like this: 38 | 39 | .. raw:: html 40 | 41 |
     42 |     Home
     43 |     
    44 | 45 | .. only:: not html 46 | 47 | :: 48 | 49 | Home 50 | 51 | 52 | .. _defining-parents: 53 | 54 | ================================================================================ 55 | Parent links 56 | ================================================================================ 57 | 58 | This is another static page, but this has a parent link before it: 59 | 60 | .. code-block:: php 61 | 62 | Breadcrumbs::register('blog', function($breadcrumbs) { 63 | $breadcrumbs->parent('home'); 64 | $breadcrumbs->push('Blog', route('blog')); 65 | }); 66 | 67 | It would be rendered like this: 68 | 69 | .. raw:: html 70 | 71 |
     72 |     Home / Blog
     73 |     
    74 | 75 | .. only:: not html 76 | 77 | :: 78 | 79 | Home > Blog 80 | 81 | 82 | ================================================================================ 83 | Dynamic titles and links 84 | ================================================================================ 85 | 86 | This is a dynamically generated page pulled from the database: 87 | 88 | .. code-block:: php 89 | 90 | Breadcrumbs::register('page', function($breadcrumbs, $page) { 91 | $breadcrumbs->parent('blog'); 92 | $breadcrumbs->push($page->title, route('page', $page->id)); 93 | }); 94 | 95 | The ``$page`` variable would simply be passed in from the view: 96 | 97 | .. code-block:: html+php 98 | 99 | {!! Breadcrumbs::render('page', $page) !!} 100 | 101 | It would be rendered like this: 102 | 103 | .. raw:: html 104 | 105 |
    106 |     Home / Blog / Page Title
    107 |     
    108 | 109 | .. only:: not html 110 | 111 | :: 112 | 113 | Home > Blog > Page Title 114 | 115 | **Tip:** You can pass multiple parameters if necessary. 116 | 117 | 118 | ================================================================================ 119 | Nested categories 120 | ================================================================================ 121 | 122 | Finally if you have nested categories or other special requirements, you can call ``$breadcrumbs->push()`` multiple times: 123 | 124 | .. code-block:: php 125 | 126 | Breadcrumbs::register('category', function($breadcrumbs, $category) { 127 | $breadcrumbs->parent('blog'); 128 | 129 | foreach ($category->ancestors as $ancestor) { 130 | $breadcrumbs->push($ancestor->title, route('category', $ancestor->id)); 131 | } 132 | 133 | $breadcrumbs->push($category->title, route('category', $category->id)); 134 | }); 135 | 136 | Alternatively you could make a recursive function such as this: 137 | 138 | .. code-block:: php 139 | 140 | Breadcrumbs::register('category', function($breadcrumbs, $category) { 141 | if ($category->parent) 142 | $breadcrumbs->parent('category', $category->parent); 143 | else 144 | $breadcrumbs->parent('blog'); 145 | 146 | $breadcrumbs->push($category->title, route('category', $category->slug)); 147 | }); 148 | 149 | Both would be rendered like this: 150 | 151 | .. raw:: html 152 | 153 |
    154 |     Home / Blog / Grandparent Category / Parent Category / Category Title
    155 |     
    156 | 157 | .. only:: not html 158 | 159 | :: 160 | 161 | Home > Blog > Grandparent Category > Parent Category > Category Title 162 | -------------------------------------------------------------------------------- /docs/advanced.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Advanced Usage 3 | ################################################################################ 4 | 5 | .. only:: html 6 | 7 | .. contents:: 8 | :local: 9 | 10 | 11 | .. _no-url: 12 | 13 | ================================================================================ 14 | Breadcrumbs with no URL 15 | ================================================================================ 16 | 17 | The second parameter to ``push()`` is optional, so if you want a breadcrumb with no URL you can do so: 18 | 19 | .. code-block:: php 20 | 21 | $breadcrumbs->push('Sample'); 22 | 23 | The ``$breadcrumb->url`` value will be ``null``. 24 | 25 | 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. 26 | 27 | *Note: Support for this was added to the Twitter Bootstrap templates in 2.1.0. Before this you would need to create a custom template.* 28 | 29 | 30 | .. _custom-data: 31 | 32 | ================================================================================ 33 | Custom data 34 | ================================================================================ 35 | 36 | *Added in 2.3.0.* 37 | 38 | The ``push()`` method accepts an optional third parameter, ``$data`` - an array of arbitrary data to be passed to the breadcrumb, which you can use in your custom template. For example, if you wanted each breadcrumb to have an icon, you could do: 39 | 40 | .. code-block:: php 41 | 42 | $breadcrumbs->push('Home', '/', ['icon' => 'home.png']); 43 | 44 | The ``$data`` array's entries will be merged into the breadcrumb as properties, so you would access the icon as ``$breadcrumb->icon`` in your template, like this: 45 | 46 | .. code-block:: html+php 47 | 48 |
  • 49 | 50 | {{{ $breadcrumb->title }}} 51 |
  • 52 | 53 | Do not use the following keys in your data array, as they will be overwritten: ``title``, ``url``, ``first``, ``last``. 54 | 55 | 56 | ================================================================================ 57 | Defining breadcrumbs in a different file 58 | ================================================================================ 59 | 60 | If you don't want to use ``app/Http/breadcrumbs.php``, you can define them in ``app/Http/routes.php`` or any other file as long as it's loaded by Laravel. 61 | 62 | 63 | .. _switching-views: 64 | 65 | ================================================================================ 66 | Switching views dynamically 67 | ================================================================================ 68 | 69 | You can change the view at runtime by calling: 70 | 71 | .. code-block:: php 72 | 73 | Breadcrumbs::setView('view.name'); 74 | 75 | Or you can call ``Breadcrumbs::generate()`` and then load the view manually: 76 | 77 | .. code-block:: html+php 78 | 79 | @include('_partials/breadcrumbs2', ['breadcrumbs' => Breadcrumbs::generate('category', $category)]) 80 | 81 | 82 | .. _current-route: 83 | 84 | ================================================================================ 85 | Overriding the "current" route 86 | ================================================================================ 87 | 88 | If you call ``Breadcrumbs::render()`` or ``Breadcrumbs::generate()`` with no parameters, it will use the current route name and parameters by default (as returned by Laravel's ``Route::current()`` method). 89 | 90 | You can override this by calling ``Breadcrumbs::setCurrentRoute($name, $param1, $param2...)`` or ``Breadcrumbs::setCurrentRouteArray($name, $params)``. 91 | 92 | 93 | .. _array-parameters: 94 | 95 | ================================================================================ 96 | Passing an array of parameters 97 | ================================================================================ 98 | 99 | *Added in 2.0.0.* 100 | 101 | If the breadcrumb requires multiple parameters, you would normally pass them like this: 102 | 103 | .. code-block:: php 104 | 105 | Breadcrumbs::render('name', $param1, $param2, $param3); 106 | Breadcrumbs::generate('name', $param1, $param2, $param3); 107 | $breadcrumbs->parent('name', $param1, $param2, $param3); 108 | 109 | If you want to pass an array of parameters instead you can use these methods: 110 | 111 | .. code-block:: php 112 | 113 | Breadcrumbs::renderArray('name', $params); 114 | Breadcrumbs::generateArray('name', $params); 115 | $breadcrumbs->parentArray('name', $params); 116 | 117 | 118 | .. _exists: 119 | 120 | ================================================================================ 121 | Checking if a breadcrumb exists 122 | ================================================================================ 123 | 124 | *Added in 2.2.0.* 125 | 126 | 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: 127 | 128 | - ``Breadcrumbs::renderIfExists()`` (returns an empty string) 129 | - ``Breadcrumbs::renderArrayIfExists()`` (returns an empty string) 130 | - ``Breadcrumbs::generateIfExists()`` (returns an empty array) 131 | - ``Breadcrumbs::generateArrayIfExists()`` (returns an empty array) 132 | 133 | Alternatively you can call ``Breadcrumbs::exists('name')``, which returns a boolean. 134 | -------------------------------------------------------------------------------- /tests/unit/GeneratorTest.php: -------------------------------------------------------------------------------- 1 | generator = new Generator; 13 | } 14 | 15 | public function testCallbacks() 16 | { 17 | $this->generator->generate([ 18 | 'sample' => function($breadcrumbs) 19 | { 20 | $this->assertSame($this->generator, $breadcrumbs); 21 | }, 22 | ], 'sample', []); 23 | } 24 | 25 | public function testCallbackParameters() 26 | { 27 | $this->generator->generate([ 28 | 'sample' => function($breadcrumbs, $num, $text) 29 | { 30 | $this->assertSame(1, $num); 31 | $this->assertSame('blah', $text); 32 | }, 33 | ], 'sample', [1, 'blah']); 34 | } 35 | 36 | // $breadcrumbs->push($title) 37 | // $breadcrumb->title 38 | public function testPush_title() 39 | { 40 | $breadcrumbs = $this->generator->generate([ 41 | 'sample' => function($breadcrumbs) 42 | { 43 | $breadcrumbs->push('Home'); 44 | }, 45 | ], 'sample', []); 46 | 47 | $this->assertCount(1, $breadcrumbs); 48 | $this->assertSame('Home', $breadcrumbs[0]->title); 49 | $this->assertNull($breadcrumbs[0]->url); 50 | } 51 | 52 | // $breadcrumbs->push($title, $url) 53 | // $breadcrumb->url 54 | public function testPush_title_url() 55 | { 56 | $breadcrumbs = $this->generator->generate([ 57 | 'sample' => function($breadcrumbs) 58 | { 59 | $breadcrumbs->push('Home', '/'); 60 | }, 61 | ], 'sample', []); 62 | 63 | $this->assertCount(1, $breadcrumbs); 64 | $this->assertSame('Home', $breadcrumbs[0]->title); 65 | $this->assertSame('/', $breadcrumbs[0]->url); 66 | } 67 | 68 | // $breadcrumbs->push($title, $url, $data) 69 | // $breadcrumb->custom_attribute_name 70 | public function testPush_title_url_data() 71 | { 72 | $data = [ 73 | 'foo' => 'bar', 74 | 'baz' => 'qux', 75 | 'title' => 'should not be overwritten by custom data', 76 | ]; 77 | 78 | $breadcrumbs = $this->generator->generate([ 79 | 'sample' => function($breadcrumbs) 80 | { 81 | $breadcrumbs->push('Home', '/', ['foo' => 'bar', 'title' => 'ignored']); 82 | }, 83 | ], 'sample', []); 84 | 85 | $this->assertCount(1, $breadcrumbs); 86 | $this->assertSame('Home', $breadcrumbs[0]->title); 87 | $this->assertSame('/', $breadcrumbs[0]->url); 88 | $this->assertSame('bar', $breadcrumbs[0]->foo); 89 | } 90 | 91 | public function testPushMultipleTimes() 92 | { 93 | $breadcrumbs = $this->generator->generate([ 94 | 'sample' => function($breadcrumbs) 95 | { 96 | $breadcrumbs->push('Level 1', '/1'); 97 | $breadcrumbs->push('Level 2', '/2'); 98 | $breadcrumbs->push('Level 3', '/3'); 99 | }, 100 | ], 'sample', []); 101 | 102 | $this->assertCount(3, $breadcrumbs); 103 | $this->assertSame('Level 1', $breadcrumbs[0]->title); 104 | $this->assertSame('Level 2', $breadcrumbs[1]->title); 105 | $this->assertSame('Level 3', $breadcrumbs[2]->title); 106 | $this->assertSame('/1', $breadcrumbs[0]->url); 107 | $this->assertSame('/2', $breadcrumbs[1]->url); 108 | $this->assertSame('/3', $breadcrumbs[2]->url); 109 | } 110 | 111 | // $breadcrumbs->parent($name) 112 | public function testParent_name() 113 | { 114 | $breadcrumbs = $this->generator->generate([ 115 | 'home' => function($breadcrumbs) 116 | { 117 | $breadcrumbs->push('Home', '/'); 118 | }, 119 | 'sample' => function($breadcrumbs) 120 | { 121 | $breadcrumbs->parent('home'); 122 | $breadcrumbs->push('Page', '/page'); 123 | }, 124 | ], 'sample', []); 125 | 126 | $this->assertCount(2, $breadcrumbs); 127 | $this->assertSame('Home', $breadcrumbs[0]->title); 128 | $this->assertSame('/', $breadcrumbs[0]->url); 129 | $this->assertSame('Page', $breadcrumbs[1]->title); 130 | $this->assertSame('/page', $breadcrumbs[1]->url); 131 | } 132 | 133 | // $breadcrumbs->parent($name, $param1, ...) 134 | public function testParent_name_params() 135 | { 136 | $breadcrumbs = $this->generator->generate([ 137 | 'parent' => function($breadcrumbs, $num, $text) 138 | { 139 | $this->assertSame(1, $num); 140 | $this->assertSame('blah', $text); 141 | }, 142 | 'sample' => function($breadcrumbs) 143 | { 144 | $breadcrumbs->parent('parent', 1, 'blah'); 145 | }, 146 | ], 'sample', []); 147 | } 148 | 149 | // $breadcrumbs->parentArray($name, $params) 150 | public function testParentArray_name_params() 151 | { 152 | $breadcrumbs = $this->generator->generate([ 153 | 'parent' => function($breadcrumbs, $num, $text) 154 | { 155 | $this->assertSame(1, $num); 156 | $this->assertSame('blah', $text); 157 | }, 158 | 'sample' => function($breadcrumbs) 159 | { 160 | $breadcrumbs->parentArray('parent', [1, 'blah']); 161 | }, 162 | ], 'sample', []); 163 | } 164 | 165 | // $breadcrumb->first 166 | // $breadcrumb->last 167 | public function testFirstLast() 168 | { 169 | $breadcrumbs = $this->generator->generate([ 170 | 'sample' => function($breadcrumbs) 171 | { 172 | $breadcrumbs->push('Level 1', '/1'); 173 | $breadcrumbs->push('Level 2', '/2'); 174 | $breadcrumbs->push('Level 3', '/3'); 175 | }, 176 | ], 'sample', []); 177 | 178 | $this->assertCount(3, $breadcrumbs); 179 | 180 | $this->assertTrue($breadcrumbs[0]->first, '$breadcrumbs[0]->first'); 181 | $this->assertFalse($breadcrumbs[1]->first, '$breadcrumbs[1]->first'); 182 | $this->assertFalse($breadcrumbs[2]->first, '$breadcrumbs[2]->first'); 183 | 184 | $this->assertFalse($breadcrumbs[0]->last, '$breadcrumbs[0]->last'); 185 | $this->assertFalse($breadcrumbs[1]->last, '$breadcrumbs[1]->last'); 186 | $this->assertTrue($breadcrumbs[2]->last, '$breadcrumbs[2]->last'); 187 | } 188 | 189 | } 190 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | API Reference 3 | ################################################################################ 4 | 5 | .. only:: html 6 | 7 | .. contents:: 8 | :local: 9 | 10 | 11 | ================================================================================ 12 | ``Breadcrumbs`` Facade 13 | ================================================================================ 14 | 15 | ======================================================== ========== ========== ============================ 16 | Method Returns Added in Docs 17 | ======================================================== ========== ========== ============================ 18 | ``Breadcrumbs::register($name, $callback)`` *(none)* 1.0.0 :doc:`Defining ` 19 | ``Breadcrumbs::exists()`` boolean 2.2.0 :doc:`Route-bound ` 20 | ``Breadcrumbs::exists($name)`` boolean 2.2.0 :ref:`Exists ` 21 | ``Breadcrumbs::generate()`` array 2.2.3 :doc:`Route-bound ` 22 | ``Breadcrumbs::generate($name)`` array 1.0.0 :ref:`Switching views ` 23 | ``Breadcrumbs::generate($name, $param1, ...)`` array 1.0.0 :ref:`Switching views ` 24 | ``Breadcrumbs::generateArray($name, $params)`` array 2.0.0 :ref:`Array params ` 25 | ``Breadcrumbs::generateIfExists()`` array 2.2.0 :doc:`Route-bound ` 26 | ``Breadcrumbs::generateIfExists($name)`` array 2.2.0 :ref:`Exists ` 27 | ``Breadcrumbs::generateIfExists($name, $param1, ...)`` array 2.2.0 :ref:`Exists ` 28 | ``Breadcrumbs::generateIfExistsArray($name, $params)`` array 3.0.0 :ref:`Exists ` 29 | ``Breadcrumbs::render()`` string 2.2.0 :doc:`Route-bound ` 30 | ``Breadcrumbs::render($name)`` string 1.0.0 :doc:`Output ` 31 | ``Breadcrumbs::render($name, $param1, ...)`` string 1.0.0 :doc:`Output ` 32 | ``Breadcrumbs::renderArray($name, $params)`` string 2.0.0 :ref:`Array params ` 33 | ``Breadcrumbs::renderIfExists()`` string 2.2.0 :doc:`Route-bound ` 34 | ``Breadcrumbs::renderIfExists($name)`` string 2.2.0 :ref:`Exists ` 35 | ``Breadcrumbs::renderIfExists($name, $param1, ...)`` string 2.2.0 :ref:`Exists ` 36 | ``Breadcrumbs::renderIfExistsArray($name, $params)`` string 3.0.0 :ref:`Exists ` 37 | ``Breadcrumbs::setCurrentRoute($name)`` *(none)* 2.2.0 :ref:`Current route ` 38 | ``Breadcrumbs::setCurrentRoute($name, $param1, ...)`` *(none)* 2.2.0 :ref:`Current route ` 39 | ``Breadcrumbs::setCurrentRouteArray($name, $params)`` *(none)* 2.2.0 :ref:`Current route ` 40 | ``Breadcrumbs::clearCurrentRoute()`` *(none)* 2.2.0 41 | ``Breadcrumbs::setView($view)`` *(none)* 1.0.0 :ref:`Switching views ` 42 | ======================================================== ========== ========== ============================ 43 | 44 | `Source `__ 45 | 46 | 47 | ================================================================================ 48 | Defining breadcrumbs 49 | ================================================================================ 50 | 51 | .. code-block:: php 52 | 53 | Breadcrumbs::register('name', function($breadcrumbs, $page) { 54 | // ... 55 | }); 56 | 57 | 58 | ======================================================== ========== ========== ============================ 59 | Method Returns Added in Docs 60 | ======================================================== ========== ========== ============================ 61 | ``$breadcrumbs->push($title)`` *(none)* 1.0.0 :ref:`No URL ` 62 | ``$breadcrumbs->push($title, $url)`` *(none)* 1.0.0 :doc:`Defining ` 63 | ``$breadcrumbs->push($title, $url, $data)`` *(none)* 2.3.0 :ref:`Custom data ` 64 | ``$breadcrumbs->parent($name)`` *(none)* 1.0.0 :ref:`Parent links ` 65 | ``$breadcrumbs->parent($name, $param1, ...)`` *(none)* 1.0.0 :ref:`Parent links ` 66 | ``$breadcrumbs->parentArray($name, $params)`` *(none)* 2.0.0 :ref:`Array parameters ` 67 | ======================================================== ========== ========== ============================ 68 | 69 | `Source `__ 70 | 71 | 72 | ================================================================================ 73 | In the view (template) 74 | ================================================================================ 75 | 76 | ``$breadcrumbs`` (array), contains: 77 | 78 | ======================================================== ================ ========== ============================ 79 | Variable Type Added in Docs 80 | ======================================================== ================ ========== ============================ 81 | ``$breadcrumb->title`` string 1.0.0 :ref:`View data ` 82 | ``$breadcrumb->url`` string or null 1.0.0 :ref:`View data ` 83 | ``$breadcrumb->first`` boolean 1.0.0 :ref:`View data ` 84 | ``$breadcrumb->last`` boolean 1.0.0 :ref:`View data ` 85 | ``$breadcrumb->custom_attribute_name`` mixed 2.3.0 :ref:`Custom data ` 86 | ======================================================== ================ ========== ============================ 87 | -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Contributing 3 | ################################################################################ 4 | 5 | .. This text is also in ../CONTRIBUTING.rst 6 | 7 | If you want to submit a **bug fix**, make your changes in a new branch, based on the ``develop`` branch, then simply open a `pull request `_ on GitHub. (The information below may help you to get started if you've not done this before.) 8 | 9 | If you want to submit a **new feature**, it's usually best to open an `issue `_ to discuss the idea first -- to make sure it will be accepted before spending too much time on it. (Of course you can go ahead and develop it first if you prefer!) Please be sure to update the documentation as well. 10 | 11 | .. only:: html 12 | 13 | .. contents:: 14 | :local: 15 | 16 | 17 | ================================================================================ 18 | Developing inside a real application 19 | ================================================================================ 20 | 21 | The easiest way to develop Laravel Breadcrumbs alongside a real Laravel application is to set it up as normal, but tell Composer to install from source with the ``--prefer-source`` flag. 22 | 23 | If you've already got it installed, delete it from the ``vendor/`` directory and re-install from source: 24 | 25 | .. code-block:: bash 26 | 27 | $ cd /path/to/repo 28 | $ rm -rf vendor/davejamesmiller/laravel-breadcrumbs 29 | $ composer install --prefer-source 30 | $ cd vendor/davejamesmiller/laravel-breadcrumbs 31 | $ git checkout -t origin/develop 32 | $ git checkout -b YOUR_BRANCH 33 | # Make changes and commit them 34 | $ git remote add YOUR_USERNAME git@github.com:YOUR_USERNAME/laravel-breadcrumbs 35 | $ git push -u YOUR_USERNAME YOUR_BRANCH 36 | 37 | There is also a `test app `_ available to simplify testing against multiple versions of Laravel. 38 | 39 | .. note:: 40 | 41 | The test app is not a replacement for unit tests - we have those too - but it gives a better feel for how the package works in practice. 42 | 43 | 44 | ================================================================================ 45 | Using your fork in a project 46 | ================================================================================ 47 | 48 | If you have forked the package (e.g. to fix a bug or add a feature), you may want to use that version in your project until the changes are merged and released. To do that, simply update the ``composer.json`` in your main project as follows: 49 | 50 | .. code-block:: json 51 | 52 | { 53 | "repositories": [ 54 | { 55 | "type": "vcs", 56 | "url": "https://github.com/YOUR_USERNAME/laravel-breadcrumbs.git" 57 | } 58 | ], 59 | "require": { 60 | "davejamesmiller/laravel-breadcrumbs": "dev-YOUR_BRANCH" 61 | } 62 | } 63 | 64 | Replace ``YOUR_USERNAME`` with your GitHub username and ``YOUR_BRANCH`` with the branch name (e.g. ``develop``). This tells Composer to use your repository instead of the default one. 65 | 66 | 67 | ================================================================================ 68 | Unit tests 69 | ================================================================================ 70 | 71 | To run the unit tests, simply run: 72 | 73 | .. code-block:: bash 74 | 75 | $ cd /path/to/laravel-breadcrumbs 76 | $ composer update 77 | $ ./test.sh 78 | 79 | (Note: The unit tests are not 100% complete yet, and the code will probably need some refactoring to make it easier to test.) 80 | 81 | 82 | ---------------------------------------- 83 | Code coverage 84 | ---------------------------------------- 85 | 86 | To check code coverage, you will also need `Xdebug `_ installed. Run: 87 | 88 | .. code-block:: bash 89 | 90 | $ ./test-coverage.sh 91 | 92 | Then open ``test-coverage/index.html`` to view the results. (However, be aware of the `edge cases `_ in PHPUnit that can make it not-quite-accurate.) 93 | 94 | 95 | .. _contributing-documentation: 96 | 97 | ================================================================================ 98 | Documentation 99 | ================================================================================ 100 | 101 | Documentation is in ``docs/``. It is written in `reStructuredText `_ and converted to HTML and PDF formats by `Sphinx `_. 102 | 103 | To submit a documentation change, simply `edit the appropriate file on GitHub `_. (There's an "Edit on GitHub" link in the top-right corner of each page.) 104 | 105 | .. warning:: 106 | 107 | Not all markup is supported by GitHub -- e.g. ``:ref:`` and ``:doc:`` -- so the preview may not be exactly what appears in the online documentation. 108 | 109 | For more comprehensive documentation changes you may be better installing Sphinx so you can test the docs locally: 110 | 111 | 112 | ---------------------------------------- 113 | Installing Sphinx 114 | ---------------------------------------- 115 | 116 | You will need `Python `_ and `pip `_ to install `Sphinx `_, the documentation generator. To install them (on Debian Wheezy or similar), you can run the following: 117 | 118 | .. code-block:: bash 119 | 120 | $ sudo apt-get install python python-pip 121 | $ sudo pip install sphinx sphinx-autobuild sphinx_rtd_theme 122 | 123 | To build the PDF documentation, you will also need LaTeX installed: 124 | 125 | .. code-block:: bash 126 | 127 | $ sudo apt-get install texlive texlive-latex-extra 128 | 129 | 130 | ---------------------------------------- 131 | Building documentation 132 | ---------------------------------------- 133 | 134 | To build the HTML docs (``docs-html/index.html``): 135 | 136 | .. code-block:: bash 137 | 138 | $ ./build-html-docs.sh 139 | 140 | This will build the docs and run a HTML server on port 8000 that will automatically rebuild the docs and reload the page whenever you modify a file. 141 | 142 | To build the PDF docs (``docs-pdf/laravel-breadcrumbs.pdf``): 143 | 144 | .. code-block:: bash 145 | 146 | $ ./build-pdf-docs.sh 147 | 148 | 149 | ---------------------------------------- 150 | Sphinx markup reference 151 | ---------------------------------------- 152 | 153 | I found the following documents useful when writing the documentation: 154 | 155 | - `reStructuredText quick reference `_ 156 | - `Admonitions list `_ (``note::``, ``warning::``, etc.) 157 | - `Code examples markups `_ (``code-block::``, ``highlight::``) 158 | - `Other paragraph-level markup `_ (``versionadded::``, ``deprecated::``, etc.) 159 | - `Inline markup `_ (``:ref:``, ``:doc:``, etc.) 160 | - `Table of contents `_ (``toctree::``) 161 | 162 | 163 | ---------------------------------------- 164 | Heading styles 165 | ---------------------------------------- 166 | 167 | The following code styles are used for headings:: 168 | 169 | ################################################################################ 170 | Page title (80 hashes) 171 | ################################################################################ 172 | 173 | ================================================================================ 174 | Section title (80 equals signs) 175 | ================================================================================ 176 | 177 | ---------------------------------------- 178 | Heading 2 (40 hypens) 179 | ---------------------------------------- 180 | 181 | Heading 3 (full stops) 182 | ...................... 183 | -------------------------------------------------------------------------------- /docs/routing.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Route-Bound Breadcrumbs 3 | ################################################################################ 4 | 5 | In normal usage you must call ``Breadcrumbs::render($name, $params...)`` to render the breadcrumbs on every page. If you prefer, you can name your breadcrumbs the same as your routes and avoid this duplication. 6 | 7 | .. only:: html 8 | 9 | .. contents:: 10 | :local: 11 | 12 | 13 | ================================================================================ 14 | Setup 15 | ================================================================================ 16 | 17 | ---------------------------------------- 18 | Name your routes 19 | ---------------------------------------- 20 | 21 | Make sure each of your routes has a name (``'as'`` parameter). For example (``app/Http/routes.php``): 22 | 23 | .. code-block:: php 24 | 25 | // Home 26 | Route::get('/', ['as' => 'home', 'uses' => 'HomeController@index']); 27 | 28 | // Home > [Page] 29 | Route::get('/page/{id}', ['as' => 'page', 'uses' => 'PageController@show']); 30 | 31 | For more details see `Named Routes `_ in the Laravel documentation. 32 | 33 | 34 | ---------------------------------------- 35 | Name your breadcrumbs to match 36 | ---------------------------------------- 37 | 38 | For each route, create a breadcrumb with the same name. For example (``app/Http/routes.php``): 39 | 40 | .. code-block:: php 41 | 42 | // Home 43 | Breadcrumbs::register('home', function($breadcrumbs) { 44 | $breadcrumbs->push('Home', route('home')); 45 | }); 46 | 47 | // Home > [Page] 48 | Breadcrumbs::register('page', function($breadcrumbs, $id) 49 | { 50 | $page = Page::findOrFail($id); 51 | $breadcrumbs->parent('home'); 52 | $breadcrumbs->push($page->title, route('page', $page->id)); 53 | }); 54 | 55 | 56 | ---------------------------------------- 57 | Output breadcrumbs in your layout 58 | ---------------------------------------- 59 | 60 | Call ``Breadcrumbs::render()`` with no parameters in your layout file (e.g. ``resources/views/app.blade.php``): 61 | 62 | .. code-block:: html+php 63 | 64 | {!! Breadcrumbs::render() !!} 65 | 66 | This will automatically output breadcrumbs corresponding to the current route. 67 | 68 | It will throw an exception if the breadcrumb doesn't exist, to remind you to create one. To prevent this behaviour, change it to: 69 | 70 | .. code-block:: html+php 71 | 72 | {!! Breadcrumbs::renderIfExists() !!} 73 | 74 | 75 | ================================================================================ 76 | Route model binding 77 | ================================================================================ 78 | 79 | Laravel Breadcrumbs uses the same model binding as the controller. For example: 80 | 81 | .. code-block:: php 82 | 83 | // app/Http/routes.php 84 | Route::model('page', 'Page'); 85 | Route::get('/page/{page}', ['uses' => 'PageController@show', 'as' => 'page']); 86 | 87 | .. code-block:: php 88 | 89 | // app/Http/Controllers/PageController.php 90 | class PageController extends Controller { 91 | public function show($page) 92 | { 93 | return view('page/show', ['page' => $page]); 94 | } 95 | } 96 | 97 | .. code-block:: php 98 | 99 | // app/Http/breadcrumbs.php 100 | Breadcrumbs::register('page', function($breadcrumbs, $page) 101 | { 102 | $breadcrumbs->parent('home'); 103 | $breadcrumbs->push($page->title, route('page', $page->id)); 104 | }); 105 | 106 | This makes your code less verbose and more efficient by only loading the page from the database once. 107 | 108 | For more details see `Route Model Binding `_ in the Laravel documentation. 109 | 110 | 111 | ================================================================================ 112 | Resourceful controllers 113 | ================================================================================ 114 | 115 | Laravel automatically creates route names for resourceful controllers, e.g. ``photo.index``, which you can use when defining your breadcrumbs. For example: 116 | 117 | .. code-block:: php 118 | 119 | // app/Http/routes.php 120 | Route::resource('photo', 'PhotoController'); 121 | 122 | .. code-block:: bash 123 | 124 | $ php artisan route:list 125 | +--------+----------+--------------------+---------------+-------------------------+------------+ 126 | | Domain | Method | URI | Name | Action | Middleware | 127 | +--------+----------+--------------------+---------------+-------------------------+------------+ 128 | | | GET|HEAD | photo | photo.index | PhotoController@index | | 129 | | | GET|HEAD | photo/create | photo.create | PhotoController@create | | 130 | | | POST | photo | photo.store | PhotoController@store | | 131 | | | GET|HEAD | photo/{photo} | photo.show | PhotoController@show | | 132 | | | GET|HEAD | photo/{photo}/edit | photo.edit | PhotoController@edit | | 133 | | | PUT | photo/{photo} | photo.update | PhotoController@update | | 134 | | | PATCH | photo/{photo} | | PhotoController@update | | 135 | | | DELETE | photo/{photo} | photo.destroy | PhotoController@destroy | | 136 | +--------+----------+--------------------+---------------+-------------------------+------------+ 137 | 138 | .. code-block:: php 139 | 140 | // app/Http/breadcrumbs.php 141 | 142 | // Photos 143 | Breadcrumbs::register('photo.index', function($breadcrumbs) 144 | { 145 | $breadcrumbs->parent('home'); 146 | $breadcrumbs->push('Photos', route('photo.index')); 147 | }); 148 | 149 | // Photos > Upload Photo 150 | Breadcrumbs::register('photo.create', function($breadcrumbs) 151 | { 152 | $breadcrumbs->parent('photo.index'); 153 | $breadcrumbs->push('Upload Photo', route('photo.create')); 154 | }); 155 | 156 | // Photos > [Photo Name] 157 | Breadcrumbs::register('photo.show', function($breadcrumbs, $photo) 158 | { 159 | $breadcrumbs->parent('photo.index'); 160 | $breadcrumbs->push($photo->title, route('photo.show', $photo->id)); 161 | }); 162 | 163 | // Photos > [Photo Name] > Edit Photo 164 | Breadcrumbs::register('photo.edit', function($breadcrumbs, $photo) 165 | { 166 | $breadcrumbs->parent('photo.show', $photo); 167 | $breadcrumbs->push('Edit Photo', route('photo.edit', $photo->id)); 168 | }); 169 | 170 | For more details see `RESTful Resource Controllers `_ in the Laravel documentation. 171 | 172 | 173 | ================================================================================ 174 | Implicit controllers 175 | ================================================================================ 176 | 177 | Laravel doesn't appear to support named routes in implicit controllers (tested on Laravel 5.0.2), so you will not be able to use them with route-bound breadcrumbs. For example: 178 | 179 | .. code-block:: php 180 | 181 | // app/Http/routes.php 182 | Route::controller('users', 'UserController'); 183 | 184 | .. code-block:: bash 185 | 186 | $ php artisan route:list 187 | +----------+-----------------------------------------+-----------+------------------------------+ 188 | | Method | URI | Name | Action | 189 | +----------+-----------------------------------------+-----------+------------------------------+ 190 | | GET|HEAD | users | | UserController@getIndex | 191 | | GET|HEAD | users/index/{one?}/{two?}/{three?}... | | UserController@getIndex | 192 | | POST | users/profile/{one?}/{two?}/{three?}... | | UserController@postProfile | 193 | +----------+-----------------------------------------+-----------+------------------------------+ 194 | 195 | For more details see `Implicit Controllers `_ in the Laravel documentation. 196 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Laravel Breadcrumbs documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Nov 8 11:14:26 2014. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | import json 19 | 20 | # Custom imports 21 | import re 22 | from datetime import date 23 | 24 | # If extensions (or modules to document with autodoc) are in another directory, 25 | # add these directories to sys.path here. If the directory is relative to the 26 | # documentation root, use os.path.abspath to make it absolute, like shown here. 27 | #sys.path.insert(0, os.path.abspath('.')) 28 | 29 | # -- General configuration ------------------------------------------------ 30 | 31 | # If your documentation needs a minimal Sphinx version, state it here. 32 | #needs_sphinx = '1.0' 33 | 34 | # Add any Sphinx extension module names here, as strings. They can be 35 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 36 | # ones. 37 | extensions = [ 38 | 'sphinx.ext.todo', 39 | ] 40 | 41 | # Add any paths that contain templates here, relative to this directory. 42 | templates_path = [] 43 | 44 | # The suffix of source filenames. 45 | source_suffix = '.rst' 46 | 47 | # The encoding of source files. 48 | #source_encoding = 'utf-8-sig' 49 | 50 | # The master toctree document. 51 | master_doc = 'index' 52 | 53 | # General information about the project. 54 | project = u'Laravel Breadcrumbs' 55 | copyright = u'2013-%d, Dave James Miller' % date.today().year 56 | 57 | # The version info for the project you're documenting, acts as replacement for 58 | # |version| and |release|, also used in various other places throughout the 59 | # built documents. 60 | with open('changelog.rst', 'r') as changelog: 61 | # Determine the version number from the changelog so I don't have to update 62 | # it in two places 63 | match = re.search(r'^ v((\d+)\.\d+\.\d+)_ :(date|future):', changelog.read(), re.MULTILINE) 64 | # The short X.Y version. 65 | version = match.group(2) 66 | # The full version, including alpha/beta/rc tags. 67 | release = match.group(1) 68 | 69 | # The language for content autogenerated by Sphinx. Refer to documentation 70 | # for a list of supported languages. 71 | #language = None 72 | 73 | # There are two options for replacing |today|: either, you set today to some 74 | # non-false value, then it is used: 75 | #today = '' 76 | # Else, today_fmt is used as the format for a strftime call. 77 | today_fmt = '%-d %B %Y' 78 | 79 | # List of patterns, relative to source directory, that match files and 80 | # directories to ignore when looking for source files. 81 | exclude_patterns = [] 82 | 83 | # The reST default role (used for this markup: `text`) to use for all 84 | # documents. 85 | #default_role = None 86 | 87 | # If true, '()' will be appended to :func: etc. cross-reference text. 88 | #add_function_parentheses = True 89 | 90 | # If true, the current module name will be prepended to all description 91 | # unit titles (such as .. function::). 92 | #add_module_names = True 93 | 94 | # If true, sectionauthor and moduleauthor directives will be shown in the 95 | # output. They are ignored by default. 96 | #show_authors = False 97 | 98 | # The name of the Pygments (syntax highlighting) style to use. 99 | pygments_style = 'sphinx' 100 | 101 | # A list of ignored prefixes for module index sorting. 102 | #modindex_common_prefix = [] 103 | 104 | # If true, keep warnings as "system message" paragraphs in the built documents. 105 | #keep_warnings = False 106 | 107 | 108 | # -- Options for HTML output ---------------------------------------------- 109 | 110 | # The theme to use for HTML and HTML Help pages. See the documentation for 111 | # a list of builtin themes. 112 | html_theme = 'default' 113 | 114 | # Theme options are theme-specific and customize the look and feel of a theme 115 | # further. For a list of options available for each theme, see the 116 | # documentation. 117 | #html_theme_options = {} 118 | 119 | # Add any paths that contain custom themes here, relative to this directory. 120 | #html_theme_path = [] 121 | 122 | # The name for this set of Sphinx documents. If None, it defaults to 123 | # " v documentation". 124 | #html_title = None 125 | 126 | # A shorter title for the navigation bar. Default is the same as html_title. 127 | #html_short_title = None 128 | 129 | # The name of an image file (relative to this directory) to place at the top 130 | # of the sidebar. 131 | #html_logo = None 132 | 133 | # The name of an image file (within the static path) to use as favicon of the 134 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 135 | # pixels large. 136 | #html_favicon = None 137 | 138 | # Add any paths that contain custom static files (such as style sheets) here, 139 | # relative to this directory. They are copied after the builtin static files, 140 | # so a file named "default.css" will overwrite the builtin "default.css". 141 | html_static_path = [] 142 | 143 | # Add any extra paths that contain custom files (such as robots.txt or 144 | # .htaccess) here, relative to this directory. These files are copied 145 | # directly to the root of the documentation. 146 | #html_extra_path = [] 147 | 148 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 149 | # using the given strftime format. 150 | #html_last_updated_fmt = '%b %d, %Y' 151 | 152 | # If true, SmartyPants will be used to convert quotes and dashes to 153 | # typographically correct entities. 154 | #html_use_smartypants = True 155 | 156 | # Custom sidebar templates, maps document names to template names. 157 | #html_sidebars = {} 158 | 159 | # Additional templates that should be rendered to pages, maps page names to 160 | # template names. 161 | #html_additional_pages = {} 162 | 163 | # If false, no module index is generated. 164 | #html_domain_indices = True 165 | 166 | # If false, no index is generated. 167 | #html_use_index = True 168 | 169 | # If true, the index is split into individual pages for each letter. 170 | #html_split_index = False 171 | 172 | # If true, links to the reST sources are added to the pages. 173 | #html_show_sourcelink = True 174 | 175 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 176 | #html_show_sphinx = True 177 | 178 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 179 | #html_show_copyright = True 180 | 181 | # If true, an OpenSearch description file will be output, and all pages will 182 | # contain a tag referring to it. The value of this option must be the 183 | # base URL from which the finished HTML is served. 184 | #html_use_opensearch = '' 185 | 186 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 187 | #html_file_suffix = None 188 | 189 | # Output file base name for HTML help builder. 190 | htmlhelp_basename = 'LaravelBreadcrumbsdoc' 191 | 192 | 193 | # -- Options for LaTeX output --------------------------------------------- 194 | 195 | latex_elements = { 196 | # The paper size ('letterpaper' or 'a4paper'). 197 | #'papersize': 'letterpaper', 198 | 199 | # The font size ('10pt', '11pt' or '12pt'). 200 | #'pointsize': '10pt', 201 | 202 | # Additional stuff for the LaTeX preamble. 203 | 'preamble': '\n'.join(( 204 | # Fix the unicode characters in the file tree diagrams 205 | r'\DeclareUnicodeCharacter{251C}{+}', # BOX DRAWINGS LIGHT VERTICAL AND RIGHT 206 | r'\DeclareUnicodeCharacter{2514}{+}', # BOX DRAWINGS LIGHT UP AND RIGHT 207 | r'\DeclareUnicodeCharacter{00A0}{ }', # NO-BREAK SPACE 208 | 209 | # Fix "! Undefined control sequence. \node@class@name" error when using ".. role" 210 | # Based on https://bitbucket.org/birkenfeld/sphinx/issue/1564/custom-roles-are-not-properly-translated 211 | # (I couldn't get the patches suggested in that issue to work either!) 212 | r'\renewcommand{\DUspan}[2]{#2}', 213 | )), 214 | } 215 | 216 | # Grouping the document tree into LaTeX files. List of tuples 217 | # (source start file, target name, title, 218 | # author, documentclass [howto, manual, or own class]). 219 | latex_documents = [ 220 | ('index', 'laravel-breadcrumbs.tex', u'Laravel Breadcrumbs Documentation', 221 | u'Dave James Miller', 'manual'), 222 | ] 223 | 224 | # The name of an image file (relative to this directory) to place at the top of 225 | # the title page. 226 | #latex_logo = None 227 | 228 | # For "manual" documents, if this is true, then toplevel headings are parts, 229 | # not chapters. 230 | #latex_use_parts = False 231 | 232 | # If true, show page references after internal links. 233 | latex_show_pagerefs = True 234 | 235 | # If true, show URL addresses after external links. 236 | latex_show_urls = 'footnote' 237 | 238 | # Documents to append as an appendix to all manuals. 239 | #latex_appendices = [] 240 | 241 | # If false, no module index is generated. 242 | #latex_domain_indices = True 243 | 244 | 245 | # -- Options for manual page output --------------------------------------- 246 | 247 | # One entry per manual page. List of tuples 248 | # (source start file, name, description, authors, manual section). 249 | man_pages = [ 250 | ('index', 'laravel-breadcrumbs', u'Laravel Breadcrumbs Documentation', 251 | [u'Dave James Miller'], 1) 252 | ] 253 | 254 | # If true, show URL addresses after external links. 255 | #man_show_urls = False 256 | 257 | 258 | # -- Options for Texinfo output ------------------------------------------- 259 | 260 | # Grouping the document tree into Texinfo files. List of tuples 261 | # (source start file, target name, title, author, 262 | # dir menu entry, description, category) 263 | texinfo_documents = [ 264 | ('index', 'laravel-breadcrumbs', u'Laravel Breadcrumbs Documentation', 265 | u'Dave James Miller', 'Laravel Breadcrumbs', 'One line description of project.', 266 | 'Miscellaneous'), 267 | ] 268 | 269 | # Documents to append as an appendix to all manuals. 270 | #texinfo_appendices = [] 271 | 272 | # If false, no module index is generated. 273 | #texinfo_domain_indices = True 274 | 275 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 276 | #texinfo_show_urls = 'footnote' 277 | 278 | # If true, do not generate a @detailmenu in the "Top" node's menu. 279 | #texinfo_no_detailmenu = False 280 | 281 | 282 | # -- Custom options ------------------------------------------------------- 283 | 284 | # Default to plain text blocks 285 | highlight_language = 'none' 286 | 287 | # Custom CSS 288 | html_static_path = ['_static'] 289 | 290 | def setup(app): 291 | app.add_stylesheet('custom.css') 292 | 293 | # Only when run locally (not on Read The Docs): 294 | if os.environ.get('READTHEDOCS', None) != 'True': 295 | 296 | # Read The Docs theme 297 | # http://read-the-docs.readthedocs.org/en/latest/theme.html 298 | import sphinx_rtd_theme 299 | html_theme = 'sphinx_rtd_theme' 300 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 301 | 302 | # Show TODO items 303 | todo_include_todos = True 304 | 305 | # Show a link to the online docs in the index page 306 | tags.add('local') 307 | 308 | # Enable highlighting for PHP code not between ```` by default 309 | # https://github.com/fabpot/sphinx-php 310 | from sphinx.highlighting import lexers 311 | from pygments.lexers.web import PhpLexer 312 | 313 | lexers['php'] = PhpLexer(startinline=True) 314 | lexers['php-annotations'] = PhpLexer(startinline=True) 315 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | Changelog 3 | ################################################################################ 4 | 5 | .. role:: date 6 | :class: changelog-date 7 | 8 | .. role:: future 9 | :class: changelog-future 10 | 11 | .. role:: strikethrough 12 | :class: strikethrough 13 | 14 | 15 | Laravel Breadcrumbs uses `Semantic Versioning `_. 16 | 17 | 18 | .. ================================================================================ 19 | .. v3.0.1_ :future:`(Unreleased)` 20 | .. ================================================================================ 21 | 22 | 23 | ================================================================================ 24 | v3.0.0_ :date:`(8 Feb 2015)` 25 | ================================================================================ 26 | 27 | - Add Laravel 5 support (`#62`_) 28 | - Change view namespace from ``laravel-breadcrumbs::`` to ``breadcrumbs::`` 29 | - Change Bootstrap 3 template from ``
      `` to ``
        `` to match the `documentation `_ 30 | - Move documentation from GitHub (Markdown) to `Read The Docs `_ (reStructuredText/`Sphinx `_) 31 | - Greatly improve unit & integration tests (largely thanks to `Testbench `_) 32 | - Fix issue that prevented non-deferred service providers referencing Breadcrumbs (`#39`_) by making Breadcrumbs non-deferred also 33 | - Rename ``generateArrayIfExists()`` to ``generateIfExistsArray()`` 34 | - Rename ``renderArrayIfExists()`` to ``renderIfExistsArray()`` 35 | - Remove ``$breadcrumbs->get()`` and ``$breadcrumbs->set()`` methods from Generator class (they were never used nor documented) 36 | - Remove ``Breadcrumbs::getView()`` 37 | - Switch from PSR-0 to PSR-4 file naming 38 | 39 | .. _v3.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/3.0.0 40 | .. _#39: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/39 41 | .. _#62: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/62 42 | 43 | 44 | ---------------------------------------- 45 | Upgrading from 2.x to 3.x 46 | ---------------------------------------- 47 | 48 | - `Upgrade to Laravel 5 `_ 49 | - Move ``app/breadcrumbs.php`` to ``app/Http/breadcrumbs.php`` 50 | - Move ``app/config/packages/davejamesmiller/laravel-breadcrumbs/config.php`` to ``config/breadcrumbs.php`` (if used) 51 | 52 | The following changes are optional because there are shims in place: 53 | 54 | - In the config file, replace ``laravel-breadcrumbs::`` with ``breadcrumbs::`` 55 | - Replace any calls to ``Breadcrumbs::generateArrayIfExists()`` with ``Breadcrumbs::generateIfExistsArray()`` 56 | - Replace any calls to ``Breadcrumbs::renderArrayIfExists()`` with ``Breadcrumbs::renderIfExistsArray()`` 57 | 58 | .. note:: 59 | 60 | Laravel 4 and PHP 5.3 are no longer supported -- please continue to use the `2.x branch `_ if you use them. 61 | 62 | 63 | ================================================================================ 64 | v2.3.1_ :date:`(8 Feb 2015)` 65 | ================================================================================ 66 | 67 | - Fix issue that prevented non-deferred service providers referencing Breadcrumbs (`#39`_) by making Breadcrumbs non-deferred also (backported from 3.0.0) 68 | 69 | .. _v2.3.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/3.0.0 70 | 71 | 72 | ================================================================================ 73 | v2.3.0_ :date:`(26 Oct 2014)` 74 | ================================================================================ 75 | 76 | - Add ``$data`` parameter to ``$breadcrumb->push()`` to allow for arbitrary data (`#34`_, `#35`_, `#55`_, `#56`_) 77 | 78 | .. _v2.3.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.3.0 79 | .. _#34: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/34 80 | .. _#35: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/35 81 | .. _#55: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/55 82 | .. _#56: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/56 83 | .. _3a0afc2: https://github.com/laravel/framework/commit/3a0afc20f25ad3bed640ff1a14957f972d123cf7 84 | 85 | 86 | ================================================================================ 87 | v2.2.3_ :date:`(10 Sep 2014)` 88 | ================================================================================ 89 | 90 | - Fix ``Breadcrumbs::generate()`` with no parameters so it uses the current route, like ``Breadcrumbs::render()`` does (`#46`_) 91 | 92 | .. _v2.2.3: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.3 93 | .. _#46: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/46 94 | 95 | 96 | ================================================================================ 97 | v2.2.2_ :date:`(3 Aug 2014)` 98 | ================================================================================ 99 | 100 | - Support for Laravel's ``App::missing()`` method when using automatic route detection (`#40`_, `#41`_) 101 | 102 | .. _v2.2.2: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.2 103 | .. _#40: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/40 104 | .. _#41: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/41 105 | 106 | 107 | ================================================================================ 108 | v2.2.1_ :date:`(19 May 2014)` 109 | ================================================================================ 110 | 111 | - Laravel 4.2 support (`#21`_, `#28`_) 112 | 113 | .. _v2.2.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.1 114 | .. _#21: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/21 115 | .. _#28: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/28 116 | 117 | 118 | ================================================================================ 119 | v2.2.0_ :date:`(26 Jan 2014)` 120 | ================================================================================ 121 | 122 | - Add ``Breadcrumbs::exists()``, ``renderIfExists()``, ``renderArrayIfExists()`` (`#22`_) 123 | - Use the current route name & parameters by default so you don't have to specify them in the view (as long as you use consistent names) (`#16`_, `#24`_) 124 | 125 | .. _v2.2.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.0 126 | .. _#16: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/16 127 | .. _#22: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/22 128 | .. _#24: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/24 129 | 130 | 131 | ================================================================================ 132 | v2.1.0_ :date:`(16 Oct 2013)` 133 | ================================================================================ 134 | 135 | - Add support for non-linked breadcrumbs to the Twitter Bootstrap templates (`#20`_) 136 | 137 | .. _v2.1.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.1.0 138 | .. _#20: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/20 139 | 140 | 141 | ================================================================================ 142 | v2.0.0_ :date:`(28 Sep 2013)` 143 | ================================================================================ 144 | 145 | - Add Twitter Bootstrap v3 template (`#7`_) 146 | - Twitter Bootstrap v3 is now the default template 147 | - Support for passing arrays into ``render()``, ``generate()`` and ``parent()`` (**not backwards-compatible**) (`#8`_) 148 | 149 | - Split ``Breadcrumbs::render()`` into ``render($name, $arg1, $arg2)`` and ``renderArray($name, $params)`` 150 | - Split ``Breadcrumbs::generate()`` into ``generate($name, $arg1, $arg2)`` and ``generateArray($name, $params)`` 151 | - Split ``$breadcrumbs->parent()`` into ``parent($name, $arg1, $arg2)`` and ``parentArray($name, $params)`` 152 | 153 | - Set view name in config file instead of in ``breadcrumbs.php`` (`#10`_, `#11`_) 154 | - Simplify class names (`#15`_) 155 | - Add unit tests 156 | 157 | .. _v2.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.0.0 158 | .. _#7: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/7 159 | .. _#8: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/8 160 | .. _#10: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/10 161 | .. _#11: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/11 162 | .. _#15: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/15 163 | 164 | 165 | ---------------------------------------- 166 | Upgrading from 1.x to 2.x 167 | ---------------------------------------- 168 | 169 | - In ``app/config/app.php`` change ``DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider`` to ``DaveJamesMiller\Breadcrumbs\ServiceProvider`` 170 | - In ``app/config/app.php`` change ``DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs`` to ``DaveJamesMiller\Breadcrumbs\Facade`` 171 | - The default template was changed from Bootstrap 2 to Bootstrap 3. See :ref:`Choose a template ` if you need to switch it back. 172 | 173 | The following internal changes will not affect most people but if you have any problems please be aware of the following: 174 | 175 | - The view namespace was changed from ``breadcrumbs`` to ``laravel-breadcrumbs`` to match the Composer project name. 176 | - The Bootstrap 2 template name was changed from ``breadcrumbs::bootstrap`` to ``laravel-breadcrumbs::bootstrap2``. 177 | - If you pass arrays into any of the methods, please read the following section: 178 | 179 | 180 | Passing arrays into ``render()``, ``generate()`` and ``parent()`` 181 | ................................................................. 182 | 183 | In **version 1.x** you could pass an array into each of these methods and it was split up into several parameters. For example: 184 | 185 | .. code-block:: php 186 | 187 | // If this breadcrumb is defined: 188 | Breadcrumbs::register('page', function($breadcrumbs, $param1, $param2) 189 | { 190 | $breadcrumbs->push($param1, $param2); 191 | }); 192 | 193 | // Then this: 194 | Breadcrumbs::render('page', ['param1', 'param2']); 195 | 196 | // Was equivalent to this: 197 | Breadcrumbs::render('page', 'param1', 'param2'); 198 | 199 | // But to pass an array as the first parameter you would have to do this instead: 200 | Breadcrumbs::render('page', [['param1A', 'param1B']]); 201 | 202 | This means you couldn't pass an array as the first parameter unless you wrapped all parameters in another array (issue `#8`_). 203 | 204 | In **version 2.x** this has been split into two methods: 205 | 206 | .. code-block:: php 207 | 208 | // Now this: 209 | Breadcrumbs::renderArray('page', ['param1', 'param2']); 210 | 211 | // Is equivalent to this: 212 | Breadcrumbs::render('page', 'param1', 'param2'); 213 | 214 | // And this only passes a single parameter (an array) to the callback: 215 | Breadcrumbs::render('page', ['param1A', 'param1B']); 216 | 217 | Similarly ``Breadcrumbs::generateArray()`` and ``$breadcrumbs->parentArray()`` methods are available, which take a single array argument. 218 | 219 | 220 | ================================================================================ 221 | v1.0.1_ :date:`(13 Jul 2013)` 222 | ================================================================================ 223 | 224 | - Fix for PHP 5.3 compatibility (`#3`_) 225 | 226 | .. _v1.0.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/1.0.1 227 | .. _#3: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/3 228 | 229 | 230 | ================================================================================ 231 | v1.0.0_ :date:`(25 May 2013)` 232 | ================================================================================ 233 | 234 | .. _v1.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/1.0.0 235 | 236 | - Initial release 237 | -------------------------------------------------------------------------------- /tests/unit/ManagerTest.php: -------------------------------------------------------------------------------- 1 | currentRoute = m::mock('DaveJamesMiller\Breadcrumbs\CurrentRoute'); 13 | $this->generator = m::mock('DaveJamesMiller\Breadcrumbs\Generator'); 14 | $this->view = m::mock('DaveJamesMiller\Breadcrumbs\View'); 15 | $this->manager = new Manager($this->currentRoute, $this->generator, $this->view); 16 | 17 | $this->manager->setView('view'); 18 | } 19 | 20 | // Breadcrumbs::register($name, $callback) is tested by other methods 21 | protected function register($name) 22 | { 23 | $this->manager->register($name, $fn = function() { 24 | // We're not testing whether the callbacks are executed - see GeneratorTest 25 | throw new Exception('Callback executed'); 26 | }); 27 | 28 | return $fn; 29 | } 30 | 31 | // Breadcrumbs::exists() -> boolean 32 | public function testExists() 33 | { 34 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 35 | 36 | $this->assertFalse($this->manager->exists()); 37 | 38 | $this->register('sample'); 39 | $this->assertTrue($this->manager->exists()); 40 | } 41 | 42 | // Breadcrumbs::exists($name) -> boolean 43 | public function testExists_name() 44 | { 45 | $this->assertFalse($this->manager->exists('sample')); 46 | 47 | $this->register('sample'); 48 | $this->assertTrue($this->manager->exists('sample')); 49 | } 50 | 51 | // Breadcrumbs::generate() -> array 52 | public function testGenerate() 53 | { 54 | $fn = $this->register('sample'); 55 | 56 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 57 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 58 | 59 | $this->assertSame('generated', $this->manager->generate()); 60 | } 61 | 62 | // Breadcrumbs::generate($name) -> array 63 | public function testGenerate_name() 64 | { 65 | $fn = $this->register('sample'); 66 | 67 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');; 68 | 69 | $this->assertSame('generated', $this->manager->generate('sample')); 70 | } 71 | 72 | // Breadcrumbs::generate($name, $param1, ...) -> array 73 | public function testGenerate_name_params() 74 | { 75 | $fn = $this->register('sample'); 76 | 77 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 78 | 79 | $this->assertSame('generated', $this->manager->generate('sample', 1, 'blah')); 80 | } 81 | 82 | // Breadcrumbs::generateArray($name, $params) -> array 83 | public function testGenerateArray_name_params() 84 | { 85 | $fn = $this->register('sample'); 86 | 87 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 88 | 89 | $this->assertSame('generated', $this->manager->generateArray('sample', [1, 'blah'])); 90 | } 91 | 92 | // Breadcrumbs::generateIfExists() -> array 93 | public function testGenerateIfExists_existing() 94 | { 95 | $fn = $this->register('sample'); 96 | 97 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 98 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 99 | 100 | $this->assertSame('generated', $this->manager->generateIfExists()); 101 | } 102 | 103 | public function testGenerateIfExists_nonexistant() 104 | { 105 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 106 | $this->generator->shouldReceive('generate')->never(); 107 | 108 | $this->assertSame([], $this->manager->generateIfExists()); 109 | } 110 | 111 | // Breadcrumbs::generateIfExists($name) -> array 112 | public function testGenerateIfExists_name_existing() 113 | { 114 | $fn = $this->register('sample'); 115 | 116 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated'); 117 | 118 | $this->assertSame('generated', $this->manager->generateIfExists('sample')); 119 | } 120 | 121 | public function testGenerateIfExists_name_nonexistant() 122 | { 123 | $this->generator->shouldReceive('generate')->never(); 124 | 125 | $this->assertSame([], $this->manager->generateIfExists('sample')); 126 | } 127 | 128 | // Breadcrumbs::generateIfExists($name, $param1, ...) -> array 129 | public function testGenerateIfExists_name_params_existing() 130 | { 131 | $fn = $this->register('sample'); 132 | 133 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 134 | 135 | $this->assertSame('generated', $this->manager->generateIfExists('sample', 1, 'blah')); 136 | } 137 | 138 | public function testGenerateIfExists_name_params_nonexistant() 139 | { 140 | $this->generator->shouldReceive('generate')->never(); 141 | 142 | $this->assertSame([], $this->manager->generateIfExists('sample', 1, 'blah')); 143 | } 144 | 145 | // Breadcrumbs::generateArrayIfExists($name, $params) -> array 146 | public function testGenerateArrayIfExists_name_params_existing() 147 | { 148 | $fn = $this->register('sample'); 149 | 150 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 151 | 152 | $this->assertSame('generated', $this->manager->generateArrayIfExists('sample', [1, 'blah'])); 153 | } 154 | 155 | public function testGenerateArrayIfExists_name_params_nonexistant() 156 | { 157 | $this->generator->shouldReceive('generate')->never(); 158 | 159 | $this->assertSame([], $this->manager->generateArrayIfExists('sample', [1, 'blah'])); 160 | } 161 | 162 | // Breadcrumbs::render() -> array 163 | public function testRender() 164 | { 165 | $fn = $this->register('sample'); 166 | 167 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 168 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 169 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 170 | 171 | $this->assertSame('rendered', $this->manager->render()); 172 | } 173 | 174 | // Breadcrumbs::render($name) -> array 175 | public function testRender_name() 176 | { 177 | $fn = $this->register('sample'); 178 | 179 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');; 180 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 181 | 182 | $this->assertSame('rendered', $this->manager->render('sample')); 183 | } 184 | 185 | // Breadcrumbs::render($name, $param1, ...) -> array 186 | public function testRender_name_params() 187 | { 188 | $fn = $this->register('sample'); 189 | 190 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 191 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 192 | 193 | $this->assertSame('rendered', $this->manager->render('sample', 1, 'blah')); 194 | } 195 | 196 | // Breadcrumbs::renderArray($name, $params) -> array 197 | public function testRenderArray_name_params() 198 | { 199 | $fn = $this->register('sample'); 200 | 201 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 202 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 203 | 204 | $this->assertSame('rendered', $this->manager->renderArray('sample', [1, 'blah'])); 205 | } 206 | 207 | // Breadcrumbs::renderIfExists() -> array 208 | public function testRenderIfExists_existing() 209 | { 210 | $fn = $this->register('sample'); 211 | 212 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 213 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 214 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 215 | 216 | $this->assertSame('rendered', $this->manager->renderIfExists()); 217 | } 218 | 219 | public function testRenderIfExists_nonexistant() 220 | { 221 | $this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]); 222 | $this->generator->shouldReceive('generate')->never(); 223 | $this->view->shouldReceive('render')->never(); 224 | 225 | $this->assertSame('', $this->manager->renderIfExists()); 226 | } 227 | 228 | // Breadcrumbs::renderIfExists($name) -> array 229 | public function testRenderIfExists_name_existing() 230 | { 231 | $fn = $this->register('sample'); 232 | 233 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated'); 234 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 235 | 236 | $this->assertSame('rendered', $this->manager->renderIfExists('sample')); 237 | } 238 | 239 | public function testRenderIfExists_name_nonexistant() 240 | { 241 | $this->generator->shouldReceive('generate')->never(); 242 | $this->view->shouldReceive('render')->never(); 243 | 244 | $this->assertSame('', $this->manager->renderIfExists('sample')); 245 | } 246 | 247 | // Breadcrumbs::renderIfExists($name, $param1, ...) -> array 248 | public function testRenderIfExists_name_params_existing() 249 | { 250 | $fn = $this->register('sample'); 251 | 252 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 253 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 254 | 255 | $this->assertSame('rendered', $this->manager->renderIfExists('sample', 1, 'blah')); 256 | } 257 | 258 | public function testRenderIfExists_name_params_nonexistant() 259 | { 260 | $this->generator->shouldReceive('generate')->never(); 261 | $this->view->shouldReceive('render')->never(); 262 | 263 | $this->assertSame('', $this->manager->renderIfExists('sample', 1, 'blah')); 264 | } 265 | 266 | // Breadcrumbs::renderArrayIfExists($name, $params) -> array 267 | public function testRenderArrayIfExists_name_params_existing() 268 | { 269 | $fn = $this->register('sample'); 270 | 271 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated'); 272 | $this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered'); 273 | 274 | $this->assertSame('rendered', $this->manager->renderArrayIfExists('sample', [1, 'blah'])); 275 | } 276 | 277 | public function testRenderArrayIfExists_name_params_nonexistant() 278 | { 279 | $this->generator->shouldReceive('generate')->never(); 280 | $this->view->shouldReceive('render')->never(); 281 | 282 | $this->assertSame('', $this->manager->renderArrayIfExists('sample', [1, 'blah'])); 283 | } 284 | 285 | // Breadcrumbs::setCurrentRoute($name) 286 | public function testSetCurrentRoute_name() 287 | { 288 | $this->currentRoute->shouldReceive('set')->with('sample', [])->once(); 289 | 290 | $this->manager->setCurrentRoute('sample'); 291 | } 292 | 293 | // Breadcrumbs::setCurrentRoute($name, $param1, ...) 294 | public function testSetCurrentRoute_name_params() 295 | { 296 | $this->currentRoute->shouldReceive('set')->with('sample', [1, 'blah'])->once(); 297 | 298 | $this->manager->setCurrentRoute('sample', 1, 'blah'); 299 | } 300 | 301 | // Breadcrumbs::setCurrentRouteArray($name, $params) 302 | public function testSetCurrentRouteArray_name_params() 303 | { 304 | $this->currentRoute->shouldReceive('set')->with('sample', [1, 'blah'])->once(); 305 | 306 | $this->manager->setCurrentRouteArray('sample', [1, 'blah']); 307 | } 308 | 309 | // Breadcrumbs::clearCurrentRoute() 310 | public function testClearCurrentRoute() 311 | { 312 | $this->currentRoute->shouldReceive('clear')->withNoArgs()->once(); 313 | 314 | $this->manager->clearCurrentRoute(); 315 | } 316 | 317 | // Breadcrumbs::setView($view) 318 | public function testSetView() 319 | { 320 | $fn = $this->register('sample'); 321 | 322 | $this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');; 323 | $this->view->shouldReceive('render')->with('custom.view', 'generated')->once()->andReturn('rendered'); 324 | 325 | $this->manager->setView($view = 'custom.view'); 326 | $this->assertSame('rendered', $this->manager->render('sample', 1, 'blah')); 327 | } 328 | 329 | } 330 | --------------------------------------------------------------------------------