0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-12-01 11:41:20 +01:00

allow for procedural highlighting of menu items. also highlights parents of submenus

This commit is contained in:
Josh Barr 2015-04-15 09:38:51 +12:00
parent 306276b4d7
commit 648efe0e18
4 changed files with 100 additions and 65 deletions

View File

@ -11,13 +11,19 @@ from django.utils.safestring import mark_safe
from wagtail.wagtailcore import hooks
from django.template import Context, loader
class MenuItem(with_metaclass(MediaDefiningClass)):
def __init__(self, label, url, name=None, classnames='', attrs=None, order=1000):
def __init__(self, label, url, name=None, classnames='', attrs=None, order=1000, template='wagtailadmin/shared/menu_item.html'):
self.label = label
self.url = url
self.classnames = classnames
self.name = (name or slugify(text_type(label)))
self.order = order
self.template = template
if attrs:
self.attr_string = flatatt(attrs)
@ -31,10 +37,22 @@ class MenuItem(with_metaclass(MediaDefiningClass)):
"""
return True
def is_active(self, request):
return request.path.startswith(self.url)
def render_html(self, request):
return format_html(
"""<li class="menu-item menu-{0}"><a href="{1}" class="{2}"{3}>{4}</a></li>""",
self.name, self.url, self.classnames, self.attr_string, self.label)
t = loader.get_template(self.template)
c = Context({
'name': self.name,
'url': self.url,
'classnames': self.classnames,
'attr_string': self.attr_string,
'label': self.label,
'request': request,
'active': self.is_active(request)
})
return t.render(c)
class Menu(object):
@ -56,6 +74,9 @@ class Menu(object):
def menu_items_for_request(self, request):
return [item for item in self.registered_menu_items if item.is_shown(request)]
def menu_items_active(self, request):
return [item for item in self.menu_items_for_request(request) if item.is_active(request)]
@property
def media(self):
media = Media()
@ -77,16 +98,18 @@ class Menu(object):
rendered_menu_items.append(item.render_html(request))
except TypeError:
# fallback for older render_html methods that don't accept a request arg
rendered_menu_items.append(item.render_html())
rendered_menu_items.append(item.render_html(request))
return mark_safe(''.join(rendered_menu_items))
class SubmenuMenuItem(MenuItem):
"""A MenuItem which wraps an inner Menu object"""
def __init__(self, label, menu, **kwargs):
def __init__(self, label, menu,
template='wagtailadmin/shared/menu_submenu_item.html',
**kwargs):
self.menu = menu
super(SubmenuMenuItem, self).__init__(label, '#', **kwargs)
super(SubmenuMenuItem, self).__init__(label, '#', template=template, **kwargs)
@property
def media(self):
@ -96,17 +119,30 @@ class SubmenuMenuItem(MenuItem):
# show the submenu if one or more of its children is shown
return bool(self.menu.menu_items_for_request(request))
def is_active(self, request):
return bool(self.menu.menu_items_active(request))
def render_html(self, request):
return format_html(
"""<li class="menu-item menu-{0}">
<a href="#" class="submenu-trigger {1}"{2}>{3}</a>
<div class="nav-submenu">
<h2 class="{1}">{3}</h2>
<ul>{4}</ul>
</div>
</li>""",
self.name, self.classnames, self.attr_string, self.label, self.menu.render_html(request)
)
self.menu.menu_items_for_request(request)
is_active = request.path.startswith(self.url)
if not is_active:
is_active = self.is_active(request)
t = loader.get_template(self.template)
c = Context({
'name': self.name,
'url': self.url,
'classnames': self.classnames,
'attr_string': self.attr_string,
'label': self.label,
'menu_html': self.menu.render_html(request),
'request': request,
'active': is_active
})
return t.render(c)
admin_menu = Menu(register_hook_name='register_admin_menu_item', construct_hook_name='construct_main_menu')

View File

@ -2,7 +2,7 @@ $selected-highlight:darken($color-grey-1, 10%);
$submenu-color:darken($color-grey-1, 5%);
.nav-wrapper{
position:relative;
position: relative;
background: $color-grey-1;
margin-left: -$menu-width;
width: $menu-width;
@ -11,9 +11,9 @@ $submenu-color:darken($color-grey-1, 5%);
min-height:800px;
}
#nav-toggle{
left:$mobile-nice-padding;
left: $mobile-nice-padding;
cursor:pointer;
position:absolute;
position: absolute;
&:before{
font-size:40px;
@ -23,43 +23,32 @@ $submenu-color:darken($color-grey-1, 5%);
}
}
.nav-main{
.menu-active {
background: $selected-highlight;
text-shadow: -1px -1px 0px rgba(0,0,0,0.3);
& > a {
border-left-color:$color-salmon;
color:white;
}
}
.nav-main {
top: 43px;
bottom: 0px;
overflow: auto;
width:100%;
width: 100%;
ul, li{
margin:0;
padding:0;
list-style-type:none;
ul, li {
margin: 0;
padding: 0;
list-style-type: none;
}
li{
li {
@include transition(border-color 0.2s ease);
position:relative;
/* TODO: find better way to procedurally detect the appropriate menu to highlight */
.menu-snippets &.menu-snippets,
.menu-users &.menu-users,
.menu-groups &.menu-groups,
.menu-sites &.menu-sites,
.menu-redirects &.menu-redirects,
.menu-editorspicks &.menu-editors-picks,
.menu-snippets &.menu-snippets,
.menu-documents &.menu-documents,
.menu-images &.menu-images,
.menu-search &.menu-search,
.menu-explorer &.menu-explorer,
.menu-forms &.menu-forms{
background:$selected-highlight;
text-shadow:-1px -1px 0px rgba(0,0,0,0.3);
a{
border-left-color:$color-salmon;
color:white;
}
}
position: relative;
}
a{
@ -101,13 +90,13 @@ $submenu-color:darken($color-grey-1, 5%);
top:0.5em;
margin-top:0.15em;
}
}
}
.account{
@include clearfix();
.avatar{
display:none;
}
@ -119,9 +108,9 @@ $submenu-color:darken($color-grey-1, 5%);
}
}
.nav-submenu{
.nav-submenu{
background:$submenu-color;
h2{
display:none;
}
@ -186,7 +175,7 @@ $submenu-color:darken($color-grey-1, 5%);
padding:0;
width:3em; height:100%;
overflow:hidden;
&:before{
font-family:wagtail;
font-weight:200;
@ -198,7 +187,7 @@ $submenu-color:darken($color-grey-1, 5%);
padding:0 1em;
}
}
}
/* Navigation open condition */
@ -280,13 +269,13 @@ body.explorer-open {
position:fixed;
width:$menu-width - 7;
bottom:0;
}
.account{
@include clearfix();
padding-right:0;
padding-left:15px;
.avatar{
display:inline-block;
padding:0;
@ -307,7 +296,7 @@ body.explorer-open {
}
}
.nav-submenu{
.nav-submenu{
position:fixed;
height:100%;
width:0;
@ -317,7 +306,7 @@ body.explorer-open {
overflow:auto;
max-height:100%;
border-right:1px solid rgba(0,0,0,0.1);
h2,ul{
float:right;
width:$menu-width;
@ -348,9 +337,9 @@ body.explorer-open {
> a{
text-shadow:-1px -1px 0px rgba(0,0,0,0.3);
&:hover{
background-color:transparent;
background-color:transparent;
}
}
.nav-submenu{
@ -399,4 +388,4 @@ body.explorer-open {
display:block;
}
}
}
}

View File

@ -0,0 +1,3 @@
<li class="menu-item menu-{{name}}{% if active %} menu-active{% endif %}">
<a href="{{url}}" class="{{classnames}}"{{attr_string}}>{{label}}</a>
</li>

View File

@ -0,0 +1,7 @@
<li class="menu-item menu-{{name}}{% if active %} menu-active{% endif %}">
<a href="#" class="submenu-trigger {{classnames}}"{{attr_string}}>{{label}}</a>
<div class="nav-submenu">
<h2 class="{{classnames}}">{{label}}</h2>
<ul>{{menu_html}}</ul>
</div>
</li>