├── .gitignore
├── .travis.yml
├── DependencyInjection
├── Configuration.php
└── WhiteOctoberBreadcrumbsExtension.php
├── LICENSE
├── Model
├── Breadcrumbs.php
└── SingleBreadcrumb.php
├── README.md
├── Resources
├── config
│ └── breadcrumbs.xml
└── views
│ ├── breadcrumbs.html.twig
│ ├── json-ld.html.twig
│ └── microdata.html.twig
├── Templating
└── Helper
│ └── BreadcrumbsHelper.php
├── Test
├── AppKernel.php
├── BundleTest.php
├── bootstrap.php
└── config.xml
├── Twig
└── Extension
│ └── BreadcrumbsExtension.php
├── WhiteOctoberBreadcrumbsBundle.php
├── code-of-conduct.md
├── composer.json
└── phpunit.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | /vendor/
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | dist: trusty
4 |
5 | php:
6 | - 7.0
7 | - 7.1
8 | - 7.2
9 | - 7.3
10 | - 7.4snapshot
11 |
12 | matrix:
13 | include:
14 | - php: 7.1
15 | env: SYMFONY_VERSION=2.7.*
16 | - php: 7.1
17 | env: SYMFONY_VERSION=2.8.*
18 | - php: 7.1
19 | env: SYMFONY_VERSION=3.4.*
20 | - php: 7.1
21 | env: SYMFONY_VERSION="4.1.*"
22 | - php: 7.1
23 | env: SYMFONY_VERSION="4.2.*"
24 |
25 | sudo: false
26 |
27 | cache:
28 | directories:
29 | - $HOME/.composer/cache/files
30 |
31 | before_install:
32 | - composer self-update
33 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require --dev --no-update symfony/symfony=$SYMFONY_VERSION; fi
34 | - INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini;
35 | - echo memory_limit = -1 >> $INI_FILE
36 |
37 | install:
38 | - composer install
39 |
40 | script:
41 | - vendor/bin/phpunit
42 |
--------------------------------------------------------------------------------
/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 | getRootNode();
21 | } else {
22 | // BC layer for symfony/config 4.1 and older
23 | $rootNode = $treeBuilder->root("white_october_breadcrumbs");
24 | }
25 |
26 | $rootNode->
27 | children()->
28 | scalarNode("separator")->defaultValue("/")->end()->
29 | scalarNode("separatorClass")->defaultValue("separator")->end()->
30 | scalarNode("listId")->defaultValue("wo-breadcrumbs")->end()->
31 | scalarNode("listClass")->defaultValue("breadcrumb")->end()->
32 | scalarNode("itemClass")->defaultValue("")->end()->
33 | scalarNode("linkRel")->defaultValue("")->end()->
34 | scalarNode("locale")->defaultNull()->end()->
35 | scalarNode("translation_domain")->defaultNull()->end()->
36 | scalarNode("viewTemplate")->defaultValue("WhiteOctoberBreadcrumbsBundle::microdata.html.twig")->end()->
37 | end()
38 | ;
39 |
40 | return $treeBuilder;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/DependencyInjection/WhiteOctoberBreadcrumbsExtension.php:
--------------------------------------------------------------------------------
1 | loadConfiguration($configs, $container);
22 |
23 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
24 | $loader->load('breadcrumbs.xml');
25 | }
26 |
27 | /**
28 | * Loads the configuration in, with any defaults
29 | *
30 | * @param array $configs
31 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
32 | */
33 | protected function loadConfiguration(array $configs, ContainerBuilder $container)
34 | {
35 | $configuration = new Configuration();
36 | $config = $this->processConfiguration($configuration, $configs);
37 |
38 | if($config['viewTemplate'] === 'WhiteOctoberBreadcrumbsBundle::breadcrumbs.html.twig') {
39 | trigger_error(
40 | 'Using viewTemplate "'.$config['viewTemplate'].'"" is deprecated and should be replaced by ' .
41 | '"WhiteOctoberBreadcrumbsBundle::microdata.html.twig"',
42 | E_USER_DEPRECATED
43 | );
44 | }
45 |
46 | $container->setParameter("white_october_breadcrumbs.options", $config);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2012 White October Ltd
2 | http://www.whiteoctober.co.uk/
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Model/Breadcrumbs.php:
--------------------------------------------------------------------------------
1 | array()
13 | );
14 |
15 | /**
16 | * @var RouterInterface
17 | */
18 | private $router;
19 |
20 | /**
21 | * @param string $text #TranslationKey
22 | */
23 | public function addItem($text, $url = "", array $translationParameters = array(), $translate = true)
24 | {
25 | return $this->addNamespaceItem(self::DEFAULT_NAMESPACE, $text, $url, $translationParameters, $translate);
26 | }
27 |
28 | /**
29 | * @param string $text #TranslationKey
30 | */
31 | public function addNamespaceItem($namespace, $text, $url = "", array $translationParameters = array(), $translate = true)
32 | {
33 | $b = new SingleBreadcrumb($text, $url, $translationParameters, $translate);
34 | $this->breadcrumbs[$namespace][] = $b;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * @param string $text #TranslationKey
41 | */
42 | public function prependItem($text, $url = "", array $translationParameters = array(), $translate = true)
43 | {
44 | return $this->prependNamespaceItem(self::DEFAULT_NAMESPACE, $text, $url, $translationParameters, $translate);
45 | }
46 |
47 | /**
48 | * @param string $text #TranslationKey
49 | */
50 | public function prependNamespaceItem($namespace, $text, $url = "", array $translationParameters = array(), $translate = true)
51 | {
52 | $b = new SingleBreadcrumb($text, $url, $translationParameters, $translate);
53 | array_unshift($this->breadcrumbs[$namespace], $b);
54 |
55 | return $this;
56 | }
57 |
58 | /**
59 | * @param string $text #TranslationKey
60 | * @param string $route #Route
61 | */
62 | public function addRouteItem($text, $route, array $parameters = array(), $referenceType = RouterInterface::ABSOLUTE_PATH, array $translationParameters = array(), $translate = true)
63 | {
64 | return $this->addNamespaceRouteItem(self::DEFAULT_NAMESPACE, $text, $route, $parameters, $referenceType, $translationParameters, $translate);
65 | }
66 |
67 | /**
68 | * @param string $text #TranslationKey
69 | * @param string $route #Route
70 | */
71 | public function addNamespaceRouteItem($namespace, $text, $route, array $parameters = array(), $referenceType = RouterInterface::ABSOLUTE_PATH, array $translationParameters = array(), $translate = true)
72 | {
73 | $url = $this->router->generate($route, $parameters, $referenceType);
74 |
75 | return $this->addNamespaceItem($namespace, $text, $url, $translationParameters, $translate);
76 | }
77 |
78 | /**
79 | * @param string $text #TranslationKey
80 | * @param string $route #Route
81 | */
82 | public function prependRouteItem($text, $route, array $parameters = array(), $referenceType = RouterInterface::ABSOLUTE_PATH, array $translationParameters = array(), $translate = true)
83 | {
84 | return $this->prependNamespaceRouteItem(self::DEFAULT_NAMESPACE, $text, $route, $parameters, $referenceType, $translationParameters, $translate);
85 | }
86 |
87 | /**
88 | * @param string $text #TranslationKey
89 | * @param string $route #Route
90 | */
91 | public function prependNamespaceRouteItem($namespace, $text, $route, array $parameters = array(), $referenceType = RouterInterface::ABSOLUTE_PATH, array $translationParameters = array(), $translate = true)
92 | {
93 | $url = $this->router->generate($route, $parameters, $referenceType);
94 |
95 | return $this->prependNamespaceItem($namespace, $text, $url, $translationParameters, $translate);
96 | }
97 |
98 | /**
99 | * @param string $text #TranslationKey
100 | */
101 | public function addObjectArray(array $objects, $text, $url = "", array $translationParameters = array(), $translate = true)
102 | {
103 | return $this->addNamespaceObjectArray(self::DEFAULT_NAMESPACE, $objects, $text, $url, $translationParameters, $translate);
104 | }
105 |
106 | /**
107 | * @param string $text #TranslationKey
108 | */
109 | public function addNamespaceObjectArray($namespace, array $objects, $text, $url = "", array $translationParameters = array(), $translate = true)
110 | {
111 | foreach($objects as $object) {
112 | $itemText = $this->validateArgument($object, $text);
113 | if ($url != "") {
114 | $itemUrl = $this->validateArgument($object, $url);
115 | } else {
116 | $itemUrl = "";
117 | }
118 | $this->addNamespaceItem($namespace, $itemText, $itemUrl, $translationParameters, $translate);
119 | }
120 |
121 | return $this;
122 | }
123 |
124 | public function clear($namespace = "")
125 | {
126 | if (strlen($namespace)) {
127 | $this->breadcrumbs[$namespace] = array();
128 | } else {
129 | $this->breadcrumbs = array(
130 | self::DEFAULT_NAMESPACE => array()
131 | );
132 | }
133 |
134 | return $this;
135 | }
136 |
137 | /**
138 | * @param string $text #TranslationKey
139 | */
140 | public function addObjectTree($object, $text, $url = "", $parent = 'parent', array $translationParameters = array(), $firstPosition = -1)
141 | {
142 | return $this->addNamespaceObjectTree(self::DEFAULT_NAMESPACE, $object, $text, $url, $parent, $translationParameters, $firstPosition);
143 | }
144 |
145 | /**
146 | * @param string $text #TranslationKey
147 | */
148 | public function addNamespaceObjectTree($namespace, $object, $text, $url = "", $parent = 'parent', array $translationParameters = array(), $firstPosition = -1)
149 | {
150 | $itemText = $this->validateArgument($object, $text);
151 | if ($url != "") {
152 | $itemUrl = $this->validateArgument($object, $url);
153 | } else {
154 | $itemUrl = "";
155 | }
156 | $itemParent = $this->validateArgument($object, $parent);
157 | if ($firstPosition == -1) {
158 | $firstPosition = sizeof($this->breadcrumbs);
159 | }
160 | $b = new SingleBreadcrumb($itemText, $itemUrl, $translationParameters);
161 | array_splice($this->breadcrumbs[$namespace], $firstPosition, 0, array($b));
162 | if ($itemParent) {
163 | $this->addNamespaceObjectTree($namespace, $itemParent, $text, $url, $parent, $translationParameters, $firstPosition);
164 | }
165 | return $this;
166 | }
167 |
168 | public function getNamespaceBreadcrumbs($namespace = self::DEFAULT_NAMESPACE)
169 | {
170 | // Check whether requested namespace breadcrumbs is exists
171 | if (!$this->hasNamespaceBreadcrumbs($namespace)) {
172 | throw new \InvalidArgumentException(sprintf(
173 | 'The breadcrumb namespace "%s" does not exist', $namespace
174 | ));
175 | }
176 |
177 | return $this->breadcrumbs[$namespace];
178 | }
179 |
180 | /**
181 | * @param string $namespace
182 | * @return bool
183 | */
184 | public function hasNamespaceBreadcrumbs($namespace = self::DEFAULT_NAMESPACE)
185 | {
186 | return isset($this->breadcrumbs[$namespace]);
187 | }
188 |
189 | /**
190 | * @param RouterInterface $router
191 | */
192 | public function setRouter(RouterInterface $router)
193 | {
194 | $this->router = $router;
195 | }
196 |
197 | public function rewind($namespace = self::DEFAULT_NAMESPACE)
198 | {
199 | return reset($this->breadcrumbs[$namespace]);
200 | }
201 |
202 | public function current($namespace = self::DEFAULT_NAMESPACE)
203 | {
204 | return current($this->breadcrumbs[$namespace]);
205 | }
206 |
207 | public function key($namespace = self::DEFAULT_NAMESPACE)
208 | {
209 | return key($this->breadcrumbs[$namespace]);
210 | }
211 |
212 | public function next($namespace = self::DEFAULT_NAMESPACE)
213 | {
214 | return next($this->breadcrumbs[$namespace]);
215 | }
216 |
217 | public function valid($namespace = self::DEFAULT_NAMESPACE)
218 | {
219 | return null !== key($this->breadcrumbs[$namespace]);
220 | }
221 |
222 | public function offsetExists($offset, $namespace = self::DEFAULT_NAMESPACE)
223 | {
224 | return isset($this->breadcrumbs[$namespace][$offset]);
225 | }
226 |
227 | public function offsetSet($offset, $value, $namespace = self::DEFAULT_NAMESPACE)
228 | {
229 | $this->breadcrumbs[$namespace][$offset] = $value;
230 | }
231 |
232 | public function offsetGet($offset, $namespace = self::DEFAULT_NAMESPACE)
233 | {
234 | return isset($this->breadcrumbs[$namespace][$offset]) ? $this->breadcrumbs[$namespace][$offset] : null;
235 | }
236 |
237 | public function offsetUnset($offset, $namespace = self::DEFAULT_NAMESPACE)
238 | {
239 | unset($this->breadcrumbs[$namespace][$offset]);
240 | }
241 |
242 | public function count($namespace = self::DEFAULT_NAMESPACE)
243 | {
244 | return count($this->breadcrumbs[$namespace]);
245 | }
246 |
247 | private function validateArgument($object, $argument)
248 | {
249 | if (is_callable($argument)) {
250 | return $argument($object);
251 | }
252 |
253 | $getter = 'get' . ucfirst($argument);
254 | if (method_exists($object, $getter)) {
255 | return call_user_func(array(&$object, $getter), $getter);
256 | }
257 |
258 | throw new \InvalidArgumentException(sprintf(
259 | 'Neither a valid callback function passed nor a method with the name %s() is exists', $getter
260 | ));
261 | }
262 | }
263 |
--------------------------------------------------------------------------------
/Model/SingleBreadcrumb.php:
--------------------------------------------------------------------------------
1 | url = $url;
15 | $this->text = $text;
16 | $this->translationParameters = $translationParameters;
17 | $this->translate = $translate;
18 | }
19 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > WARNING: This project is **no longer maintained**.
2 | > If you are using it with Symfony >= 4.3, you may want to use [this fork](https://github.com/mhujer/BreadcrumbsBundle) instead.
3 |
4 | Installation
5 | ============
6 |
7 | 1. Configure templating for your application if you haven't already. For example:
8 |
9 | ```yaml
10 | # app/config/config.yml (Symfony <=3)
11 | framework:
12 | templating:
13 | engines: ['twig']
14 |
15 | # config/packages/framework.yaml (Symfony 4)
16 | templating:
17 | engines: ['twig']
18 | ```
19 |
20 | 2. Install this bundle using [Composer](https://getcomposer.org/):
21 |
22 | ``` bash
23 | composer require whiteoctober/breadcrumbs-bundle
24 | ```
25 |
26 | 3. Add this bundle to your application's kernel:
27 |
28 | ``` php
29 | // app/AppKernel.php
30 | public function registerBundles()
31 | {
32 | $bundles = array(
33 | // ...
34 | new WhiteOctober\BreadcrumbsBundle\WhiteOctoberBreadcrumbsBundle(),
35 | // ...
36 | );
37 | }
38 | ```
39 |
40 | If you're using Symfony 4, this step will be done for you by Symfony Flex.
41 |
42 | 4. Configure the bundle in your config:
43 |
44 | ``` yaml
45 | # app/config/config.yml
46 | white_october_breadcrumbs: ~
47 | ```
48 |
49 | That's it for basic configuration. For more options check the [Configuration](#configuration) section.
50 |
51 | Usage
52 | =====
53 |
54 | In your application controller methods:
55 |
56 | ``` php
57 | public function yourAction(User $user)
58 | {
59 | $breadcrumbs = $this->get("white_october_breadcrumbs");
60 |
61 | // Simple example
62 | $breadcrumbs->addItem("Home", $this->get("router")->generate("index"));
63 |
64 | // Example without URL
65 | $breadcrumbs->addItem("Some text without link");
66 |
67 | // Example with parameter injected into translation "user.profile"
68 | $breadcrumbs->addItem($txt, $url, ["%user%" => $user->getName()]);
69 | }
70 | ```
71 |
72 | For Symfony 4, don't retrieve the service via `get`, instead use
73 | [dependency injection](https://symfony.com/doc/current/service_container.html#fetching-and-using-services):
74 |
75 | ```php
76 | use WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs;
77 |
78 | class YourController extends AbstractController
79 | {
80 | public function yourAction(Breadcrumbs $breadcrumbs)
81 | {
82 | // ...
83 | }
84 | }
85 | ```
86 |
87 |
88 | Then, in your template:
89 |
90 | ``` jinja
91 | {{ wo_render_breadcrumbs() }}
92 | ```
93 |
94 | The last item in the breadcrumbs collection will automatically be rendered
95 | as plain text rather than a `...` tag.
96 |
97 | The `addItem()` method adds an item to the *end* of the breadcrumbs collection.
98 | You can use the `prependItem()` method to add an item to the *beginning* of
99 | the breadcrumbs collection. This is handy when used in conjunction with
100 | hierarchical data (e.g. Doctrine Nested-Set). This example uses categories in
101 | a product catalog:
102 |
103 | ``` php
104 | public function yourAction(Category $category)
105 | {
106 | $breadcrumbs = $this->get("white_october_breadcrumbs");
107 |
108 | $node = $category;
109 |
110 | while ($node) {
111 | $breadcrumbs->prependItem($node->getName(), "");
112 |
113 | $node = $node->getParent();
114 | }
115 | }
116 | ```
117 |
118 | If you do not want to generate a URL manually, you can easily add breadcrumb items
119 | passing only the route name with any required parameters, using the `addRouteItem()`
120 | and `prependRouteItem()` methods:
121 |
122 | ``` php
123 | public function yourAction()
124 | {
125 | $breadcrumbs = $this->get("white_october_breadcrumbs");
126 |
127 | // Pass "_demo" route name without any parameters
128 | $breadcrumbs->addRouteItem("Demo", "_demo");
129 |
130 | // Pass "_demo_hello" route name with route parameters
131 | $breadcrumbs->addRouteItem("Hello Breadcrumbs", "_demo_hello", [
132 | 'name' => 'Breadcrumbs',
133 | ]);
134 |
135 | // Add "homepage" route link at the start of the breadcrumbs
136 | $breadcrumbs->prependRouteItem("Home", "homepage");
137 | }
138 | ```
139 |
140 | Configuration
141 | =============
142 |
143 | The following *default* parameters can be overriden in your `config.yml` or similar:
144 |
145 | ``` yaml
146 | # app/config/config.yml
147 | white_october_breadcrumbs:
148 | separator: '/'
149 | separatorClass: 'separator'
150 | listId: 'wo-breadcrumbs'
151 | listClass: 'breadcrumb'
152 | itemClass: ''
153 | linkRel: ''
154 | locale: ~ # defaults to null, so the default locale is used
155 | translation_domain: ~ # defaults to null, so the default domain is used
156 | viewTemplate: 'WhiteOctoberBreadcrumbsBundle::microdata.html.twig'
157 | ```
158 |
159 | These can also be passed as parameters in the view when rendering the
160 | breadcrumbs - for example:
161 |
162 | ``` jinja
163 | {{ wo_render_breadcrumbs({separator: '>', listId: 'breadcrumbs'}) }}
164 | ```
165 |
166 | > **NOTE:** If you need more than one set of breadcrumbs on the same page you can use namespaces.
167 | By default, breadcrumbs use the `default` namespace, but you can add more.
168 | To add breadcrumbs to your custom namespace use `addNamespaceItem` / `prependNamespaceItem`
169 | or `addNamespaceRouteItem` / `prependNamespaceRouteItem` methods respectively, for example:
170 |
171 | ``` php
172 | public function yourAction(User $user)
173 | {
174 | $breadcrumbs = $this->get("white_october_breadcrumbs");
175 |
176 | // Simple example
177 | $breadcrumbs->prependNamespaceItem("subsection", "Home", $this->get("router")->generate("index"));
178 |
179 | // Example without URL
180 | $breadcrumbs->addNamespaceItem("subsection", "Some text without link");
181 |
182 | // Example with parameter injected into translation "user.profile"
183 | $breadcrumbs->addNamespaceItem("subsection", $txt, $url, ["%user%" => $user->getName()]);
184 |
185 | // Example with route name with required parameters
186 | $breadcrumbs->addNamespaceRouteItem("subsection", $user->getName(), "user_show", ["id" => $user->getId()]);
187 | }
188 | ```
189 |
190 | Then to render the `subsection` breadcrumbs in your templates, specify this namespace in the options:
191 |
192 | ``` jinja
193 | {{ wo_render_breadcrumbs({namespace: "subsection"}) }}
194 | ```
195 |
196 | Advanced Usage
197 | ==============
198 |
199 | You can add a whole array of objects at once
200 |
201 | ``` php
202 | $breadcrumbs->addObjectArray(array $objects, $text, $url, $translationParameters);
203 | ```
204 |
205 | ```
206 | objects: array of objects
207 | text: name of object property or closure
208 | url: name of URL property or closure
209 | ```
210 |
211 | Example:
212 |
213 | ``` php
214 | $that = $this;
215 | $breadcrumbs->addObjectArray($selectedPath, "name", function($object) use ($that) {
216 | return $that->generateUrl('_object_index', ['slug' => $object->getSlug()]);
217 | });
218 | ```
219 |
220 | You can also add a tree path
221 |
222 | ``` php
223 | $breadcrumbs->addObjectTree($object, $text, $url = "", $parent = 'parent', array $translationParameters = [], $firstPosition = -1)
224 | ```
225 |
226 | ```
227 | object: object to start with
228 | text: name of object property or closure
229 | url: name of URL property or closure
230 | parent: name of parent property or closure
231 | firstPosition: position to start inserting items (-1 = determine automatically)
232 | ```
233 |
234 | > **NOTE:** You can use `addNamespaceObjectArray` and `addNamespaceObjectTree` respectively
235 | for work with multiple breadcrumbs on the same page.
236 |
237 | Overriding the template
238 | =======================
239 |
240 | There are two methods for doing this.
241 |
242 | 1. You can override the template used by copying the
243 | `Resources/views/microdata.html.twig` file out of the bundle and placing it
244 | into `app/Resources/WhiteOctoberBreadcrumbsBundle/views`, then customising
245 | as you see fit. Check the [Overriding bundle templates][1] documentation section
246 | for more information.
247 |
248 | 2. Use the `viewTemplate` configuration parameter:
249 |
250 | ``` jinja
251 | {{ wo_render_breadcrumbs({ viewTemplate: "YourOwnBundle::yourBreadcrumbs.html.twig" }) }}
252 | ```
253 | > **NOTE:** If you want to use the JSON-LD format, there's already an existing template
254 | at `WhiteOctoberBreadcrumbsBundle::json-ld.html.twig`. Just set this template as the value for
255 | `viewTemplate` either in your Twig function call (see Step 2 above) or in your bundle [configuration](#configuration).
256 |
257 |
258 |
259 | [1]: http://symfony.com/doc/current/book/templating.html#overriding-bundle-templates
260 | [2]: https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx
261 |
262 |
263 | _(This project was originally at https://github.com/whiteoctober/BreadcrumbsBundle)_
264 |
--------------------------------------------------------------------------------
/Resources/config/breadcrumbs.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | %white_october_breadcrumbs.options%
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Resources/views/breadcrumbs.html.twig:
--------------------------------------------------------------------------------
1 | {% include "WhiteOctoberBreadcrumbsBundle::microdata.html.twig" %}
2 |
--------------------------------------------------------------------------------
/Resources/views/json-ld.html.twig:
--------------------------------------------------------------------------------
1 | {% if wo_breadcrumbs()|length %}
2 | {% apply spaceless %}
3 |
23 | {% endapply %}
24 | {% endif %}
25 |
--------------------------------------------------------------------------------
/Resources/views/microdata.html.twig:
--------------------------------------------------------------------------------
1 | {% if wo_breadcrumbs()|length %}
2 | {% apply spaceless %}
3 |
4 | {% for b in breadcrumbs %}
5 | -
6 | {% if b.url and not loop.last %}
7 |
8 | {% endif %}
9 | {% if b.translate is defined and b.translate == true %}{{- b.text | trans(b.translationParameters, translation_domain, locale) -}}{% else %}{{- b.text -}}{% endif %}
10 | {% if b.url and not loop.last %}
11 |
12 | {% elseif b.url %}
13 |
14 | {% endif %}
15 |
16 |
17 | {% if separator is not null and not loop.last %}
18 | {{ separator }}
19 | {% endif %}
20 |
21 | {% endfor %}
22 |
23 | {% endapply %}
24 | {% endif %}
25 |
--------------------------------------------------------------------------------
/Templating/Helper/BreadcrumbsHelper.php:
--------------------------------------------------------------------------------
1 | templating = $templating;
34 | $this->breadcrumbs = $breadcrumbs;
35 | $this->options = array_merge($options, array(
36 | 'namespace' => Breadcrumbs::DEFAULT_NAMESPACE, // inject default namespace to options
37 | ));
38 | }
39 |
40 | /**
41 | * Returns the HTML for the namespace breadcrumbs
42 | *
43 | * @param array $options The user-supplied options from the view
44 | * @return string A HTML string
45 | */
46 | public function breadcrumbs(array $options = array())
47 | {
48 | $options = $this->resolveOptions($options);
49 |
50 | // Assign namespace breadcrumbs
51 | $options["breadcrumbs"] = $this->breadcrumbs->getNamespaceBreadcrumbs($options['namespace']);
52 |
53 | return $this->templating->render(
54 | $options["viewTemplate"],
55 | $options
56 | );
57 | }
58 |
59 | /**
60 | * {@inheritdoc}
61 | * @codeCoverageIgnore
62 | */
63 | public function getName()
64 | {
65 | return 'breadcrumbs';
66 | }
67 |
68 | /**
69 | * Merges user-supplied options from the view
70 | * with base config values
71 | *
72 | * @param array $options The user-supplied options from the view
73 | * @return array
74 | */
75 | private function resolveOptions(array $options = array())
76 | {
77 | return array_merge($this->options, $options);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Test/AppKernel.php:
--------------------------------------------------------------------------------
1 | cachePrefix = $cachePrefix;
34 | $this->addBundle(FrameworkBundle::class);
35 | $this->addConfigFile(__DIR__.'/config.xml');
36 | $this->addConfigFile(__DIR__.'/../Resources/config/breadcrumbs.xml');
37 | }
38 |
39 | public function addBundle($bundleClassName)
40 | {
41 | $this->bundlesToRegister[] = $bundleClassName;
42 | }
43 |
44 | public function registerBundles()
45 | {
46 | $this->bundlesToRegister = array_unique($this->bundlesToRegister);
47 | $bundles = [];
48 | foreach ($this->bundlesToRegister as $bundle) {
49 | $bundles[] = new $bundle();
50 | }
51 |
52 | return $bundles;
53 | }
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function registerContainerConfiguration(LoaderInterface $loader)
58 | {
59 | $loader->load(function (ContainerBuilder $container) use ($loader) {
60 | $this->configFiles = array_unique($this->configFiles);
61 | foreach ($this->configFiles as $path) {
62 | $loader->load($path);
63 | }
64 |
65 | $container->addObjectResource($this);
66 | $container->setParameter('white_october_breadcrumbs.options', []);
67 | });
68 | }
69 | /**
70 | * @param string $configFile path to config file
71 | */
72 | public function addConfigFile($configFile)
73 | {
74 | $this->configFiles[] = $configFile;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Test/BundleTest.php:
--------------------------------------------------------------------------------
1 | getContainer();
15 |
16 | // Test if the service exists
17 | $this->assertTrue($container->has('white_october_breadcrumbs.helper'));
18 |
19 | $service = $container->get('white_october_breadcrumbs.helper');
20 | $this->assertInstanceOf(\WhiteOctober\BreadcrumbsBundle\Templating\Helper\BreadcrumbsHelper::class, $service);
21 | }
22 |
23 | public static function getKernelClass()
24 | {
25 | return \WhiteOctober\BreadcrumbsBundle\Test\AppKernel::class;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Test/bootstrap.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | php
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Twig/Extension/BreadcrumbsExtension.php:
--------------------------------------------------------------------------------
1 | container = $container;
20 | $this->breadcrumbs = $container->get("white_october_breadcrumbs");
21 | }
22 |
23 | /**
24 | * {@inheritdoc}
25 | */
26 | public function getFunctions()
27 | {
28 | return array(
29 | new \Twig_SimpleFunction("wo_breadcrumbs", array($this, "getBreadcrumbs")),
30 | new \Twig_SimpleFunction("wo_breadcrumbs_exists", array($this, "hasBreadcrumbs")),
31 | new \Twig_SimpleFunction("wo_render_breadcrumbs", array($this, "renderBreadcrumbs"), array("is_safe" => array("html"))),
32 | );
33 | }
34 |
35 | /**
36 | * {@inheritdoc}
37 | */
38 | public function getFilters()
39 | {
40 | return array(
41 | new \Twig_SimpleFilter("wo_is_final_breadcrumb", array($this, "isLastBreadcrumb")),
42 | );
43 | }
44 |
45 | /**
46 | * Returns the breadcrumbs object
47 | *
48 | * @param string $namespace
49 | * @return \WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs
50 | */
51 | public function getBreadcrumbs($namespace = Breadcrumbs::DEFAULT_NAMESPACE)
52 | {
53 | return $this->breadcrumbs->getNamespaceBreadcrumbs($namespace);
54 | }
55 |
56 | /**
57 | * @param string $namespace
58 | * @return bool
59 | */
60 | public function hasBreadcrumbs($namespace = Breadcrumbs::DEFAULT_NAMESPACE)
61 | {
62 | return $this->breadcrumbs->hasNamespaceBreadcrumbs($namespace);
63 | }
64 |
65 | /**
66 | * Renders the breadcrumbs in a list
67 | *
68 | * @param array $options
69 | * @return string
70 | */
71 | public function renderBreadcrumbs(array $options = array())
72 | {
73 | return $this->container->get("white_october_breadcrumbs.helper")->breadcrumbs($options);
74 | }
75 |
76 | /**
77 | * Checks if this breadcrumb is the last one in the collection
78 | *
79 | * @param SingleBreadcrumb $crumb
80 | * @param string $namespace
81 | * @return bool
82 | */
83 | public function isLastBreadcrumb(SingleBreadcrumb $crumb, $namespace = Breadcrumbs::DEFAULT_NAMESPACE)
84 | {
85 | $offset = $this->breadcrumbs->count($namespace) - 1;
86 |
87 | return $crumb === $this->breadcrumbs->offsetGet($offset, $namespace);
88 | }
89 |
90 | /**
91 | * {@inheritdoc}
92 | */
93 | public function getName()
94 | {
95 | return "breadcrumbs";
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/WhiteOctoberBreadcrumbsBundle.php:
--------------------------------------------------------------------------------
1 | =5.3.2",
16 | "symfony/framework-bundle": "~2.0|~3.0|^4.0",
17 | "symfony/templating": "~2.7|~3.0|^4.0"
18 | },
19 | "require-dev": {
20 | "phpunit/phpunit": "^6.4",
21 | "symfony/browser-kit": "~2.7|~3.0|^4.0"
22 | },
23 | "abandoned": "mhujer/breadcrumbs-bundle",
24 | "autoload": {
25 | "psr-0": { "WhiteOctober\\BreadcrumbsBundle": "" }
26 | },
27 | "target-dir": "WhiteOctober/BreadcrumbsBundle"
28 | }
29 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Test/
7 |
8 |
9 |
10 |
11 |
12 | /
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------