[Zope3-Users] Re: menus, menu items and actions
Philipp von Weitershausen
philipp at weitershausen.de
Wed Jun 1 18:07:16 EDT 2005
Jan-Wijbrand Kolman wrote:
> Hi,
>
>
> I'm working an application that will have some sort of 'main menu' of actions,
> that should always be available in the UI of this applications.
>
> So, I register a menu:
>
> <menu
> id="foo_menu"
> title="The Main Foo Menu"
> />
>
> and a menu item for it:
>
> <menuItem
> title="Do Bar"
> description="Do Bar In This Application"
> for="*"
> menu="foo_menu"
> action="bar"
> permission="zope.Public"
> />
>
> When rendering the HTML for this menu, the menu item's action is basically used
> as a relative URL (relative to the current location in e.g. a content object
> tree).
>
> However, what I would like is to point to a specific URL relative to my
> application root - since 'bar' is a specific view on my app.root.
>
> At the moment, I solved it by implementing a custom menu class, subclassing
> BrowserMenu:
>
> from zope.app.publisher.browser.menu import BrowserMenu
> class FooMenu(BrowserMenu):
> def getMenuItems(self, object, request):
> items = super(FooMenu, self).getMenuItems(object, request)
> base = 'http://baz.qux.com/' # the base URL will be the absolute url for
> # my application root
> for item in items:
> item['action'] = '%s/%s' % (base, item['action'])
> return items
>
> And register my foo menu like so:
>
> <menu
> id="foo_menu"
> title="The Main Foo Menu"
> class="fooapplication.browser.menu.FooMenu"
> />
>
>
> This does work, but feels a bit icky - although I cannot really say why. Is
> there a better way to achieve this?
You don't really need to treat the action path in the menu class. You
can just as well assemble it in the Page Template where you're actually
looping over the menu items.
For a simple setup (e.g. the one I use on worldcookery.com), I used:
<metal:macro define-macro="navigation_tree_box">
<div class="box" id="navigationTree">
<h4 i18n:translate="">Navigation</h4>
<tal:loop define="request_url request/URL/-1;
stem_url request/URL/0"
repeat="nav context/@@view_get_menu/wcsite_navigation">
<div tal:define="selected python:request_url == stem_url +
nav['action']"
tal:attributes="class python:selected and 'navitem_selected'
or 'navitem'">
<a href="" tal:attributes="href string:${stem_url}${nav/action};"
tal:content="nav/title"
i18n:translate="">label</a>
</div>
</tal:loop>
</div>
</metal:macro>
If you need a more complex setup, e.g. have your 'stem_url' always be
the URL of some object that is not the root of your Virtual Host, you
could define a browser view (not a page!) named 'get_application_root'
or so, have that traverse the acquisition path to the object and return
it and then use that object's @@absolute_url.
Hard coding a URL in Python is definitely not very useful.
Philipp
More information about the Zope3-users
mailing list