-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] [Outdated] Added a first implementation of a BreadcrumbRenderer #45
Conversation
|
||
namespace Knp\Menu\Renderer; | ||
|
||
use \Knp\Menu\ItemInterface; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First \
is not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed. I missed it because I created the file by copying the ListRenderer
does this PR has tests? |
@cordoval as you can see in the diff, there is no tests at all. But I started the description by saying it is a WIP meant for discussion with the CMF guys asking for the feature (and any other guy interested in it) |
break; | ||
} | ||
|
||
return str_repeat(' ', $spacing).$html."\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just about readability of the html source code, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed. This is used to render some nice HTML (which can be changed by setting the compressed
option to true, like other renderers)
thanks for taking this up! i think its on a good track. from drupal i remember that you had the option to tell the breadcrumb to not show the current item, or to not link but make it just text. not showing the current menu item would here mean to just render the parent of the current item when calling the twig function, right? should we maybe add an option whether the current item should be linked or not? and anyway add a special class to it so it can be stiled differently? |
Regarding not rendering the current item, it is indeed as easy as passing the parent to the render call. About adding a special class for the current item, it is a bit hard as we only have the label and the uri currently. So the first point would be discussing if we use |
RE special class for current item: you are right. i think we should rather take this and recommend to extend the renderer for special requirements like this. one question remains: could we use twig templates for the rendering or do you really want to render all in php? (see comment on the code where its looking rather complicated) but i have no experience with twig extension best practice, maybe the overhead is too big? i don't have a strong opinion but if its doable twig could be nice (also to extend by just replacing a twig template rather than extending the renderer class). |
@dbu My only issue with Twig is the way default options are handled. The BreadcrumbRenderer uses different options, and I would like to avoid duplicating the TwigRenderer for this. So I need to find a better way to handle this (which is why I started with a whole separate Renderer). What do you think about my point about using item vs using arrays ? Btw, there is an issue with the breadcrumbs array (see the ticket linked above) |
sounds to me like we should do a bc break for #47 anyway, its a rather surprising and unnecessary constraint to not be allowed the same label twice. we could define the new structure as array of array (the main array being the breadcrumbs, with insignificant indexes) and the inner array containing fields 'label' and 'url' (or whatever we previously had) and an 'item' that is the item object if there is any, in case you have a custom renderer that does more stuff with it. wdyt? |
cool, what is missing to merge this? |
I think it is quite ready. I will look at it this evening. Then, I will need to check how it could be done using Twig without duplicating the renderer |
I just tried it, and it currently renders nodes that should not be displayed. I applied this patch to get it working. diff --git a/src/Knp/Menu/Renderer/BreadcrumbRenderer.php b/src/Knp/Menu/Renderer/BreadcrumbRenderer.php
index a7aab60..5d7492b 100644
--- a/src/Knp/Menu/Renderer/BreadcrumbRenderer.php
+++ b/src/Knp/Menu/Renderer/BreadcrumbRenderer.php
@@ -92,6 +92,10 @@ class BreadcrumbRenderer extends Renderer implements RendererInterface
*/
protected function renderItem($label, $uri, array $options, ItemInterface $item = null)
{
+ if (null !== $item && !$item->isDisplayed()) {
+ return '';
+ }
+
$isCurrent = null !== $item && $item->isCurrent();
$attributes = $isCurrent ? array('class' => $options['current_class']) : array();
|
@havvg when an item is not displayed in a menu, none of its children are displayed either. Your change would not do it. And btw, this would mean that you are explicitly asking to display the breadcrumb for a hidden item, so I'm not sure we should hide it in such case. |
Hm.. then I'm doing it wrong, I guess. I'm retrieving it like this: (Symfony2 + KnpMenuBundle) This renders the root item + the menu (patch reverted): {{ knp_menu_render(knp_menu_get('main', ['profile', 'show']), {}, 'breadcrumb') }} This code does not (default twig renderer), it only renders the children of the root item: {{ knp_menu_render('main') }} Did I miss something? |
@havvg I know that the current code shows every node in the breadcrumb. But try to hide the |
Seems reasonable; then I'm asking, why the second call is not rendering the root node, but only its children and how may I accomplish this with the breadcrumb, too? |
ah yeah, the breadcrumb array includes the root item. This should probably be changed. This methods needs more changes... |
{ | ||
$this->defaultOptions = array_merge(array( | ||
'current_as_link' => true, | ||
'current_class' => 'current', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it intended to have those options with underscore? The other renderers have their options called currentAsLink
, currentClass
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only place where the library does not follow the Symfony2 standards is for array keys, where underscores should be used (which also leads to a violation of the Twig CS for the same reason). So I'm wondering about changing them to underscores in the v2 of the library, but I'm not sure yet (it would be a BC break)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imho it should be compatible with the current renderers and break BC with all at once at some version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the master branch of the library is the dev branch for 2.0. I want to think a bit more about this renaming, and about the issues related to the breadcrumb (see other comments) but such renaming would be done not long after the merge. But I will open a separate issue to discuss it
Hey, this seems to be an interesting effort. Maybe I could get involved somehow too... I finally got it loading after I realized I have to define a service that provides breadcrumb renderer (like this) services:
knp_menu.renderer.breadcrumb:
class: Knp\Menu\Renderer\BreadcrumbRenderer
tags:
- { name: knp_menu.renderer, alias: breadcrumb } Now I'm wondering why it only renders the root node if I leave all extra parameters out. But anyway, it's 1.30 am, so I'm gonna have to look at this more tomorrow. |
As described above, you need to call the render method by passing it the item for which you want to render the breadcrumb, not the root. |
@stof Okay, so is there a generic way of retrieving the item for current url/route (from twig point of view)? I guess the path method isn't something that can generally be used because path variables are not 'known' in any random bundle/template that uses the menu. |
rendering the root node would best be optional. some people want it, others don't. |
Yep, I checked that I'd be able to do what I need to do with css selector :last-child. But it's IE9+ only. So not a true option for any real application quite yet. I'm not really sure how this should be solved. I'm just saying, the 'last' class for the last item (how ever it is solved) might be needed. |
Any new developments in this PR ? I'd like to use this breadcrumb renderer. |
+1 for this |
Any news on this PR? |
+1 |
1 similar comment
+1 |
+1 |
5 similar comments
+1 |
+1 |
👍 |
+1 |
+1 |
this implementation of the breadcrumb was in what state? |
+1 |
Any news on this feature? |
@stof nothing against rebasing on master this branch ? |
@Nek- Actually, I'm not convinced this is the appropriate approach:
this could make it really confusing to use. However, I have no real idea about a good implementation. thus, we don't have yet a way to get the current item easily from Twig (we have a way to get it in PHP thanks to the filter iterator) |
@stof can you come on gitter ( https://gitter.im/KnpLabs/KnpMenu ) to speak about the future of KnpMenu ? |
not really during work time. Is it OK for you if we do it this evening or during the weekend ? |
It will be perfect at the evening, thanks :-) . |
+1 |
i guess #161 aims to address this for 2.1? |
This is a WIP about #24 meant for discussion.
This implementation uses the
getBreadcrumbsArray
method, making it easy to append additional stuff at the end of the breadcrumb. However, it means that you are limited when rendering each item as you only have the label and the uri. The other solution would be to build an array of items or to call getParent each time, but it would make it harder to pass additional paths as it would require building items for them (in this regards, an array of items would be easier than callinggetParent
during the rendering though as we don't need to add the new items in the existing menu tree).To use it, you need to call the
knp_menu_render
method with the item corresponding to the end of the breadcrumbs, i.e. the item for which the breadcrumb is rendered (except the additional path of course). This is a good use case to get an item by path in the tree