make menu easier to extend

13 views
Skip to first unread message

Eric Drechsel

unread,
Sep 18, 2008, 4:46:27 PM9/18/08
to django-hotclub
I'm customizing Pinax, and I see that there is work to be done to make
the template structure easier to work with in customized sites.
Ideally it should be possible to customize the global "look" without
modifying Pinax's app templates, and to add new apps to main
navigation simply by following established conventions.

Unfortunately, the site-menu's active navigation tab markup is funky
to work around limitations of the template system without introducing
the concept of dynamic menus, and each new tab requires a line be
added to base.css, even though they all act the same.

I'd like to help work on making pinax easier to extend (primarily a
lack of documentation). This task seems like a good starting point in
Pinax for me, a newish Django developer. I'm posting to the list
rather than the tracker to solicit feedback from as wide a group as
possible. Have you found a great way to do extensible menus with
Django? A method exclusively using templates would be preferred,
although a dynamic app isn't out of the question I guess.

Eric Drechsel

unread,
Sep 19, 2008, 3:35:48 AM9/19/08
to django-hotclub
I looked at http://www.djangosnippets.org/snippets/347/ , which seems
pretty nice for outputting menus with active links and such, but it
doesn't address pluggability. However, since the main menu just in
settings.py, one could follow the pattern set by the url mapping
system, and move the menu definition out into a global menu.py that
includes from the menu.py from individual apps.

the data structure in the snippet probably isn't quite right (does it
support nested menus? need to look closer). there are some nice things
about the data structure for the menu system in Drupal, might be a
good starting point.

Dougn

unread,
Sep 22, 2008, 7:25:07 PM9/22/08
to django-hotclub
I would recommend just using unregistered plugins to get the job done:

site_base.html:
{% load app_plugins %}
{% block right_tab %}
{% if user.is_authenticated %}
<table>
<tr>{% plugin_point "menu" %}</tr>
</table>
{% endif %}
{% endblock right_tab %}

templates/appname/plugins/menu.html:
{% extends "pinax/menu.html" %}
{% block tab_class %}rtab_tribes{% endblock tab_class %}
{% block tab_link%}<a href="{% url tribes.views.tribes %}">{% trans
"Tribes" %}</a>{% endblock tab_link %}

templates/pinax/menu.html:
<td class="tab {% block tab_class %}{% endblock %}"><div>{% block
tab_link %}{% endblock %}</div></td>


Then menu items will show up in whatever order they are listed in
INSTALLED_APPS
Not in installed apps? wont show up.
Want to add a menu item? add a template.

-Doug


On Sep 19, 3:35 am, Eric Drechsel <ericd...@gmail.com> wrote:
> I looked athttp://www.djangosnippets.org/snippets/347/, which seems

Dougn

unread,
Sep 22, 2008, 8:35:53 PM9/22/08
to django-hotclub
ok, after looking over the code the missing piece is the CSS (of
course).

some of the CSS for the tab selection needs to be mived out of the css
file ind into a style block in site_base.html.
This is style information for the tab_id which is overloaded in each
of the app 'base.html' files.

add this to site_base.html:

#{% block tab_id %}
{
bottom: -1px !important;
padding-bottom: 0 !important;
}
#{% block tab_id %} a
{
color: #000 !important; /* selected tab text colour */
}
#{% block tab_id %} div
{
margin: 0;
background-color: #DEF !important; /* selected tab colour */
border-left: 1px solid #000 !important; /* tab border */
border-top: 1px solid #000 !important; /* tab border */
border-right: 1px solid #000 !important; /* tab border */
padding-bottom: 5px; /* 1px more than unselected padding-bottom */
}

templates/tribes/plugins/menu.html:
{% extends "pinax/menu.html" %}
{% block rtab_id %}tribes_tab{% endblock rtab_id %}
{% block rtab_link%}<a href="{% url tribes.views.tribes %}">{% trans
"Tribes" %}</a>{% endblock rtab_link %}

templates/pinax/menu.html:
<td class="tab" id="{% block rtab_id %}{% endblock %}"><div>{% block
rtab_link %}{% endblock %}</div></td>


The key is that the tab_id and rtab_id blocks must match with an app.
tab_id is already set in tribes/base.html


This should make it so that you dont need to edit any files for
apps... if its in INSTALLED_APPS and it has a <app>/plugins/menu.html
file (which is correct) then it will work.

-Doug

Dougn

unread,
Sep 22, 2008, 8:41:34 PM9/22/08
to django-hotclub
ok, that doesn't work ;-) cant have the same blok multiple times as
needed by the CSS I wrote... (and didnt even end the block tags...)

James Tauber

unread,
Sep 22, 2008, 8:57:19 PM9/22/08
to django-...@googlegroups.com


Template-based navigation certainly has its advantages when building a
one-off site (e.g. Cloud27). Other possibilities would be
configuration-based navigation and database-based navigation.

I don't really like navigation to be the database, but it's a must if
you want to allow site administrators to build a site entirely via the
browser. Pinax is a fair way from that :-)

The biggest problem with the current system is the duplication in the
CSS. I certainly welcome patches for alternatives if they have feature
parity, as I have plenty of other stuff I'm working on.

James


Milan Andric

unread,
Sep 25, 2008, 1:40:15 PM9/25/08
to django-hotclub
Also keep in mind that it's common to render a menu or navigation
based on permissions. That also points to keeping with a template
based menu solution, otherwise you would have to build that into the
templatetag code and that starts to get too complex and harder to
customize with settings. The latter (harder to customize) being the
worse of the negative effects. The big win with django and using
common patterns/conventions is easy customization once you know the
patterns. The menu solution should remain a building block as opposed
to a "plugin" (something that just works but you almost never
customize).

--
Milan

Eric Drechsel

unread,
Sep 30, 2008, 2:42:56 AM9/30/08
to django-hotclub
Thanks for the thoughtful responses. Dougn, I didn't know what plugins
did, that's very useful.

I spent some time trying to implement a {% readblock blockname %}
template tag, which would make setting an "active" menu item easier,
but no luck so far (I think it requires a core patch to do with any
efficiency). Jinja allows accessing block contents via self.blockname:
http://jinja.pocoo.org/2/documentation/templates#child-template . This
seems fairly intuitive.

I think allowing apps to bundle "branches" of the menu tree for the
site creator to place is a good goal (in much the same way as url
mapping works). It should also be possible to hide menus from
unauthorized clients, so I think menu nodes should be able to have an
access callback. Maybe if a parent callback fails then that whole
branch is "clipped".
Reply all
Reply to author
Forward
0 new messages