Good day! Most of the projects we write on Yii2, because it is cool and we love it.
However, there is always something to improve (this is not hampered by the Yii architecture). I want to share a solution that simplifies the writing of navigation in applications on Yii2.
When we add a page to the application, we need to register the following things for it (after creating the controller and view):
$this->title = ...
);$this->params['breadcrumbs'][] = ...
);\yii\base\ActionFilter
in controller behaviors
);visible
with access check in all menus where there is a link to this page;\yii\web\UrlManager::rules
for a nice link;Isn't it a bit too much for "one more page"? The worst thing about this is that all these items need to be remembered and not forgotten. And if the navigation in the project begins to change, then it becomes even easier to break something, most often you forget about bread crumbs and they simply become not working.
We assumed that any page of the application should be included in the general site map. So, if you create such a site map (in the form of a multilevel tree) with comprehensive information about the page (see the items from the "Problem" section), then adding the page will be reduced to describing it in the site map, just in one place! We can register there both headings, and the rights and rules of links, and having a site map it is easy to get bread crumbs and sitemap.xml.
Thus, the [MegaMenu] () component was obtained, which I represent to the habrassocommunity.
Install the component via Composer:
$ composer require ExtPoint/yii2-megamenu
Next, we need to add a component to the application configuration:
As an application component:
'components' => [ 'megaMenu'=> [ 'class' => '\extpoint\megamenu\MegaMenu', 'items' => [ // You sitemap [ 'label' => '', 'url' => ['/site/index'], 'urlRule' => '/', ], ... ], ], ... ],
And load it before launching the application (to add rules to UrlManager
):
... 'bootstrap' => ['log', 'megamenu'], ...
API component was created as close as possible to Yii2, often repeating it 1 to 1.
\extpoint\megamenu\MegaMenu::items
parameter)Each item mostly corresponds to the navigation task format for \yii\bootstrap\Nav::items
, where each item has attributes label
, url
, visible
, active
, encode
, items
, options
, linkOptions
. Each item is specified as an array, from which an instance of the \extpoint\megamenu\MegaMenuItem
class is then created.
Below we list the new parameters that are not in \yii\bootstrap\Nav::items
:
urlRule
(string, array or instance \yii\rest\UrlRule
). The format matches the rule from \yii\web\UrlManager::rules
;roles
(string or array of strings). The format is identical to \yii\filters\AccessRule::roles
. Supported values are "?"
, "@"
and specifying the role as a string.order
(number) Each menu level is sorted according to this parameter. The default value is 0.\extpoint\megamenu\MegaMenu
setItems(array $items)
Adds menu items to the end of the list;addItems()
Adds menu items;getItems()
Returns the menu items;getActiveItem()
Returns the current route, similar to \Yii::$app->requestedRoute
, but with parsed parameters;getMenu(array $item, $custom)
Finds a nested menu item ( null
= root) and returns a nested menu with children. In the custom parameter, you can override the menu configuration by setting it as an array. If you specify a number, it will indicate the return nesting of the menu. For example, \Yii::$app->megaMenu->getMenu(null, 2)
will return a two-level menu, even if the menu itself has more nesting.getTitle($url = null)
Finds the item for the specified url
(default is the current page) and returns its titlegetFullTitle($url = null, $separator = ' — ')
Same as above, but also adds all the parent names of item'sgetBreadcrumbs($url = null)
Returns breadcrumbs for the widget \yii\widgets\Breadcrumbs::links
getItem($item, &$parents = [])
Finds item by url / route, adds item's parents for item to item's parentsgetItemUrl($item)
Finds item and returns its urlThe logic of comparing two item is implemented in the \extpoint\megamenu\MegaMenu::isUrlEquals
. Links are compared by comparing two lines.
Roads are compared a little more difficult: first they are normalized (getting a full route, indicating the module, controller and action), then only routes are compared. If the routes match, then the parameters are compared.
If the parameter is different from null, then its key and value are compared. If the value is specified as null, it means that there can be any value, only the presence of keys is compared.
Examples:
An example of a small web application with MegaMenu installed can be found in the tests folder:
However, there will be. MegaMenu has already been successfully used in several large projects. In our projects we always break the functionality into modules and MegaMenu does not resist this.
An example of such a breakdown and a more realistic example can be seen in our boilerplate . The menu is assembled in pieces from modules or controllers .
The component is still developing, here are some features that should be expected in the near future:
Thanks to all who read / leaf through to the end. Any suggestions and wishes write to affka@affka.ru
Put the stars on the githaba - ExtPoint / yii2-megamenu
Have a great day everyone!
Source: https://habr.com/ru/post/302954/
All Articles