ability to render sub-menus
it would be nice to have a way to just render the current submenu if there is one of that navigation depth. we can render from a menu item but not a a menu node. and we don't have a decent way to know how deep in the menu tree we currently are
this is the hack i came up with to get it going. but this is pretty ridiculous.
{% if cmfMainContent is defined and cmfMainContent.menus|length > 0 %}
{% for menu in cmfMainContent.menus %}
{% if menu.id|split('/')|length == 6 %}
{% set main = menu.parent.name %}
{% set sub = menu.name %}
<div class="related_items">
{{ knp_menu_render(['main', main, sub], { 'depth': 1 } ) }}
</div>
{% endif %}
{% if menu.id|split('/')|length == 7 %}
{% set main = menu.parent.parent.name %}
{% set sub = menu.parent.name %}
<div class="related_items">
{{ knp_menu_render(['main', main, sub], { 'depth': 1, 'currentClass': 'selected' } ) }}
</div>
{% endif %}
{% endfor %}
{% endif %}
What would be the ideal API call for this?
not so sure. one issue is that i can have the menu node here, but not the menu item. the menu item would have the getLevel method to know the depth.
i think having cmf_menu_item(Knp\Menu\NodeInterface) would solve the issue. then i could use knp_menu_render with the right item and depth limit.
@stof would it make sense to have a twig helper to get the menu item from a menu node in knp_menu? or could we handle the node case in knp_menu_get, using the factory::createFromNode?
@dbu you could implement it using createFromNode and a custom menu provider getting the node as option.
btw, the NodeProvider could be part of KnpMenu itself
@stof not sure to get what you mean exactly. createFromNode would be what i need to implement such a node to item converter twig function, yes. but what would be the right function, make knp_menu_get flexible in that way or a knp_menu_item_from_node? where would i need a custom menu provider? i do have the node instance already, but need the item, so i "just" need the factory. i guess one issue is how to pick the right factory?
what would be the NodeProvider? something similar to the menu provider but that i can get a node from? i think i do not need that, i have the node from doctrine relation mappings on my content.
Something like this (incomplete code, add the use statements and the constructor)
class NodeProvider implements MenuProviderInterface
{
private $factory;
public function get($name, array $options = array())
{
if (!$this->has($name, $options)) {
throw new \InvalidArgumentException('The menu is not defined.');
}
return $this->factory->createFromNode($options['node']);
}
public function has($name, array $options = array())
{
return 'from_node' === $name
&& isset($options['node'])
&& $options['node'] instanceof NodeInterface;
}
}
and then register it in the container and use it in the template:
{% set menu = knp_menu_get('from_node', options={'node': node}) %}
ah cool, now i got it. thanks stof, will do a PR
What is the preferred way to do this nowadays besides the hack in the first post? I cannot find anyway to render a submenu from the current node from within twig. A cookbook entry would be nice. Will this be easier once the PR for menu_bundle 2.0 is merged?