update v 1.0.7.5

This commit is contained in:
Sujit Prasad
2016-06-13 20:41:55 +05:30
parent aa9786d829
commit 283d97e3ea
5078 changed files with 339851 additions and 175995 deletions

View File

@@ -0,0 +1 @@
service_name: travis-ci

View File

@@ -0,0 +1,15 @@
# http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
[*.yml]
indent_size = 2
indent_style = space

View File

@@ -0,0 +1,14 @@
# PHP packages
/vendor
composer.phar
composer.lock
# Compiled documentation (run `grunt docs` for HTML; `grunt pdfdocs` for PDF)
/docs-html/
/docs-pdf/
# Test coverage output
/test-coverage/
# Operating system files
.DS_Store

View File

@@ -0,0 +1,17 @@
language: php
php:
- 5.6
- 5.5
- 5.4
- hhvm
install:
- composer self-update # https://github.com/phpspec/prophecy/issues/149
- travis_retry composer install --no-interaction --prefer-source
script:
- phpunit --coverage-clover build/logs/clover.xml
after_script:
- php vendor/bin/coveralls -v

View File

@@ -0,0 +1,36 @@
################################################################################
Support & Contribution Guidelines
################################################################################
.. This file is for GitHub (https://github.com/blog/1184-contributing-guidelines)
Please submit support requests, bug reports, feature requests and pull requests using `GitHub issues <https://github.com/davejamesmiller/laravel-breadcrumbs/issues>`_.
All **support requests / bug reports** should include the following:
- The complete error message, including file & line numbers
- Steps to reproduce the problem
- Laravel Breadcrumbs version
- Laravel version
- PHP version
You should also include copies of the following where appropriate:
- ``app/Http/breadcrumbs.php``
- ``config/breadcrumbs.php`` (if used)
- The view or layout that outputs the breadcrumbs
- The custom breadcrumbs template (if applicable)
- 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
- Any other relevant files
**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 <http://laravel-breadcrumbs.davejamesmiller.com/en/latest/>`_ carefully.
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.
.. This text is also in docs/contributing.rst
If you want to submit a **bug fix**, please make your changes in a new branch (based on the ``develop`` branch), then open a `pull request <https://github.com/davejamesmiller/laravel-breadcrumbs/pulls>`_. (The `Contributing page of the docs <http://laravel-breadcrumbs.davejamesmiller.com/en/latest/contributing.html>`_ may help you to get started if you've not done this before.)
.. This text is also in docs/contributing.rst
If you want to submit a **new feature**, it's usually best to open an `issue <https://github.com/davejamesmiller/laravel-breadcrumbs/issues>`_ 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.
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.)

View File

@@ -0,0 +1,19 @@
# Laravel Breadcrumbs 3
[![Latest Stable Version](https://poser.pugx.org/davejamesmiller/laravel-breadcrumbs/v/stable.png)](https://packagist.org/packages/davejamesmiller/laravel-breadcrumbs)
[![Total Downloads](https://img.shields.io/packagist/dt/davejamesmiller/laravel-breadcrumbs.svg?style=flat)](https://packagist.org/packages/davejamesmiller/laravel-breadcrumbs)
[![Reference Status](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/reference_badge.svg?style=flat)](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/references)<br>
[![Build Status](https://img.shields.io/travis/davejamesmiller/laravel-breadcrumbs/master.svg?style=flat)](https://travis-ci.org/davejamesmiller/laravel-breadcrumbs)
[![Coverage Status](https://img.shields.io/coveralls/davejamesmiller/laravel-breadcrumbs.png)](https://coveralls.io/r/davejamesmiller/laravel-breadcrumbs)
[![Dependency Status](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs/badge.svg)](https://www.versioneye.com/php/davejamesmiller:laravel-breadcrumbs)
A simple Laravel-style way to create breadcrumbs in [Laravel 5](http://laravel.com/).
**[Documentation >>](http://laravel-breadcrumbs.davejamesmiller.com/)**
[Support & Contribution Guidelines](CONTRIBUTING.rst)
[MIT License](docs/license.rst)
--------------------------------------------------------------------------------
*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.*

View File

@@ -0,0 +1,8 @@
# Release Checklist
- [ ] Ensure the documentation is up to date, particularly the changelog
- [ ] Merge the `develop` branch into the `master` branch (`git checkout master; git merge develop`)
- [ ] Push the code changes to GitHub (`git push`)
- [ ] Double-check the [Travis CI results](https://travis-ci.org/davejamesmiller/laravel-breadcrumbs)
- [ ] Tag the release (`git tag 1.2.3`)
- [ ] Push the tag (`git push --tag`)

View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -eu
cd $(dirname $0)
rm -rf docs-html/
sphinx-build docs/ docs-html/
sphinx-autobuild -H 0.0.0.0 docs/ docs-html/

View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -eu
cd $(dirname $0)
rm -rf docs-pdf/
sphinx-build -b latex docs/ docs-pdf/
make -C docs-pdf/ all-pdf

View File

@@ -0,0 +1,32 @@
{
"name": "davejamesmiller/laravel-breadcrumbs",
"description": "A simple Laravel-style way to create breadcrumbs in Laravel 4+.",
"keywords": [
"laravel"
],
"homepage": "https://github.com/davejamesmiller/laravel-breadcrumbs",
"authors": [
{
"name": "Dave James Miller",
"email": "dave@davejamesmiller.com",
"homepage": "http://davejamesmiller.com/"
}
],
"license": "MIT License",
"require": {
"php": ">=5.4.0",
"illuminate/support": "5.*",
"illuminate/view": "5.*"
},
"require-dev": {
"mockery/mockery": "0.9.*",
"orchestra/testbench": "3.0.*",
"phpunit/phpunit": "4.*",
"satooshi/php-coveralls": "0.6.*"
},
"autoload": {
"psr-4": {
"DaveJamesMiller\\Breadcrumbs\\": "src/"
}
}
}

View File

@@ -0,0 +1,7 @@
<?php
return [
'view' => 'breadcrumbs::bootstrap3',
];

View File

@@ -0,0 +1,6 @@
# 4 space indents in ReST because that's what we want for most code examples
# and if we use tabs it defaults to 8 (and isn't easy to change)
# http://stackoverflow.com/questions/1686837
[*]
indent_size = 4
indent_style = space

View File

@@ -0,0 +1,26 @@
/* Make sections stand out more */
h2 {
border-top: 1px solid #e1e4e5;
padding-top: 24px;
}
h1 + .section > h2:first-child {
border-top: none;
padding-top: 0;
}
/* Changelog styles */
.changelog-date {
font-size: 70%;
}
.changelog-future {
color: #b65a5a;
font-size: 70%;
font-style: italic;
font-weight: bold;
}
.strikethrough {
text-decoration: line-through;
}

View File

@@ -0,0 +1,133 @@
################################################################################
Advanced Usage
################################################################################
.. only:: html
.. contents::
:local:
.. _no-url:
================================================================================
Breadcrumbs with no URL
================================================================================
The second parameter to ``push()`` is optional, so if you want a breadcrumb with no URL you can do so:
.. code-block:: php
$breadcrumbs->push('Sample');
The ``$breadcrumb->url`` value will be ``null``.
The default Twitter Bootstrap templates provided render this with a CSS class of "active", the same as the last breadcrumb, because otherwise they default to black text not grey which doesn't look right.
*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.*
.. _custom-data:
================================================================================
Custom data
================================================================================
*Added in 2.3.0.*
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:
.. code-block:: php
$breadcrumbs->push('Home', '/', ['icon' => 'home.png']);
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:
.. code-block:: html+php
<li><a href="{{{ $breadcrumb->url }}}">
<img src="/images/icons/{{{ $breadcrumb->icon }}}">
{{{ $breadcrumb->title }}}
</a></li>
Do not use the following keys in your data array, as they will be overwritten: ``title``, ``url``, ``first``, ``last``.
================================================================================
Defining breadcrumbs in a different file
================================================================================
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.
.. _switching-views:
================================================================================
Switching views dynamically
================================================================================
You can change the view at runtime by calling:
.. code-block:: php
Breadcrumbs::setView('view.name');
Or you can call ``Breadcrumbs::generate()`` and then load the view manually:
.. code-block:: html+php
@include('_partials/breadcrumbs2', ['breadcrumbs' => Breadcrumbs::generate('category', $category)])
.. _current-route:
================================================================================
Overriding the "current" route
================================================================================
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).
You can override this by calling ``Breadcrumbs::setCurrentRoute($name, $param1, $param2...)`` or ``Breadcrumbs::setCurrentRouteArray($name, $params)``.
.. _array-parameters:
================================================================================
Passing an array of parameters
================================================================================
*Added in 2.0.0.*
If the breadcrumb requires multiple parameters, you would normally pass them like this:
.. code-block:: php
Breadcrumbs::render('name', $param1, $param2, $param3);
Breadcrumbs::generate('name', $param1, $param2, $param3);
$breadcrumbs->parent('name', $param1, $param2, $param3);
If you want to pass an array of parameters instead you can use these methods:
.. code-block:: php
Breadcrumbs::renderArray('name', $params);
Breadcrumbs::generateArray('name', $params);
$breadcrumbs->parentArray('name', $params);
.. _exists:
================================================================================
Checking if a breadcrumb exists
================================================================================
*Added in 2.2.0.*
By default an exception will be thrown if the breadcrumb doesn't exist, so you know to add it. If you want suppress this you can call the following methods instead:
- ``Breadcrumbs::renderIfExists()`` (returns an empty string)
- ``Breadcrumbs::renderArrayIfExists()`` (returns an empty string)
- ``Breadcrumbs::generateIfExists()`` (returns an empty array)
- ``Breadcrumbs::generateArrayIfExists()`` (returns an empty array)
Alternatively you can call ``Breadcrumbs::exists('name')``, which returns a boolean.

View File

@@ -0,0 +1,86 @@
################################################################################
API Reference
################################################################################
.. only:: html
.. contents::
:local:
================================================================================
``Breadcrumbs`` Facade
================================================================================
======================================================== ========== ========== ============================
Method Returns Added in Docs
======================================================== ========== ========== ============================
``Breadcrumbs::register($name, $callback)`` *(none)* 1.0.0 :doc:`Defining <defining>`
``Breadcrumbs::exists()`` boolean 2.2.0 :doc:`Route-bound <routing>`
``Breadcrumbs::exists($name)`` boolean 2.2.0 :ref:`Exists <exists>`
``Breadcrumbs::generate()`` array 2.2.3 :doc:`Route-bound <routing>`
``Breadcrumbs::generate($name)`` array 1.0.0 :ref:`Switching views <switching-views>`
``Breadcrumbs::generate($name, $param1, ...)`` array 1.0.0 :ref:`Switching views <switching-views>`
``Breadcrumbs::generateArray($name, $params)`` array 2.0.0 :ref:`Array params <array-parameters>`
``Breadcrumbs::generateIfExists()`` array 2.2.0 :doc:`Route-bound <routing>`
``Breadcrumbs::generateIfExists($name)`` array 2.2.0 :ref:`Exists <exists>`
``Breadcrumbs::generateIfExists($name, $param1, ...)`` array 2.2.0 :ref:`Exists <exists>`
``Breadcrumbs::generateIfExistsArray($name, $params)`` array 3.0.0 :ref:`Exists <exists>`
``Breadcrumbs::render()`` string 2.2.0 :doc:`Route-bound <routing>`
``Breadcrumbs::render($name)`` string 1.0.0 :doc:`Output <output>`
``Breadcrumbs::render($name, $param1, ...)`` string 1.0.0 :doc:`Output <output>`
``Breadcrumbs::renderArray($name, $params)`` string 2.0.0 :ref:`Array params <array-parameters>`
``Breadcrumbs::renderIfExists()`` string 2.2.0 :doc:`Route-bound <routing>`
``Breadcrumbs::renderIfExists($name)`` string 2.2.0 :ref:`Exists <exists>`
``Breadcrumbs::renderIfExists($name, $param1, ...)`` string 2.2.0 :ref:`Exists <exists>`
``Breadcrumbs::renderIfExistsArray($name, $params)`` string 3.0.0 :ref:`Exists <exists>`
``Breadcrumbs::setCurrentRoute($name)`` *(none)* 2.2.0 :ref:`Current route <current-route>`
``Breadcrumbs::setCurrentRoute($name, $param1, ...)`` *(none)* 2.2.0 :ref:`Current route <current-route>`
``Breadcrumbs::setCurrentRouteArray($name, $params)`` *(none)* 2.2.0 :ref:`Current route <current-route>`
``Breadcrumbs::clearCurrentRoute()`` *(none)* 2.2.0
``Breadcrumbs::setView($view)`` *(none)* 1.0.0 :ref:`Switching views <switching-views>`
======================================================== ========== ========== ============================
`Source <https://github.com/davejamesmiller/laravel-breadcrumbs/blob/develop/src/Manager.php>`__
================================================================================
Defining breadcrumbs
================================================================================
.. code-block:: php
Breadcrumbs::register('name', function($breadcrumbs, $page) {
// ...
});
======================================================== ========== ========== ============================
Method Returns Added in Docs
======================================================== ========== ========== ============================
``$breadcrumbs->push($title)`` *(none)* 1.0.0 :ref:`No URL <no-url>`
``$breadcrumbs->push($title, $url)`` *(none)* 1.0.0 :doc:`Defining <defining>`
``$breadcrumbs->push($title, $url, $data)`` *(none)* 2.3.0 :ref:`Custom data <custom-data>`
``$breadcrumbs->parent($name)`` *(none)* 1.0.0 :ref:`Parent links <defining-parents>`
``$breadcrumbs->parent($name, $param1, ...)`` *(none)* 1.0.0 :ref:`Parent links <defining-parents>`
``$breadcrumbs->parentArray($name, $params)`` *(none)* 2.0.0 :ref:`Array parameters <array-parameters>`
======================================================== ========== ========== ============================
`Source <https://github.com/davejamesmiller/laravel-breadcrumbs/blob/develop/src/Generator.php>`__
================================================================================
In the view (template)
================================================================================
``$breadcrumbs`` (array), contains:
======================================================== ================ ========== ============================
Variable Type Added in Docs
======================================================== ================ ========== ============================
``$breadcrumb->title`` string 1.0.0 :ref:`View data <view-data>`
``$breadcrumb->url`` string or null 1.0.0 :ref:`View data <view-data>`
``$breadcrumb->first`` boolean 1.0.0 :ref:`View data <view-data>`
``$breadcrumb->last`` boolean 1.0.0 :ref:`View data <view-data>`
``$breadcrumb->custom_attribute_name`` mixed 2.3.0 :ref:`Custom data <custom-data>`
======================================================== ================ ========== ============================

View File

@@ -0,0 +1,236 @@
################################################################################
Changelog
################################################################################
.. role:: date
:class: changelog-date
.. role:: future
:class: changelog-future
.. role:: strikethrough
:class: strikethrough
Laravel Breadcrumbs uses `Semantic Versioning <http://semver.org/>`_.
.. ================================================================================
.. v3.0.1_ :future:`(Unreleased)`
.. ================================================================================
================================================================================
v3.0.0_ :date:`(8 Feb 2015)`
================================================================================
- Add Laravel 5 support (`#62`_)
- Change view namespace from ``laravel-breadcrumbs::`` to ``breadcrumbs::``
- Change Bootstrap 3 template from ``<ul>`` to ``<ol>`` to match the `documentation <http://getbootstrap.com/components/#breadcrumbs>`_
- Move documentation from GitHub (Markdown) to `Read The Docs <https://readthedocs.org/>`_ (reStructuredText/`Sphinx <http://sphinx-doc.org/>`_)
- Greatly improve unit & integration tests (largely thanks to `Testbench <https://github.com/orchestral/testbench>`_)
- Fix issue that prevented non-deferred service providers referencing Breadcrumbs (`#39`_) by making Breadcrumbs non-deferred also
- Rename ``generateArrayIfExists()`` to ``generateIfExistsArray()``
- Rename ``renderArrayIfExists()`` to ``renderIfExistsArray()``
- Remove ``$breadcrumbs->get()`` and ``$breadcrumbs->set()`` methods from Generator class (they were never used nor documented)
- Remove ``Breadcrumbs::getView()``
- Switch from PSR-0 to PSR-4 file naming
.. _v3.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/3.0.0
.. _#39: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/39
.. _#62: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/62
----------------------------------------
Upgrading from 2.x to 3.x
----------------------------------------
- `Upgrade to Laravel 5 <http://laravel.com/docs/5.0/upgrade#upgrade-5.0>`_
- Move ``app/breadcrumbs.php`` to ``app/Http/breadcrumbs.php``
- Move ``app/config/packages/davejamesmiller/laravel-breadcrumbs/config.php`` to ``config/breadcrumbs.php`` (if used)
The following changes are optional because there are shims in place:
- In the config file, replace ``laravel-breadcrumbs::`` with ``breadcrumbs::``
- Replace any calls to ``Breadcrumbs::generateArrayIfExists()`` with ``Breadcrumbs::generateIfExistsArray()``
- Replace any calls to ``Breadcrumbs::renderArrayIfExists()`` with ``Breadcrumbs::renderIfExistsArray()``
.. note::
Laravel 4 and PHP 5.3 are no longer supported -- please continue to use the `2.x branch <https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.x>`_ if you use them.
================================================================================
v2.3.1_ :date:`(8 Feb 2015)`
================================================================================
- Fix issue that prevented non-deferred service providers referencing Breadcrumbs (`#39`_) by making Breadcrumbs non-deferred also (backported from 3.0.0)
.. _v2.3.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/3.0.0
================================================================================
v2.3.0_ :date:`(26 Oct 2014)`
================================================================================
- Add ``$data`` parameter to ``$breadcrumb->push()`` to allow for arbitrary data (`#34`_, `#35`_, `#55`_, `#56`_)
.. _v2.3.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.3.0
.. _#34: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/34
.. _#35: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/35
.. _#55: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/55
.. _#56: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/56
.. _3a0afc2: https://github.com/laravel/framework/commit/3a0afc20f25ad3bed640ff1a14957f972d123cf7
================================================================================
v2.2.3_ :date:`(10 Sep 2014)`
================================================================================
- Fix ``Breadcrumbs::generate()`` with no parameters so it uses the current route, like ``Breadcrumbs::render()`` does (`#46`_)
.. _v2.2.3: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.3
.. _#46: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/46
================================================================================
v2.2.2_ :date:`(3 Aug 2014)`
================================================================================
- Support for Laravel's ``App::missing()`` method when using automatic route detection (`#40`_, `#41`_)
.. _v2.2.2: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.2
.. _#40: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/40
.. _#41: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/41
================================================================================
v2.2.1_ :date:`(19 May 2014)`
================================================================================
- Laravel 4.2 support (`#21`_, `#28`_)
.. _v2.2.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.1
.. _#21: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/21
.. _#28: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/28
================================================================================
v2.2.0_ :date:`(26 Jan 2014)`
================================================================================
- Add ``Breadcrumbs::exists()``, ``renderIfExists()``, ``renderArrayIfExists()`` (`#22`_)
- 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`_)
.. _v2.2.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.2.0
.. _#16: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/16
.. _#22: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/22
.. _#24: https://github.com/davejamesmiller/laravel-breadcrumbs/pull/24
================================================================================
v2.1.0_ :date:`(16 Oct 2013)`
================================================================================
- Add support for non-linked breadcrumbs to the Twitter Bootstrap templates (`#20`_)
.. _v2.1.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.1.0
.. _#20: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/20
================================================================================
v2.0.0_ :date:`(28 Sep 2013)`
================================================================================
- Add Twitter Bootstrap v3 template (`#7`_)
- Twitter Bootstrap v3 is now the default template
- Support for passing arrays into ``render()``, ``generate()`` and ``parent()`` (**not backwards-compatible**) (`#8`_)
- Split ``Breadcrumbs::render()`` into ``render($name, $arg1, $arg2)`` and ``renderArray($name, $params)``
- Split ``Breadcrumbs::generate()`` into ``generate($name, $arg1, $arg2)`` and ``generateArray($name, $params)``
- Split ``$breadcrumbs->parent()`` into ``parent($name, $arg1, $arg2)`` and ``parentArray($name, $params)``
- Set view name in config file instead of in ``breadcrumbs.php`` (`#10`_, `#11`_)
- Simplify class names (`#15`_)
- Add unit tests
.. _v2.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.0.0
.. _#7: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/7
.. _#8: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/8
.. _#10: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/10
.. _#11: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/11
.. _#15: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/15
----------------------------------------
Upgrading from 1.x to 2.x
----------------------------------------
- In ``app/config/app.php`` change ``DaveJamesMiller\Breadcrumbs\BreadcrumbsServiceProvider`` to ``DaveJamesMiller\Breadcrumbs\ServiceProvider``
- In ``app/config/app.php`` change ``DaveJamesMiller\Breadcrumbs\Facades\Breadcrumbs`` to ``DaveJamesMiller\Breadcrumbs\Facade``
- The default template was changed from Bootstrap 2 to Bootstrap 3. See :ref:`Choose a template <choose-template>` if you need to switch it back.
The following internal changes will not affect most people but if you have any problems please be aware of the following:
- The view namespace was changed from ``breadcrumbs`` to ``laravel-breadcrumbs`` to match the Composer project name.
- The Bootstrap 2 template name was changed from ``breadcrumbs::bootstrap`` to ``laravel-breadcrumbs::bootstrap2``.
- If you pass arrays into any of the methods, please read the following section:
Passing arrays into ``render()``, ``generate()`` and ``parent()``
.................................................................
In **version 1.x** you could pass an array into each of these methods and it was split up into several parameters. For example:
.. code-block:: php
// If this breadcrumb is defined:
Breadcrumbs::register('page', function($breadcrumbs, $param1, $param2)
{
$breadcrumbs->push($param1, $param2);
});
// Then this:
Breadcrumbs::render('page', ['param1', 'param2']);
// Was equivalent to this:
Breadcrumbs::render('page', 'param1', 'param2');
// But to pass an array as the first parameter you would have to do this instead:
Breadcrumbs::render('page', [['param1A', 'param1B']]);
This means you couldn't pass an array as the first parameter unless you wrapped all parameters in another array (issue `#8`_).
In **version 2.x** this has been split into two methods:
.. code-block:: php
// Now this:
Breadcrumbs::renderArray('page', ['param1', 'param2']);
// Is equivalent to this:
Breadcrumbs::render('page', 'param1', 'param2');
// And this only passes a single parameter (an array) to the callback:
Breadcrumbs::render('page', ['param1A', 'param1B']);
Similarly ``Breadcrumbs::generateArray()`` and ``$breadcrumbs->parentArray()`` methods are available, which take a single array argument.
================================================================================
v1.0.1_ :date:`(13 Jul 2013)`
================================================================================
- Fix for PHP 5.3 compatibility (`#3`_)
.. _v1.0.1: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/1.0.1
.. _#3: https://github.com/davejamesmiller/laravel-breadcrumbs/issues/3
================================================================================
v1.0.0_ :date:`(25 May 2013)`
================================================================================
.. _v1.0.0: https://github.com/davejamesmiller/laravel-breadcrumbs/tree/1.0.0
- Initial release

View File

@@ -0,0 +1,314 @@
# -*- coding: utf-8 -*-
#
# Laravel Breadcrumbs documentation build configuration file, created by
# sphinx-quickstart on Sat Nov 8 11:14:26 2014.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import json
# Custom imports
import re
from datetime import date
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.todo',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = []
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Laravel Breadcrumbs'
copyright = u'2013-%d, Dave James Miller' % date.today().year
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
with open('changelog.rst', 'r') as changelog:
# Determine the version number from the changelog so I don't have to update
# it in two places
match = re.search(r'^ v((\d+)\.\d+\.\d+)_ :(date|future):', changelog.read(), re.MULTILINE)
# The short X.Y version.
version = match.group(2)
# The full version, including alpha/beta/rc tags.
release = match.group(1)
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
today_fmt = '%-d %B %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'LaravelBreadcrumbsdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
'preamble': '\n'.join((
# Fix the unicode characters in the file tree diagrams
r'\DeclareUnicodeCharacter{251C}{+}', # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
r'\DeclareUnicodeCharacter{2514}{+}', # BOX DRAWINGS LIGHT UP AND RIGHT
r'\DeclareUnicodeCharacter{00A0}{ }', # NO-BREAK SPACE
# Fix "! Undefined control sequence. <argument> \node@class@name" error when using ".. role"
# Based on https://bitbucket.org/birkenfeld/sphinx/issue/1564/custom-roles-are-not-properly-translated
# (I couldn't get the patches suggested in that issue to work either!)
r'\renewcommand{\DUspan}[2]{#2}',
)),
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'laravel-breadcrumbs.tex', u'Laravel Breadcrumbs Documentation',
u'Dave James Miller', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
latex_show_pagerefs = True
# If true, show URL addresses after external links.
latex_show_urls = 'footnote'
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'laravel-breadcrumbs', u'Laravel Breadcrumbs Documentation',
[u'Dave James Miller'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'laravel-breadcrumbs', u'Laravel Breadcrumbs Documentation',
u'Dave James Miller', 'Laravel Breadcrumbs', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# -- Custom options -------------------------------------------------------
# Default to plain text blocks
highlight_language = 'none'
# Custom CSS
html_static_path = ['_static']
def setup(app):
app.add_stylesheet('custom.css')
# Only when run locally (not on Read The Docs):
if os.environ.get('READTHEDOCS', None) != 'True':
# Read The Docs theme
# http://read-the-docs.readthedocs.org/en/latest/theme.html
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Show TODO items
todo_include_todos = True
# Show a link to the online docs in the index page
tags.add('local')
# Enable highlighting for PHP code not between ``<?php ... ?>`` by default
# https://github.com/fabpot/sphinx-php
from sphinx.highlighting import lexers
from pygments.lexers.web import PhpLexer
lexers['php'] = PhpLexer(startinline=True)
lexers['php-annotations'] = PhpLexer(startinline=True)

View File

@@ -0,0 +1,182 @@
################################################################################
Contributing
################################################################################
.. This text is also in ../CONTRIBUTING.rst
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 <https://github.com/davejamesmiller/laravel-breadcrumbs/pulls>`_ on GitHub. (The information below may help you to get started if you've not done this before.)
If you want to submit a **new feature**, it's usually best to open an `issue <https://github.com/davejamesmiller/laravel-breadcrumbs/issues>`_ 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.
.. only:: html
.. contents::
:local:
================================================================================
Developing inside a real application
================================================================================
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.
If you've already got it installed, delete it from the ``vendor/`` directory and re-install from source:
.. code-block:: bash
$ cd /path/to/repo
$ rm -rf vendor/davejamesmiller/laravel-breadcrumbs
$ composer install --prefer-source
$ cd vendor/davejamesmiller/laravel-breadcrumbs
$ git checkout -t origin/develop
$ git checkout -b YOUR_BRANCH
# Make changes and commit them
$ git remote add YOUR_USERNAME git@github.com:YOUR_USERNAME/laravel-breadcrumbs
$ git push -u YOUR_USERNAME YOUR_BRANCH
There is also a `test app <https://github.com/davejamesmiller/laravel-breadcrumbs-test>`_ available to simplify testing against multiple versions of Laravel.
.. note::
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.
================================================================================
Using your fork in a project
================================================================================
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:
.. code-block:: json
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/YOUR_USERNAME/laravel-breadcrumbs.git"
}
],
"require": {
"davejamesmiller/laravel-breadcrumbs": "dev-YOUR_BRANCH"
}
}
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.
================================================================================
Unit tests
================================================================================
To run the unit tests, simply run:
.. code-block:: bash
$ cd /path/to/laravel-breadcrumbs
$ composer update
$ ./test.sh
(Note: The unit tests are not 100% complete yet, and the code will probably need some refactoring to make it easier to test.)
----------------------------------------
Code coverage
----------------------------------------
To check code coverage, you will also need `Xdebug <http://xdebug.org/>`_ installed. Run:
.. code-block:: bash
$ ./test-coverage.sh
Then open ``test-coverage/index.html`` to view the results. (However, be aware of the `edge cases <https://phpunit.de/manual/current/en/code-coverage-analysis.html#code-coverage-analysis.edge-cases>`_ in PHPUnit that can make it not-quite-accurate.)
.. _contributing-documentation:
================================================================================
Documentation
================================================================================
Documentation is in ``docs/``. It is written in `reStructuredText <http://docutils.sourceforge.net/rst.html>`_ and converted to HTML and PDF formats by `Sphinx <http://sphinx-doc.org/>`_.
To submit a documentation change, simply `edit the appropriate file on GitHub <https://github.com/alberon/awe/tree/master/docs>`_. (There's an "Edit on GitHub" link in the top-right corner of each page.)
.. warning::
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.
For more comprehensive documentation changes you may be better installing Sphinx so you can test the docs locally:
----------------------------------------
Installing Sphinx
----------------------------------------
You will need `Python <https://www.python.org/>`_ and `pip <https://pypi.python.org/pypi/pip>`_ to install `Sphinx <http://sphinx-doc.org/>`_, the documentation generator. To install them (on Debian Wheezy or similar), you can run the following:
.. code-block:: bash
$ sudo apt-get install python python-pip
$ sudo pip install sphinx sphinx-autobuild sphinx_rtd_theme
To build the PDF documentation, you will also need LaTeX installed:
.. code-block:: bash
$ sudo apt-get install texlive texlive-latex-extra
----------------------------------------
Building documentation
----------------------------------------
To build the HTML docs (``docs-html/index.html``):
.. code-block:: bash
$ ./build-html-docs.sh
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.
To build the PDF docs (``docs-pdf/laravel-breadcrumbs.pdf``):
.. code-block:: bash
$ ./build-pdf-docs.sh
----------------------------------------
Sphinx markup reference
----------------------------------------
I found the following documents useful when writing the documentation:
- `reStructuredText quick reference <http://docutils.sourceforge.net/docs/user/rst/quickref.html>`_
- `Admonitions list <http://docutils.sourceforge.net/docs/ref/rst/directives.html#admonitions>`_ (``note::``, ``warning::``, etc.)
- `Code examples markups <http://sphinx-doc.org/markup/code.html>`_ (``code-block::``, ``highlight::``)
- `Other paragraph-level markup <http://sphinx-doc.org/markup/para.html>`_ (``versionadded::``, ``deprecated::``, etc.)
- `Inline markup <http://sphinx-doc.org/markup/inline.html>`_ (``:ref:``, ``:doc:``, etc.)
- `Table of contents <http://sphinx-doc.org/markup/toctree.html>`_ (``toctree::``)
----------------------------------------
Heading styles
----------------------------------------
The following code styles are used for headings::
################################################################################
Page title (80 hashes)
################################################################################
================================================================================
Section title (80 equals signs)
================================================================================
----------------------------------------
Heading 2 (40 hypens)
----------------------------------------
Heading 3 (full stops)
......................

View File

@@ -0,0 +1,161 @@
################################################################################
Defining Breadcrumbs
################################################################################
Breadcrumbs will usually correspond to actions or types of page. For each breadcrumb you specify a name, the breadcrumb title and the URL to link it to. Since these are likely to change dynamically, you do this in a closure, and you pass any variables you need into the closure.
The following examples should make it clear:
.. only:: html
.. contents::
:local:
================================================================================
Static pages
================================================================================
The most simple breadcrumb is probably going to be your homepage, which will look something like this:
.. code-block:: php
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', route('home'));
});
As you can see, you simply call ``$breadcrumbs->push($title, $url)`` inside the closure.
For generating the URL, you can use any of the standard Laravel URL-generation methods, including:
- ``url('path/to/route')`` (``URL::to()``)
- ``secure_url('path/to/route')``
- ``route('routename')`` (``URL::route()``)
- ``action('controller@action')`` (``URL::action()``)
- Or just pass a string URL (``'http://www.example.com/'``)
This example would be rendered like this:
.. raw:: html
<div class="highlight"><pre>
Home
</pre></div>
.. only:: not html
::
Home
.. _defining-parents:
================================================================================
Parent links
================================================================================
This is another static page, but this has a parent link before it:
.. code-block:: php
Breadcrumbs::register('blog', function($breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Blog', route('blog'));
});
It would be rendered like this:
.. raw:: html
<div class="highlight"><pre>
<a href="#">Home</a> / Blog
</pre></div>
.. only:: not html
::
Home > Blog
================================================================================
Dynamic titles and links
================================================================================
This is a dynamically generated page pulled from the database:
.. code-block:: php
Breadcrumbs::register('page', function($breadcrumbs, $page) {
$breadcrumbs->parent('blog');
$breadcrumbs->push($page->title, route('page', $page->id));
});
The ``$page`` variable would simply be passed in from the view:
.. code-block:: html+php
{!! Breadcrumbs::render('page', $page) !!}
It would be rendered like this:
.. raw:: html
<div class="highlight"><pre>
<a href="#">Home</a> / <a href="#">Blog</a> / Page Title
</pre></div>
.. only:: not html
::
Home > Blog > Page Title
**Tip:** You can pass multiple parameters if necessary.
================================================================================
Nested categories
================================================================================
Finally if you have nested categories or other special requirements, you can call ``$breadcrumbs->push()`` multiple times:
.. code-block:: php
Breadcrumbs::register('category', function($breadcrumbs, $category) {
$breadcrumbs->parent('blog');
foreach ($category->ancestors as $ancestor) {
$breadcrumbs->push($ancestor->title, route('category', $ancestor->id));
}
$breadcrumbs->push($category->title, route('category', $category->id));
});
Alternatively you could make a recursive function such as this:
.. code-block:: php
Breadcrumbs::register('category', function($breadcrumbs, $category) {
if ($category->parent)
$breadcrumbs->parent('category', $category->parent);
else
$breadcrumbs->parent('blog');
$breadcrumbs->push($category->title, route('category', $category->slug));
});
Both would be rendered like this:
.. raw:: html
<div class="highlight"><pre>
<a href="#">Home</a> / <a href="#">Blog</a> / <a href="#">Grandparent Category</a> / <a href="#">Parent Category</a> / Category Title
</pre></div>
.. only:: not html
::
Home > Blog > Grandparent Category > Parent Category > Category Title

View File

@@ -0,0 +1,37 @@
################################################################################
Laravel Breadcrumbs 3
################################################################################
.. Link to the online documentation
.. only:: local and html
.. admonition:: Local Documentation
:class: warning
`Read the documentation online >> <http://laravel-breadcrumbs.davejamesmiller.com/>`_
.. Introduction
A simple Laravel-style way to create breadcrumbs in `Laravel 5 <http://laravel.com/>`_.
================================================================================
Table of Contents
================================================================================
.. toctree::
start
defining
templates
output
routing
advanced
api
contributing
changelog
thanks
license
» GitHub <https://github.com/davejamesmiller/laravel-breadcrumbs>
» Packagist <https://packagist.org/packages/davejamesmiller/laravel-breadcrumbs>

View File

@@ -0,0 +1,25 @@
################################################################################
License
################################################################################
`The MIT License (MIT) <http://choosealicense.com/licenses/mit/>`_
**Copyright © 2013-2015 Dave James Miller**
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,63 @@
################################################################################
Outputting Breadcrumbs
################################################################################
Call ``Breadcrumbs::render()`` in the view template for each page, passing it the name of the breadcrumb to use and any additional parameters.
.. only:: html
.. contents::
:local:
================================================================================
With Blade
================================================================================
In the page (e.g. ``resources/views/home.blade.php``):
.. code-block:: html+php
{!! Breadcrumbs::render('home') !!}
Or with a parameter:
.. code-block:: html+php
{!! Breadcrumbs::render('category', $category) !!}
================================================================================
With Blade layouts and @section
================================================================================
In the page (e.g. ``resources/views/home.blade.php``):
.. code-block:: html+php
@extends('layout.name')
@section('breadcrumbs', Breadcrumbs::render('home'))
In the layout (e.g. ``resources/views/app.blade.php``):
.. code-block:: html+php
@yield('breadcrumbs')
================================================================================
Pure PHP (without Blade)
================================================================================
In the page (e.g. ``resources/views/home.php``):
.. code-block:: html+php
<?= Breadcrumbs::render('home') ?>
Or use the long-hand syntax if you prefer:
.. code-block:: html+php
<?php echo Breadcrumbs::render('home') ?>

View File

@@ -0,0 +1,195 @@
################################################################################
Route-Bound Breadcrumbs
################################################################################
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.
.. only:: html
.. contents::
:local:
================================================================================
Setup
================================================================================
----------------------------------------
Name your routes
----------------------------------------
Make sure each of your routes has a name (``'as'`` parameter). For example (``app/Http/routes.php``):
.. code-block:: php
// Home
Route::get('/', ['as' => 'home', 'uses' => 'HomeController@index']);
// Home > [Page]
Route::get('/page/{id}', ['as' => 'page', 'uses' => 'PageController@show']);
For more details see `Named Routes <http://laravel.com/docs/routing#named-routes>`_ in the Laravel documentation.
----------------------------------------
Name your breadcrumbs to match
----------------------------------------
For each route, create a breadcrumb with the same name. For example (``app/Http/routes.php``):
.. code-block:: php
// Home
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', route('home'));
});
// Home > [Page]
Breadcrumbs::register('page', function($breadcrumbs, $id)
{
$page = Page::findOrFail($id);
$breadcrumbs->parent('home');
$breadcrumbs->push($page->title, route('page', $page->id));
});
----------------------------------------
Output breadcrumbs in your layout
----------------------------------------
Call ``Breadcrumbs::render()`` with no parameters in your layout file (e.g. ``resources/views/app.blade.php``):
.. code-block:: html+php
{!! Breadcrumbs::render() !!}
This will automatically output breadcrumbs corresponding to the current route.
It will throw an exception if the breadcrumb doesn't exist, to remind you to create one. To prevent this behaviour, change it to:
.. code-block:: html+php
{!! Breadcrumbs::renderIfExists() !!}
================================================================================
Route model binding
================================================================================
Laravel Breadcrumbs uses the same model binding as the controller. For example:
.. code-block:: php
// app/Http/routes.php
Route::model('page', 'Page');
Route::get('/page/{page}', ['uses' => 'PageController@show', 'as' => 'page']);
.. code-block:: php
// app/Http/Controllers/PageController.php
class PageController extends Controller {
public function show($page)
{
return view('page/show', ['page' => $page]);
}
}
.. code-block:: php
// app/Http/breadcrumbs.php
Breadcrumbs::register('page', function($breadcrumbs, $page)
{
$breadcrumbs->parent('home');
$breadcrumbs->push($page->title, route('page', $page->id));
});
This makes your code less verbose and more efficient by only loading the page from the database once.
For more details see `Route Model Binding <http://laravel.com/docs/routing#route-model-binding>`_ in the Laravel documentation.
================================================================================
Resourceful controllers
================================================================================
Laravel automatically creates route names for resourceful controllers, e.g. ``photo.index``, which you can use when defining your breadcrumbs. For example:
.. code-block:: php
// app/Http/routes.php
Route::resource('photo', 'PhotoController');
.. code-block:: bash
$ php artisan route:list
+--------+----------+--------------------+---------------+-------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+--------------------+---------------+-------------------------+------------+
| | GET|HEAD | photo | photo.index | PhotoController@index | |
| | GET|HEAD | photo/create | photo.create | PhotoController@create | |
| | POST | photo | photo.store | PhotoController@store | |
| | GET|HEAD | photo/{photo} | photo.show | PhotoController@show | |
| | GET|HEAD | photo/{photo}/edit | photo.edit | PhotoController@edit | |
| | PUT | photo/{photo} | photo.update | PhotoController@update | |
| | PATCH | photo/{photo} | | PhotoController@update | |
| | DELETE | photo/{photo} | photo.destroy | PhotoController@destroy | |
+--------+----------+--------------------+---------------+-------------------------+------------+
.. code-block:: php
// app/Http/breadcrumbs.php
// Photos
Breadcrumbs::register('photo.index', function($breadcrumbs)
{
$breadcrumbs->parent('home');
$breadcrumbs->push('Photos', route('photo.index'));
});
// Photos > Upload Photo
Breadcrumbs::register('photo.create', function($breadcrumbs)
{
$breadcrumbs->parent('photo.index');
$breadcrumbs->push('Upload Photo', route('photo.create'));
});
// Photos > [Photo Name]
Breadcrumbs::register('photo.show', function($breadcrumbs, $photo)
{
$breadcrumbs->parent('photo.index');
$breadcrumbs->push($photo->title, route('photo.show', $photo->id));
});
// Photos > [Photo Name] > Edit Photo
Breadcrumbs::register('photo.edit', function($breadcrumbs, $photo)
{
$breadcrumbs->parent('photo.show', $photo);
$breadcrumbs->push('Edit Photo', route('photo.edit', $photo->id));
});
For more details see `RESTful Resource Controllers <http://laravel.com/docs/controllers#restful-resource-controllers>`_ in the Laravel documentation.
================================================================================
Implicit controllers
================================================================================
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:
.. code-block:: php
// app/Http/routes.php
Route::controller('users', 'UserController');
.. code-block:: bash
$ php artisan route:list
+----------+-----------------------------------------+-----------+------------------------------+
| Method | URI | Name | Action |
+----------+-----------------------------------------+-----------+------------------------------+
| GET|HEAD | users | | UserController@getIndex |
| GET|HEAD | users/index/{one?}/{two?}/{three?}... | | UserController@getIndex |
| POST | users/profile/{one?}/{two?}/{three?}... | | UserController@postProfile |
+----------+-----------------------------------------+-----------+------------------------------+
For more details see `Implicit Controllers <http://laravel.com/docs/controllers#implicit-controllers>`_ in the Laravel documentation.

View File

@@ -0,0 +1,144 @@
################################################################################
Getting Started
################################################################################
.. only:: html
.. contents::
:local:
================================================================================
1. Install Laravel Breadcrumbs
================================================================================
.. note::
Laravel 5.0 or above is required -- use the `2.x version <https://github.com/davejamesmiller/laravel-breadcrumbs/tree/2.x>`_ for Laravel 4.
----------------------------------------
Install with Composer
----------------------------------------
Run this at the command line:
.. code-block:: bash
$ composer require davejamesmiller/laravel-breadcrumbs
This will both update ``composer.json`` and install the package into the ``vendor/`` directory.
----------------------------------------
Add to ``config/app.php``
----------------------------------------
Add the service provider to ``providers``:
.. code-block:: php
'providers' => [
// ...
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
],
And add the facade to ``aliases``:
.. code-block:: php
'aliases' => [
// ...
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
],
================================================================================
2. Define your breadcrumbs
================================================================================
Create a file called ``app/Http/breadcrumbs.php`` that looks like this:
.. code-block:: php
<?php
// Home
Breadcrumbs::register('home', function($breadcrumbs)
{
$breadcrumbs->push('Home', route('home'));
});
// Home > About
Breadcrumbs::register('about', function($breadcrumbs)
{
$breadcrumbs->parent('home');
$breadcrumbs->push('About', route('about'));
});
// Home > Blog
Breadcrumbs::register('blog', function($breadcrumbs)
{
$breadcrumbs->parent('home');
$breadcrumbs->push('Blog', route('blog'));
});
// Home > Blog > [Category]
Breadcrumbs::register('category', function($breadcrumbs, $category)
{
$breadcrumbs->parent('blog');
$breadcrumbs->push($category->title, route('category', $category->id));
});
// Home > Blog > [Category] > [Page]
Breadcrumbs::register('page', function($breadcrumbs, $page)
{
$breadcrumbs->parent('category', $page->category);
$breadcrumbs->push($page->title, route('page', $page->id));
});
See the :doc:`defining` section for more details.
.. _choose-template:
================================================================================
3. Choose a template
================================================================================
By default a `Bootstrap <http://getbootstrap.com/components/#breadcrumbs>`_-compatible unordered list will be rendered, so if you're using Bootstrap 3 you can skip this step.
First initialise the config file by running this command:
.. code-block:: bash
$ php artisan vendor:publish
Then open ``config/breadcrumbs.php`` and edit this line:
.. code-block:: php
'view' => 'breadcrumbs::bootstrap3',
The possible values are:
- `Bootstrap 3 <http://getbootstrap.com/components/#breadcrumbs>`_: ``breadcrumbs::bootstrap3``
- `Bootstrap 2 <http://getbootstrap.com/2.3.2/components.html#breadcrumbs>`_: ``breadcrumbs::bootstrap2``
- The path to a custom view: e.g. ``_partials/breadcrumbs``
See the :doc:`templates` section for more details.
================================================================================
4. Output the breadcrumbs
================================================================================
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:
.. code-block:: html+php
{!! Breadcrumbs::render('home') !!}
{!! Breadcrumbs::render('category', $category) !!}
See the :doc:`output` section for other output options, and see :doc:`routing` for a way to link breadcrumb names to route names automatically.

View File

@@ -0,0 +1,59 @@
################################################################################
Custom Templates
################################################################################
.. only:: html
.. contents::
:local:
================================================================================
Create a view
================================================================================
To customise the HTML, create your own view file (e.g. ``resources/views/_partials/breadcrumbs.blade.php``) like this:
.. code-block:: html+php
@if ($breadcrumbs)
<ul class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if (!$breadcrumb->last)
<li><a href="{{{ $breadcrumb->url }}}">{{{ $breadcrumb->title }}}</a></li>
@else
<li class="active">{{{ $breadcrumb->title }}}</li>
@endif
@endforeach
</ul>
@endif
(See the `views/ directory <https://github.com/davejamesmiller/laravel-breadcrumbs/tree/master/views>`_ for the built-in templates.)
.. _view-data:
----------------------------------------
View data
----------------------------------------
The view will receive an array called ``$breadcrumbs``.
Each breadcrumb is an object with the following keys:
- ``title`` - The title you set above
- ``url`` - The URL you set above
- ``first`` - ``true`` for the first breadcrumb (top level), ``false`` otherwise
- ``last`` - ``true`` for the last breadcrumb (current page), ``false`` otherwise
- Additional keys for each item in ``$data`` (see :ref:`custom-data`)
================================================================================
Update the config
================================================================================
Then update your config file (``config/breadcrumbs.php``) with the custom view name, e.g.:
.. code-block:: php
'view' => '_partials/breadcrumbs',

View File

@@ -0,0 +1,24 @@
################################################################################
Thanks to
################################################################################
This package is largely based on the `Gretel <https://github.com/lassebunk/gretel>`_ plugin for Ruby on Rails, which I used for a while before discovering Laravel.
And of course it would be nothing without `Laravel <http://laravel.com/>`_ itself!
================================================================================
Contributors
================================================================================
- Christian Thomas (`christian-thomas <https://github.com/christian-thomas>`_) -
`#62 <https://github.com/davejamesmiller/laravel-breadcrumbs/issues/62#issuecomment-71724019>`_
- Miloš Levačić (`levacic <https://github.com/levacic>`_) -
`#56 <https://github.com/davejamesmiller/laravel-breadcrumbs/pull/56>`_
- Ricky Wiens (`rickywiens <https://github.com/rickywiens>`_) -
`#41 <https://github.com/davejamesmiller/laravel-breadcrumbs/pull/41>`_
- Boris Glumpler (`shabushabu <https://github.com/shabushabu>`_) -
`#28 <https://github.com/davejamesmiller/laravel-breadcrumbs/pull/28>`_
- Andrej Badin (`Andreyco <https://github.com/Andreyco>`_) -
`#24 <https://github.com/davejamesmiller/laravel-breadcrumbs/pull/24>`_
- Stef Horner (`tedslittlerobot <https://github.com/tedslittlerobot>`_) -
`#11 <https://github.com/davejamesmiller/laravel-breadcrumbs/pull/11>`_

View File

@@ -0,0 +1,7 @@
<?php
// Load Composer packages
require __DIR__ . '/vendor/autoload.php';
// Load base class
require __DIR__ . '/tests/TestCase.php';

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
bootstrap="phpunit.php"
checkForUnintentionallyCoveredCode="true"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
verbose="true"
>
<!-- List of files with tests inside -->
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">tests/unit/</directory>
<directory suffix=".php">tests/integration/</directory>
</testsuite>
</testsuites>
<!-- List of source files for code coverage checker -->
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,47 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Contracts\Routing\Registrar as Router;
class CurrentRoute {
protected $route;
protected $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function get()
{
if ($this->route)
return $this->route;
$route = $this->router->current();
if (is_null($route))
return ['', []];
$name = $route->getName();
if (is_null($name)) {
$uri = head($route->methods()) . ' /' . $route->uri();
throw new Exception("The current route ($uri) is not named - please check routes.php for an \"as\" parameter");
}
$params = array_values($route->parameters());
return [$name, $params];
}
public function set($name, $params)
{
$this->route = [$name, $params];
}
public function clear()
{
$this->route = null;
}
}

View File

@@ -0,0 +1,4 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Exception extends \Exception {
}

View File

@@ -0,0 +1,18 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Support\Facades\Facade as BaseFacade;
class Facade extends BaseFacade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
// App::make('breadcrumbs')
return 'breadcrumbs';
}
}

View File

@@ -0,0 +1,63 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Generator {
protected $breadcrumbs = [];
protected $callbacks = [];
public function generate(array $callbacks, $name, $params)
{
$this->breadcrumbs = [];
$this->callbacks = $callbacks;
$this->call($name, $params);
return $this->toArray();
}
protected function call($name, $params)
{
if (!isset($this->callbacks[$name]))
throw new Exception("Breadcrumb not found with name \"{$name}\"");
array_unshift($params, $this);
call_user_func_array($this->callbacks[$name], $params);
}
public function parent($name)
{
$params = array_slice(func_get_args(), 1);
$this->call($name, $params);
}
public function parentArray($name, $params = [])
{
$this->call($name, $params);
}
public function push($title, $url = null, array $data = [])
{
$this->breadcrumbs[] = (object) array_merge($data, [
'title' => $title,
'url' => $url,
// These will be altered later where necessary:
'first' => false,
'last' => false,
]);
}
public function toArray()
{
$breadcrumbs = $this->breadcrumbs;
// Add first & last indicators
if ($breadcrumbs) {
$breadcrumbs[0]->first = true;
$breadcrumbs[count($breadcrumbs) - 1]->last = true;
}
return $breadcrumbs;
}
}

View File

@@ -0,0 +1,158 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Manager {
protected $currentRoute;
protected $generator;
protected $view;
protected $callbacks = [];
protected $viewName;
protected $currentRouteManual;
public function __construct(CurrentRoute $currentRoute, Generator $generator, View $view)
{
$this->generator = $generator;
$this->currentRoute = $currentRoute;
$this->view = $view;
}
public function register($name, $callback)
{
$this->callbacks[$name] = $callback;
}
public function exists($name = null)
{
if (is_null($name)) {
try {
list($name) = $this->currentRoute->get();
} catch (Exception $e) {
return false;
}
}
return isset($this->callbacks[$name]);
}
public function generate($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateArray($name, $params = [])
{
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateIfExists($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
if (!$this->exists($name))
return [];
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateIfExistsArray($name, $params = [])
{
if (!$this->exists($name))
return [];
return $this->generator->generate($this->callbacks, $name, $params);
}
/**
* @deprecated Since 3.0.0
* @see generateIfExistsArray
*/
public function generateArrayIfExists()
{
return call_user_func_array([$this, 'generateIfExistsArray'], func_get_args());
}
public function render($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderArray($name, $params = [])
{
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderIfExists($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
if (!$this->exists($name))
return '';
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderIfExistsArray($name, $params = [])
{
if (!$this->exists($name))
return '';
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
/**
* @deprecated Since 3.0.0
* @see renderIfExistsArray
*/
public function renderArrayIfExists()
{
return call_user_func_array([$this, 'renderIfExistsArray'], func_get_args());
}
public function setCurrentRoute($name)
{
$params = array_slice(func_get_args(), 1);
$this->currentRoute->set($name, $params);
}
public function setCurrentRouteArray($name, $params = [])
{
$this->currentRoute->set($name, $params);
}
public function clearCurrentRoute()
{
$this->currentRoute->clear();
}
public function setView($view)
{
$this->viewName = $view;
}
}

View File

@@ -0,0 +1,77 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
class ServiceProvider extends BaseServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
// Can't enable this because there appears to be a bug in Laravel where a
// non-deferred service provider can't use a deferred one because the boot
// method is not called - see DependantServiceProviderTest.
// protected $defer = true;
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['breadcrumbs'];
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app['breadcrumbs'] = $this->app->share(function($app)
{
$breadcrumbs = $this->app->make('DaveJamesMiller\Breadcrumbs\Manager');
$viewPath = __DIR__ . '/../views/';
$this->loadViewsFrom($viewPath, 'breadcrumbs');
$this->loadViewsFrom($viewPath, 'laravel-breadcrumbs'); // Backwards-compatibility with 2.x
$breadcrumbs->setView($app['config']['breadcrumbs.view']);
return $breadcrumbs;
});
}
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$configFile = __DIR__ . '/../config/breadcrumbs.php';
$this->mergeConfigFrom($configFile, 'breadcrumbs');
$this->publishes([
$configFile => config_path('breadcrumbs.php')
]);
$this->registerBreadcrumbs();
}
// This method can be overridden in a child class
public function registerBreadcrumbs()
{
// Load the app breadcrumbs if they're in app/Http/breadcrumbs.php
if (file_exists($file = $this->app['path'].'/Http/breadcrumbs.php'))
{
require $file;
}
}
}

View File

@@ -0,0 +1,22 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Contracts\View\Factory as ViewFactory;
class View {
protected $factory;
public function __construct(ViewFactory $factory)
{
$this->factory = $factory;
}
public function render($view, $breadcrumbs)
{
if (!$view)
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)');
return $this->factory->make($view, compact('breadcrumbs'))->render();
}
}

View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -eu
cd $(dirname $0)
php -d xdebug.coverage_enable=On vendor/bin/phpunit --coverage-html test-coverage "$@"

View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -eu
cd $(dirname $0)
vendor/bin/phpunit "$@"

View File

@@ -0,0 +1,39 @@
<?php
abstract class TestCase extends Orchestra\Testbench\TestCase {
protected function getPackageProviders()
{
return [
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
];
}
protected function getPackageAliases()
{
return [
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade'
];
}
public function setUp()
{
parent::setUp();
$this->loadServiceProvider();
}
protected function loadServiceProvider()
{
// Need to trigger register() to test the views
$this->app->make('breadcrumbs');
}
public function tearDown()
{
$this->addToAssertionCount(Mockery::getContainer()->mockery_getExpectationCount());
Mockery::close();
}
}

View File

@@ -0,0 +1,3 @@
<ol class="breadcrumb">
<li class="active">Home</li>
</ol>

View File

@@ -0,0 +1,3 @@
<ol class="breadcrumb">
<li class="active">Home</li>
</ol>

View File

@@ -0,0 +1,17 @@
<ul class="breadcrumb">
<li>
<a href="/">Home</a>
<span class="divider">/</span>
</li>
<li class="active">
Not a link
<span class="divider">/</span>
</li>
<li>
<a href="/blog">Blog &amp; &lt; &gt;</a>
<span class="divider">/</span>
</li>
<li class="active">
Sample Post
</li>
</ul>

View File

@@ -0,0 +1,6 @@
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li class="active">Not a link</li>
<li><a href="/blog">Blog &amp; &lt; &gt;</a></li>
<li class="active">Sample Post</li>
</ol>

View File

@@ -0,0 +1,5 @@
<ol class="breadcrumb">
<li><a href="/">Home</a></li>
<li><a href="/category/456">Sample Category</a></li>
<li class="active">Sample Post</li>
</ol>

View File

@@ -0,0 +1,29 @@
<?php
class CustomServiceProviderTest extends TestCase {
protected function getPackageProviders()
{
return [
'CustomServiceProvider',
];
}
public function testRender()
{
$html = Breadcrumbs::render('home');
$this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/CustomServiceProvider.html', $html);
}
}
class CustomServiceProvider extends DaveJamesMiller\Breadcrumbs\ServiceProvider {
public function registerBreadcrumbs()
{
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', '/');
});
}
}

View File

@@ -0,0 +1,43 @@
<?php
class DependantServiceProviderErrorTest extends TestCase {
protected function getPackageProviders()
{
return [
// These are in the wrong order
'DependantServiceProviderError',
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
];
}
protected function loadServiceProvider()
{
// Disabled - we want to test the automatic loading instead
}
/**
* @expectedException DaveJamesMiller\Breadcrumbs\Exception
* @expectedExceptionMessage Breadcrumbs view not specified
*/
public function testRender()
{
Breadcrumbs::render('home');
}
}
class DependantServiceProviderError extends Illuminate\Support\ServiceProvider {
public function register()
{
}
public function boot()
{
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', '/');
});
}
}

View File

@@ -0,0 +1,39 @@
<?php
class DependantServiceProviderTest extends TestCase {
protected function getPackageProviders()
{
return [
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
'DependantServiceProvider',
];
}
protected function loadServiceProvider()
{
// Disabled - we want to test the automatic loading instead
}
public function testRender()
{
$html = Breadcrumbs::render('home');
$this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/DependantServiceProvider.html', $html);
}
}
class DependantServiceProvider extends Illuminate\Support\ServiceProvider {
public function register()
{
}
public function boot()
{
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', '/');
});
}
}

View File

@@ -0,0 +1,61 @@
<?php
class IntegrationTest extends TestCase {
public function setUp()
{
parent::setUp();
Breadcrumbs::register('home', function($breadcrumbs) {
$breadcrumbs->push('Home', '/');
});
Breadcrumbs::register('category', function($breadcrumbs, $category) {
$breadcrumbs->parent('home');
$breadcrumbs->push($category->title, '/category/' . $category->id);
});
Breadcrumbs::register('post', function($breadcrumbs, $post) {
$breadcrumbs->parent('category', $post->category);
$breadcrumbs->push($post->title, '/blog/' . $post->id);
});
$this->post = (object) [
'id' => 123,
'title' => 'Sample Post',
'category' => (object) [
'id' => 456,
'title' => 'Sample Category',
],
];
}
public function testGenerate()
{
$breadcrumbs = Breadcrumbs::generate('post', $this->post);
$this->assertCount(3, $breadcrumbs);
$this->assertSame('Home', $breadcrumbs[0]->title);
$this->assertSame('/', $breadcrumbs[0]->url);
$this->assertTrue($breadcrumbs[0]->first);
$this->assertFalse($breadcrumbs[0]->last);
$this->assertSame('Sample Category', $breadcrumbs[1]->title);
$this->assertSame('/category/456', $breadcrumbs[1]->url);
$this->assertFalse($breadcrumbs[1]->first);
$this->assertFalse($breadcrumbs[1]->last);
$this->assertSame('Sample Post', $breadcrumbs[2]->title);
$this->assertSame('/blog/123', $breadcrumbs[2]->url);
$this->assertFalse($breadcrumbs[2]->first);
$this->assertTrue($breadcrumbs[2]->last);
}
public function testRender()
{
$html = Breadcrumbs::render('post', $this->post);
$this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/integration.html', $html);
}
}

View File

@@ -0,0 +1,80 @@
<?php
use DaveJamesMiller\Breadcrumbs\CurrentRoute;
use Mockery as m;
class CurrentRouteTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->currentRoute = app('DaveJamesMiller\Breadcrumbs\CurrentRoute');
}
public function testNamedRoute()
{
Route::get('/sample', ['as' => 'sampleroute', function()
{
$this->assertSame(['sampleroute', []], $this->currentRoute->get());
}]);
$this->call('GET', '/sample');
}
public function testNamedRouteWithParameters()
{
$object = new stdClass;
Route::bind('object', function() use ($object) {
return $object;
});
Route::get('/sample/{text}/{object}', ['as' => 'sampleroute', function() use ($object)
{
$this->assertSame(['sampleroute', ['blah', $object]], $this->currentRoute->get());
}]);
$this->call('GET', '/sample/blah/object');
}
/**
* @expectedException DaveJamesMiller\Breadcrumbs\Exception
* @expectedExceptionMessage The current route (GET /sample/unnamed) is not named - please check routes.php for an "as" parameter
*/
public function testUnnamedRoute()
{
Route::get('/sample/unnamed', function()
{
$this->assertSame(['sample', []], $this->currentRoute->get());
});
$this->call('GET', '/sample/unnamed');
}
public function testSet()
{
$this->currentRoute->set('custom', [1, 'blah']);
Route::get('/sample', ['as' => 'sampleroute', function()
{
$this->assertSame(['custom', [1, 'blah']], $this->currentRoute->get());
}]);
$this->call('GET', '/sample');
}
public function testClear()
{
$this->currentRoute->set('custom', [1, 'blah']);
$this->currentRoute->clear();
Route::get('/sample', ['as' => 'sampleroute', function()
{
$this->assertSame(['sampleroute', []], $this->currentRoute->get());
}]);
$this->call('GET', '/sample');
}
}

View File

@@ -0,0 +1,11 @@
<?php
class FacadeTest extends TestCase {
public function testFacade()
{
$this->assertInstanceOf('DaveJamesMiller\Breadcrumbs\Manager', Breadcrumbs::getFacadeRoot());
$this->assertSame($this->app['breadcrumbs'], Breadcrumbs::getFacadeRoot());
}
}

View File

@@ -0,0 +1,189 @@
<?php
use DaveJamesMiller\Breadcrumbs\Generator;
use Mockery as m;
class GeneratorTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->generator = new Generator;
}
public function testCallbacks()
{
$this->generator->generate([
'sample' => function($breadcrumbs)
{
$this->assertSame($this->generator, $breadcrumbs);
},
], 'sample', []);
}
public function testCallbackParameters()
{
$this->generator->generate([
'sample' => function($breadcrumbs, $num, $text)
{
$this->assertSame(1, $num);
$this->assertSame('blah', $text);
},
], 'sample', [1, 'blah']);
}
// $breadcrumbs->push($title)
// $breadcrumb->title
public function testPush_title()
{
$breadcrumbs = $this->generator->generate([
'sample' => function($breadcrumbs)
{
$breadcrumbs->push('Home');
},
], 'sample', []);
$this->assertCount(1, $breadcrumbs);
$this->assertSame('Home', $breadcrumbs[0]->title);
$this->assertNull($breadcrumbs[0]->url);
}
// $breadcrumbs->push($title, $url)
// $breadcrumb->url
public function testPush_title_url()
{
$breadcrumbs = $this->generator->generate([
'sample' => function($breadcrumbs)
{
$breadcrumbs->push('Home', '/');
},
], 'sample', []);
$this->assertCount(1, $breadcrumbs);
$this->assertSame('Home', $breadcrumbs[0]->title);
$this->assertSame('/', $breadcrumbs[0]->url);
}
// $breadcrumbs->push($title, $url, $data)
// $breadcrumb->custom_attribute_name
public function testPush_title_url_data()
{
$data = [
'foo' => 'bar',
'baz' => 'qux',
'title' => 'should not be overwritten by custom data',
];
$breadcrumbs = $this->generator->generate([
'sample' => function($breadcrumbs)
{
$breadcrumbs->push('Home', '/', ['foo' => 'bar', 'title' => 'ignored']);
},
], 'sample', []);
$this->assertCount(1, $breadcrumbs);
$this->assertSame('Home', $breadcrumbs[0]->title);
$this->assertSame('/', $breadcrumbs[0]->url);
$this->assertSame('bar', $breadcrumbs[0]->foo);
}
public function testPushMultipleTimes()
{
$breadcrumbs = $this->generator->generate([
'sample' => function($breadcrumbs)
{
$breadcrumbs->push('Level 1', '/1');
$breadcrumbs->push('Level 2', '/2');
$breadcrumbs->push('Level 3', '/3');
},
], 'sample', []);
$this->assertCount(3, $breadcrumbs);
$this->assertSame('Level 1', $breadcrumbs[0]->title);
$this->assertSame('Level 2', $breadcrumbs[1]->title);
$this->assertSame('Level 3', $breadcrumbs[2]->title);
$this->assertSame('/1', $breadcrumbs[0]->url);
$this->assertSame('/2', $breadcrumbs[1]->url);
$this->assertSame('/3', $breadcrumbs[2]->url);
}
// $breadcrumbs->parent($name)
public function testParent_name()
{
$breadcrumbs = $this->generator->generate([
'home' => function($breadcrumbs)
{
$breadcrumbs->push('Home', '/');
},
'sample' => function($breadcrumbs)
{
$breadcrumbs->parent('home');
$breadcrumbs->push('Page', '/page');
},
], 'sample', []);
$this->assertCount(2, $breadcrumbs);
$this->assertSame('Home', $breadcrumbs[0]->title);
$this->assertSame('/', $breadcrumbs[0]->url);
$this->assertSame('Page', $breadcrumbs[1]->title);
$this->assertSame('/page', $breadcrumbs[1]->url);
}
// $breadcrumbs->parent($name, $param1, ...)
public function testParent_name_params()
{
$breadcrumbs = $this->generator->generate([
'parent' => function($breadcrumbs, $num, $text)
{
$this->assertSame(1, $num);
$this->assertSame('blah', $text);
},
'sample' => function($breadcrumbs)
{
$breadcrumbs->parent('parent', 1, 'blah');
},
], 'sample', []);
}
// $breadcrumbs->parentArray($name, $params)
public function testParentArray_name_params()
{
$breadcrumbs = $this->generator->generate([
'parent' => function($breadcrumbs, $num, $text)
{
$this->assertSame(1, $num);
$this->assertSame('blah', $text);
},
'sample' => function($breadcrumbs)
{
$breadcrumbs->parentArray('parent', [1, 'blah']);
},
], 'sample', []);
}
// $breadcrumb->first
// $breadcrumb->last
public function testFirstLast()
{
$breadcrumbs = $this->generator->generate([
'sample' => function($breadcrumbs)
{
$breadcrumbs->push('Level 1', '/1');
$breadcrumbs->push('Level 2', '/2');
$breadcrumbs->push('Level 3', '/3');
},
], 'sample', []);
$this->assertCount(3, $breadcrumbs);
$this->assertTrue($breadcrumbs[0]->first, '$breadcrumbs[0]->first');
$this->assertFalse($breadcrumbs[1]->first, '$breadcrumbs[1]->first');
$this->assertFalse($breadcrumbs[2]->first, '$breadcrumbs[2]->first');
$this->assertFalse($breadcrumbs[0]->last, '$breadcrumbs[0]->last');
$this->assertFalse($breadcrumbs[1]->last, '$breadcrumbs[1]->last');
$this->assertTrue($breadcrumbs[2]->last, '$breadcrumbs[2]->last');
}
}

View File

@@ -0,0 +1,329 @@
<?php
use DaveJamesMiller\Breadcrumbs\Manager;
use Mockery as m;
class ManagerTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->currentRoute = m::mock('DaveJamesMiller\Breadcrumbs\CurrentRoute');
$this->generator = m::mock('DaveJamesMiller\Breadcrumbs\Generator');
$this->view = m::mock('DaveJamesMiller\Breadcrumbs\View');
$this->manager = new Manager($this->currentRoute, $this->generator, $this->view);
$this->manager->setView('view');
}
// Breadcrumbs::register($name, $callback) is tested by other methods
protected function register($name)
{
$this->manager->register($name, $fn = function() {
// We're not testing whether the callbacks are executed - see GeneratorTest
throw new Exception('Callback executed');
});
return $fn;
}
// Breadcrumbs::exists() -> boolean
public function testExists()
{
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->assertFalse($this->manager->exists());
$this->register('sample');
$this->assertTrue($this->manager->exists());
}
// Breadcrumbs::exists($name) -> boolean
public function testExists_name()
{
$this->assertFalse($this->manager->exists('sample'));
$this->register('sample');
$this->assertTrue($this->manager->exists('sample'));
}
// Breadcrumbs::generate() -> array
public function testGenerate()
{
$fn = $this->register('sample');
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->assertSame('generated', $this->manager->generate());
}
// Breadcrumbs::generate($name) -> array
public function testGenerate_name()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');;
$this->assertSame('generated', $this->manager->generate('sample'));
}
// Breadcrumbs::generate($name, $param1, ...) -> array
public function testGenerate_name_params()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->assertSame('generated', $this->manager->generate('sample', 1, 'blah'));
}
// Breadcrumbs::generateArray($name, $params) -> array
public function testGenerateArray_name_params()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->assertSame('generated', $this->manager->generateArray('sample', [1, 'blah']));
}
// Breadcrumbs::generateIfExists() -> array
public function testGenerateIfExists_existing()
{
$fn = $this->register('sample');
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->assertSame('generated', $this->manager->generateIfExists());
}
public function testGenerateIfExists_nonexistant()
{
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->never();
$this->assertSame([], $this->manager->generateIfExists());
}
// Breadcrumbs::generateIfExists($name) -> array
public function testGenerateIfExists_name_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');
$this->assertSame('generated', $this->manager->generateIfExists('sample'));
}
public function testGenerateIfExists_name_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->assertSame([], $this->manager->generateIfExists('sample'));
}
// Breadcrumbs::generateIfExists($name, $param1, ...) -> array
public function testGenerateIfExists_name_params_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->assertSame('generated', $this->manager->generateIfExists('sample', 1, 'blah'));
}
public function testGenerateIfExists_name_params_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->assertSame([], $this->manager->generateIfExists('sample', 1, 'blah'));
}
// Breadcrumbs::generateArrayIfExists($name, $params) -> array
public function testGenerateArrayIfExists_name_params_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->assertSame('generated', $this->manager->generateArrayIfExists('sample', [1, 'blah']));
}
public function testGenerateArrayIfExists_name_params_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->assertSame([], $this->manager->generateArrayIfExists('sample', [1, 'blah']));
}
// Breadcrumbs::render() -> array
public function testRender()
{
$fn = $this->register('sample');
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->render());
}
// Breadcrumbs::render($name) -> array
public function testRender_name()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');;
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->render('sample'));
}
// Breadcrumbs::render($name, $param1, ...) -> array
public function testRender_name_params()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->render('sample', 1, 'blah'));
}
// Breadcrumbs::renderArray($name, $params) -> array
public function testRenderArray_name_params()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->renderArray('sample', [1, 'blah']));
}
// Breadcrumbs::renderIfExists() -> array
public function testRenderIfExists_existing()
{
$fn = $this->register('sample');
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->renderIfExists());
}
public function testRenderIfExists_nonexistant()
{
$this->currentRoute->shouldReceive('get')->andReturn(['sample', [1, 'blah']]);
$this->generator->shouldReceive('generate')->never();
$this->view->shouldReceive('render')->never();
$this->assertSame('', $this->manager->renderIfExists());
}
// Breadcrumbs::renderIfExists($name) -> array
public function testRenderIfExists_name_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [])->once()->andReturn('generated');
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->renderIfExists('sample'));
}
public function testRenderIfExists_name_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->view->shouldReceive('render')->never();
$this->assertSame('', $this->manager->renderIfExists('sample'));
}
// Breadcrumbs::renderIfExists($name, $param1, ...) -> array
public function testRenderIfExists_name_params_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->renderIfExists('sample', 1, 'blah'));
}
public function testRenderIfExists_name_params_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->view->shouldReceive('render')->never();
$this->assertSame('', $this->manager->renderIfExists('sample', 1, 'blah'));
}
// Breadcrumbs::renderArrayIfExists($name, $params) -> array
public function testRenderArrayIfExists_name_params_existing()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');
$this->view->shouldReceive('render')->with('view', 'generated')->once()->andReturn('rendered');
$this->assertSame('rendered', $this->manager->renderArrayIfExists('sample', [1, 'blah']));
}
public function testRenderArrayIfExists_name_params_nonexistant()
{
$this->generator->shouldReceive('generate')->never();
$this->view->shouldReceive('render')->never();
$this->assertSame('', $this->manager->renderArrayIfExists('sample', [1, 'blah']));
}
// Breadcrumbs::setCurrentRoute($name)
public function testSetCurrentRoute_name()
{
$this->currentRoute->shouldReceive('set')->with('sample', [])->once();
$this->manager->setCurrentRoute('sample');
}
// Breadcrumbs::setCurrentRoute($name, $param1, ...)
public function testSetCurrentRoute_name_params()
{
$this->currentRoute->shouldReceive('set')->with('sample', [1, 'blah'])->once();
$this->manager->setCurrentRoute('sample', 1, 'blah');
}
// Breadcrumbs::setCurrentRouteArray($name, $params)
public function testSetCurrentRouteArray_name_params()
{
$this->currentRoute->shouldReceive('set')->with('sample', [1, 'blah'])->once();
$this->manager->setCurrentRouteArray('sample', [1, 'blah']);
}
// Breadcrumbs::clearCurrentRoute()
public function testClearCurrentRoute()
{
$this->currentRoute->shouldReceive('clear')->withNoArgs()->once();
$this->manager->clearCurrentRoute();
}
// Breadcrumbs::setView($view)
public function testSetView()
{
$fn = $this->register('sample');
$this->generator->shouldReceive('generate')->with(['sample' => $fn], 'sample', [1, 'blah'])->once()->andReturn('generated');;
$this->view->shouldReceive('render')->with('custom.view', 'generated')->once()->andReturn('rendered');
$this->manager->setView($view = 'custom.view');
$this->assertSame('rendered', $this->manager->render('sample', 1, 'blah'));
}
}

View File

@@ -0,0 +1,51 @@
<?php
class ViewTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->view = app('DaveJamesMiller\Breadcrumbs\View');
$this->breadcrumbs = [
(object) [
'title' => 'Home',
'url' => '/',
'first' => true,
'last' => false,
],
(object) [
'title' => 'Not a link',
'url' => null, // Test non-links
'first' => false,
'last' => false,
],
(object) [
'title' => 'Blog & < >', // Test HTML escaping
'url' => '/blog',
'first' => false,
'last' => false,
],
(object) [
'title' => 'Sample Post',
'url' => '/blog/123',
'first' => false,
'last' => true,
],
];
}
public function testBootstrap2()
{
$html = $this->view->render('breadcrumbs::bootstrap2', $this->breadcrumbs);
$this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/bootstrap2.html', $html);
}
public function testBootstrap3()
{
$html = $this->view->render('breadcrumbs::bootstrap3', $this->breadcrumbs);
$this->assertXmlStringEqualsXmlFile(__DIR__ . '/../fixtures/bootstrap3.html', $html);
}
}

View File

@@ -0,0 +1,22 @@
@if ($breadcrumbs)
<ul class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if ($breadcrumb->last)
<li class="active">
{{{ $breadcrumb->title }}}
</li>
@elseif ($breadcrumb->url)
<li>
<a href="{{{ $breadcrumb->url }}}">{{{ $breadcrumb->title }}}</a>
<span class="divider">/</span>
</li>
@else
{{-- Using .active to give it the right colour (grey by default) --}}
<li class="active">
{{{ $breadcrumb->title }}}
<span class="divider">/</span>
</li>
@endif
@endforeach
</ul>
@endif

View File

@@ -0,0 +1,11 @@
@if ($breadcrumbs)
<ol class="breadcrumb">
@foreach ($breadcrumbs as $breadcrumb)
@if ($breadcrumb->url && !$breadcrumb->last)
<li><a href="{{{ $breadcrumb->url }}}">{{{ $breadcrumb->title }}}</a></li>
@else
<li class="active">{{{ $breadcrumb->title }}}</li>
@endif
@endforeach
</ol>
@endif