Adds a simple implementation for an automatic generation of a page tree to build a menu.
Install the bundle via packagist:
// ...
require: {
// ...
"becklyn/page-tree-bundle": "~1.0"
},
// ...
Load the bundle in your app/AppKernel.php
:
public function registerBundles()
{
$bundles = array(
// ...
new \Becklyn\PageTreeBundle\BecklynPageTreeBundle(),
);
// ...
}
You add elements to the page tree by setting the options of the routes:
homepage:
path: /
my_route:
path: /my_route
options:
page_tree:
parent: homepage
title: "My Route"
All routes without the page_tree
option are not included in the page tree.
You can directly get the service becklyn.page_tree
and load the page tree from there.
$pageTreeModel = $container->get("becklyn.page_tree");
// the complete page tree
$tree1 = $pageTreeModel->getPageTree();
// the tree under my_route, including all child nodes, excluding my_route
$tree2 = $pageTreeModel->getPageTree("my_route");
The return value is a list of nodes.
route:
options:
page_tree:
parent: homepage # the name of the parent node
is_root: false # whether this is a root node
title: "abc" # (optional) title of the node
hidden: false # (optional) whether the node should be hidden when rendering
parameters: {} # (optional) the default values for the parameters
separator: null # (optional) where to place a separator
Either parent
or is_root
(must be true
) must be set.
Also all referenced parent
-routes need to exist.
Notice: if you pass both parent
and is_root
the parent will be discarded and it will be a root page.
Hidden
The hidden
flag hides the menu item (including all children) when rendering:
<ul>
<!-- ... -->
<li style="display:none">
<a href="#">This is hidden</a>
</li>
<!-- ... -->
</ul>
This is necessary, because currently (v2.0.0@alpha) there is only one pagetree in the KnpMenuBundle, which is used for both rendering and voting on the active element. So if you want to display active parents without including the actual element in the menu, it needs to be in the tree, but hidden in the generated HTML.
Please note: if you use the bootstrap menu renderer, the hidden items are correctly stripped from the HTML, instead of hiding the via CSS.
The parameters can define default values for parameters:
page_listing:
path: /listing/{page}
options:
page_tree:
parameters:
page: 1
If you do not define a default value, 1
is used
You can use the expression language for the default values. Currently supported functions:
date()
(wraps the PHP date function, for the current timestamp)
calendar:
path: /calendar/{year}
options:
page_tree:
parameters:
year: "date('Y')"
You can place a separator before or after any menu item. The used template must support properly it.
In the bootstrap theme this is only properly supported for dropdown menus. Please note, that adjacent separators are not merged.
Possible values:
null
: no separator (default)before
: place separator right before this itemafter
: place separator right after this item
If the page tree is invalid a InvalidPageTreeException
is thrown, on the first construction of the page tree.
There is an automatic menu builder, based on the page tree. You need to define your menus as service, the menu builder service is named becklyn.page_tree.menu_builder
.
Just add the definition to your services.yml
this is pretty much based on the official KnpMenuBundle documentation.
my_app.menu:
class: Knp\Menu\MenuItem
factory_service: becklyn.page_tree.menu_builder
factory_method: buildMenu
arguments: ["my_route"] # <- the starting route. Can be left empty (or pass null explicitly), to include the complete page tree
tags:
- { name: knp_menu.menu, alias: menu_name }
The menu builder will use your title
as link text. If no title
is set, the route name is used.
A Bootstrap 3 compatible menu renderer is included in the bundle.
It will render the inner <ul class="nav navbar-nav">
of the navbar for you.
{{ renderPageTreeBootstrapMenu("menu_name") }}
It will automatically strip all hidden menu items from the HTML - therefore the known li.first
and li.last
from the default KnpMenu theme will not be included.
It also has new options, in addition to the existing KnpMenu options:
hoverDropdown: true
If you set hoverDropdown
to true, the data-toggle="dropdown"
from the items with dropdown is removed - you could add a hover
functionality via CSS then (as shown here).
This is a pretty simple implementation, which is intended:
- It should be fast. The page tree is not (yet?) cached, so the generation should be fast.
- No existing site should break by just activating the bundle.
- The declaration effort should be low but avoid clashes.
- The title can currently not be changed dynamically, it needs to be "hardcoded" in your route definition.
- Fake parameters, only generation with
1
as parameters
To build a complete page tree, the bundle needs to build URLs for every route inside the page tree. This bundle's main use case is to build a "hidden" menu, which only marks the top level main menu elements as active. Therefore it is valid to just use "fake" route parameters and fill everything with 1 (the voter needs to only compare the routes and not the route parameters).