google-code-export / django-treemenus

Automatically exported from code.google.com/p/django-treemenus
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

[enh] Server-side foldable menu #29

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hello,

I don't see a ML/group for this project, so I leave here my proposal. Tell
me if there is a better place to discuss it anyway.

I used your project for the new Italian Python website, and I've chosen
your project instead of rolling my own menu structure (as I did in other
projects) for the very well done and usable admin interface. The website
preview is available at http://www2.python.it/ 

The look is the same of the python.org website, and is side menu is
"foldable": from the homepage only the first level items are visible; when
you click on any item you move to a different page where only its second
level children are visible; when you click on a second level item the new
page will show all the 1st level items, only the 2nd level siblings of the
clicked one and its children etc... It's easier show it than type it: for
an example go to http://www2.python.it/comunita/sito/ (sorry if the link
breaks: we are organizing the pages now; feel free to roam).

I was able to crete this menu using your project: I didn't have to subclass
the objects (and it's natural: it is just a different visualization) but I
had to write a customized 'show_menu_item' template tag where I added to
the context a 'menu_item_selected' flag; the template can then decide
whether to visit or not the item children depending on its value. You can
see in [1] the tags

[1]
http://hg.python.it/pythonit/file/tip/pythonit/siteapp/templatetags/menuapp.py
[2]
http://hg.python.it/pythonit/file/tip/pythonit/siteapp/templates/menu_item.html

The decision of whether an item is selected or not is based on the request
path: the rule used is that the item whose url is the longest prefix of the
request path is selected, and all its ancestors are selected too. This way
not only the pages for which an "exact" menu item exist work well, but also
sub-pages of the same areas (e.g. a menu can bring the user to a Django
application entry page, let's say /board/ Every internal board page will
display the menu expanded at least to the "board" item).

Having a function returning "which menu item is selected" also makes
possible to use a menu to generate matching breadcrumb trails: you can see
them in the website; they are generated using a {% show_breadcrumb "menu
name" %} tag, also implemented in [2].

The bulk of the implementation is in [3]: what I do is to create a regex
from the items urls in order to quickly match the "longest prefix handled
by a menu item". I use post_save and post_delete signals to invalidate the
regexp and regenerate it at the following request.

[3] http://hg.python.it/pythonit/file/tip/pythonit/siteapp/menuapp.py

The trail of items and the is_selected predicate are computed finding the
item with longer path prefix and traveling through the parents: generating
the breadcrumbs would require n database hits and evaluating is_selected
for an item would also be linear in the tree depth (thus a complete tree
rendering would roughly require a quadratic number of database hits). For
these reasons I cache the menu items, using id -> item and url -> item maps
(invalidated by signals too). Notice that these problems can be avoided
storing "modified preorder tree traversal" informations in the database
[4], using which you can select a path form root to a certain node in a
single database query).

[4] http://www.sitepoint.com/print/hierarchical-data-database/

As you could see I was able to build these features on top of treemenus
only replacing the tags and I'm happy with that, but if you are interested
I can integrate directly such code into the treemenus app and provide you
the relevant patches. I think the breadcrumb trail matching the menu
structure is a nice feature.

Regards.

Original issue reported on code.google.com by daniele....@gmail.com on 4 Oct 2009 at 11:13

GoogleCodeExporter commented 9 years ago
I've fumbled with the urls above: [1] contains the tags implementation, [2] is 
the
show_menu_item template.

Original comment by daniele....@gmail.com on 4 Oct 2009 at 11:18

GoogleCodeExporter commented 9 years ago
Thank you so much for your thoughts and code. I'm quite flat out at the moment 
and
will review it in more detail when I find the time.

Regards,

Julien

Original comment by jpha...@gmail.com on 7 Oct 2009 at 11:00

GoogleCodeExporter commented 9 years ago
Hi Daniele. Thank your for this report and sorry for attending it so late - 
I've just
been very busy lately.

I think these features (is_selected flag and breadcrumbs) would be a really 
useful
contribution to treemenus. Could you please submit a patch with some tests to 
prove
that it all works?

Thanks a lot.

Original comment by jpha...@gmail.com on 6 Dec 2009 at 7:40