Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/everlutionsk/navigation-bundle
https://github.com/everlutionsk/navigation-bundle
bundle navigation symfony
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/everlutionsk/navigation-bundle
- Owner: everlutionsk
- License: mit
- Created: 2016-12-11T20:10:00.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2024-11-07T16:49:44.000Z (2 months ago)
- Last Synced: 2024-11-07T17:43:14.292Z (2 months ago)
- Topics: bundle, navigation, symfony
- Language: PHP
- Size: 125 KB
- Stars: 2
- Watchers: 6
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Navigation Bundle
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/everlutionsk/navigation-bundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/everlutionsk/navigation-bundle/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/everlutionsk/navigation-bundle/badges/build.png?b=master)](https://scrutinizer-ci.com/g/everlutionsk/navigation-bundle/build-status/master)EverlutionNavigationBundle is Symfony Bundle for rendering multiple navigation instances registered dynamically by tagged services.
If you are looking just for Navigation library check out
[everlutionsk/navigation](https://github.com/everlutionsk/navigation)### Contents
- [Installation](#installation)
- [Download the bundle](#download-the-bundle)
- [Enable the bundle](#enable-the-bundle)
- [Configuration](#configuration)
- [Usage](#usage)
- [Create navigation items](#create-navigation-items)
- [Create container and register items](#create-container-and-register-items)
- [Register item to multiple containers from anywhere](#register-item-to-multiple-containers-from-anywhere)
- [Rendering the navigation](#rendering-the-navigation)
- [Adding route with parameters to navigation item](#adding-route-with-parameters-to-navigation-item)
- [Adding dynamic parameters to item route](#adding-dynamic-parameters-to-item-route)
- [Highlight the current item in navigation](#highlight-the-current-item-in-navigation)
- [Filtering the navigation items](#filtering-the-navigation-items)
- [Sorting the navigation items](#sorting-the-navigation-items)
- [Adding nested items](#adding-nested-items)
- [Rendering breadcrumbs](#rendering-breadcrumbs)
- [Translating the item labels](#translating-the-item-labels)
- [Rendering single navigation item](#rendering-single-navigation-item)
- [Troubleshooting](#troubleshooting)
- [TO DO's](#to-dos)## Installation
### Download the bundle
```console
$ composer require everlutionsk/navigation-bundle:^2
```### Enable the bundle
```php
idProvider = $idProvider;
}public function getLabel(): \Everlution\Navigation\Item\ItemLabelInterface
{
return new \Everlution\Navigation\Item\ItemLabel('navigation.edit_user.label');
}public function getRoute(): string
{
return 'edit_user_route';
}public function getParameters(): array
{
return [
'id' => $this->idProvider->getId(),
];
}
}
```Now register the navigation item with our `SampleNavigation`:
```yaml
# services.ymlservices:
# register EditUserItem
\UserIdProvider: ~
\EditUserItem:
arguments:
- '@\UserIdProvider'# add EditUserItem to SampleNavigation
\SampleNavigation:
calls:
- ['add', ['@\EditUserItem']]
tags:
- {name: 'everlution.navigation', alias: 'sample_navigation'}
```Sometimes when you just want to reuse some parameters from the current request. For that scenario we have prepared
`Everlution\NavigationBundle\Bridge\Item\RequestAttributesTrait`. It automatically injects
`Everlution\NavigationBundle\Bridge\Item\RequestAttributesContainer` via constructor which can fetch attributes from
current master request.Example:
```php
$this->requestAttributes->get('id'),
];
}
}
```We have prepared another useful helper method within `Everlution\NavigationBundle\Bridge\Item\RequestAttributesTrait`
which allows you to copy arguments from the request with the same names.Example:
```php
copyRequestAttributes(['id', '_token']);
}
}
```### Highlight the current item in navigation
When you want to highlight the current item within the navigation you need to implement `Everlution\Navigation\Item\MatchableInterface`
and provide array of matches by `getMatches(): Everlution\Navigation\Match\MatchInterface[]`.We have prepared 3 types of match:
- `Everlution\Navigation\Match\Voter\ExactMatch` which tries to find exact match
- `Everlution\Navigation\Match\Voter\PrefixMatch` which tries find the match by provided prefix
- `Everlution\Navigation\Match\Voter\RegexMatch` which tries to find the match by provided regular expressionThe bundle will try to find any match within current URL or route. After finding the first match the process of finding
the match ends so you should provide the most generic patterns first and the most specific ones at last. You can provide
multiple or none instances of each match type.Example:
```php
roleProvider = $rolesProvider;
array_map(
[$this, 'add'],
[
new \ItemFilteredByRole(),
// you can specify multiple items here
]
);
}public function getFilters(): array
{
return [
new \Everlution\Navigation\Filter\FilterByRole($this->roleProvider),
];
}
}
```In this scenario eg. when your `FilteredNavigation` returns `FilterByRole` within array of filters all of navigation items
added to the navigation must implement `Everlution\Navigation\Item\HasSupportedRolesInterface`. To avoid an exception
you can chain your filters by preceding the filters by `Everlution\Navigation\Filter\RemoveNotSupportedRoleFilter` which
will remove all items which don't implement the `Everlution\Navigation\Item\HasSupportedRolesInterface` interface before
running `FilterByRole` filter. No exception will be thrown because the filters are executed sequentially so at the time
the `FilterByRole` filter is running which expect all items to implement `Everlution\Navigation\Item\HasSupportedRolesInterface`
all other items has been already filtered out.```php
roleProvider),
];
}
// ...```
We have also provided non strict filter `Everlution\Navigation\Filter\FilterByRoleNonStrictly` which will ignore items
non implementing `Everlution\Navigation\Item\HasSupportedRolesInterface` causing showing these items within the final
navigation no matter what role is provided.### Sorting the navigation items
At the time of rendering the navigation the navigation container has being to transformed
to `Everlution\Navigation\OrderedContainer`. In this container all items which implements
`Everlution\Navigation\Item\SortableInterface` are being sorted by simple comparison function in ascending order and all
other items are appended to the end of the sorted items in its original order. Generally the items are ordered by the
order in which they were added to the container.By implementing the `Everlution\Navigation\OrderedContainer` you are defining the number (negative or positive) which
specifies the place within the ordered container - order is specified by ordering these numbers from the smallest
to the largest.```php
parameterProvider = $provider;
}public function getLabel(): \Everlution\Navigation\Item\ItemLabelInterface
{
return new \Everlution\NavigationBundle\Bridge\Item\TranslatableItemLabel(
'navigation.translatable_label_item.label',
['%first_parameter%' => $this->parameterProvider->getParameter()]
);
}
}
``````yaml
# messages.en.yml
navigation:
translatable_label_item:
label: 'Following parameter is provided by \ParameterProvider: %first_parameter%'
```### Rendering single navigation item
If you want to render single navigation item in Twig template only thing you need to do is register your item which
implements `Everlution\Navigation\Item\ItemInterface` as service and tag it with `everlution.navigation_item` with
appropriate alias like you can see in example below.```yaml
services:
AppBundle\Navigation\LogoutItem:
tags:
- { name: 'everlution.navigation_item', alias: 'logout_item' }
```You can then call pre-defined Twig function when you will provide the alias of the registered item. Optionally you can
define Twig template which is provided for you by default.```twig
{{ render_item('logout_item') }}
```## Troubleshooting
### Alias is not registered when you registered it
![Alias is not registered exception](doc/autowire-problem.png)
Sometimes when you use Symfony's auto-wire functionality for easier registering of services exception depicted above may
occur. In this case we have registered the `main_navigation` in external file `navigaiton.yml` which is being imported
to main `services.yml`. Navigation items and navigation instances are implemented within `AppBundle\Navigation` namespace
as you can see in following snippets.```yaml
# app/config/services/navigation.ymlservices:
_defaults:
autowire: true
autoconfigure: true# navigations
AppBundle\Navigation\MainNavigation:
tags:
- { name: 'everlution.navigation', alias: 'main_navigation' }
``````yaml
# app/config/services.ymlimports:
- { resource: "services/navigation.yml" }services:
_defaults:
autowire: true
autoconfigure: true
public: falseAppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'# ...
```
The problem here is that the tagged services from `navigation.yml` are being overwriteen by main autowire config without
the tags before the bundle can collect the tagged services. The solution here is to exclude `AppBundle\Navigation` from
default autowiring.```yaml
# app/config/services.yml# ...
services:
AppBundle\:
resource: '../../src/AppBundle/*'
exclude: '../../src/AppBundle/{Entity,Repository,Tests,Navigation}' # add Navigation here# ...
```
## To Do's
- dynamic generation of navigation (eg. implement items provider)