kopia lustrzana https://github.com/wagtail/wagtail
allow for procedural highlighting of menu items. also highlights parents of submenus
rodzic
306276b4d7
commit
648efe0e18
|
@ -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')
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Ładowanie…
Reference in New Issue