Extend menu items and buttons to accept a list of required permissions

This commit is contained in:
Jeremy Stretch 2020-03-26 16:04:12 -04:00
parent 84d2db0d35
commit e7f7b14214
4 changed files with 38 additions and 27 deletions

View File

@ -305,17 +305,16 @@ A `PluginMenuItem` has the following attributes:
* `link` - The name of the URL path to which this menu item links * `link` - The name of the URL path to which this menu item links
* `link_text` - The text presented to the user * `link_text` - The text presented to the user
* `permission` - The name of the permission required to display this link (optional) * `permissions` - A list of permissions required to display this link (optional)
* `buttons` - An iterable of PluginMenuButton instances to display (optional) * `buttons` - An iterable of PluginMenuButton instances to display (optional)
A `PluginMenuButton` has the following attributes: A `PluginMenuButton` has the following attributes:
* `link` - The name of the URL path to which this button links * `link` - The name of the URL path to which this button links
* `title` - The tooltip text (displayed when the mouse hovers over the button) * `title` - The tooltip text (displayed when the mouse hovers over the button)
* `icon_class` - Button icon CSS class * `icon_class` - Button icon CSS class
* `color` - One of the choices provided by `ButtonColorChoices` (optional) * `color` - One of the choices provided by `ButtonColorChoices` (optional)
* `permission` - The name of the permission required to display this button (optional) * `permissions` - A list of permissions required to display this button (optional)
## Extending Core Templates ## Extending Core Templates

View File

@ -160,13 +160,17 @@ class PluginMenuItem:
Links are specified as Django reverse URL strings. Links are specified as Django reverse URL strings.
Buttons are each specified as a list of PluginMenuButton instances. Buttons are each specified as a list of PluginMenuButton instances.
""" """
def __init__(self, link, link_text, permission=None, buttons=None): permissions = []
buttons = []
def __init__(self, link, link_text, permissions=None, buttons=None):
self.link = link self.link = link
self.link_text = link_text self.link_text = link_text
self.permission = permission if permissions is not None:
if buttons is None: if type(permissions) not in (list, tuple):
self.buttons = [] raise TypeError("Permissions must be passed as a tuple or list.")
else: self.permissions = permissions
if buttons is not None:
self.buttons = buttons self.buttons = buttons
@ -176,13 +180,16 @@ class PluginMenuButton:
ButtonColorChoices. ButtonColorChoices.
""" """
color = ButtonColorChoices.DEFAULT color = ButtonColorChoices.DEFAULT
permissions = []
def __init__(self, link, title, icon_class, color=None, permission=None): def __init__(self, link, title, icon_class, color=None, permissions=None):
self.link = link self.link = link
self.title = title self.title = title
self.icon_class = icon_class self.icon_class = icon_class
self.permission = permission if permissions is not None:
if type(permissions) not in (list, tuple):
raise TypeError("Permissions must be passed as a tuple or list.")
self.permissions = permissions
if color is not None: if color is not None:
self.color = color self.color = color

View File

@ -1,25 +1,22 @@
{% load helpers %}
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Plugins <span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Plugins <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
{% for section_name, menu_items in plugin_menu_items.items %} {% for section_name, menu_items in plugin_menu_items.items %}
<li class="dropdown-header">{{ section_name }}</li> <li class="dropdown-header">{{ section_name }}</li>
{% for menu_item in menu_items %} {% for menu_item in menu_items %}
{% if menu_item.permission %} <li{% if menu_item.permissions and not request.user|has_perms:menu_item.permissions %} class="disabled"{% endif %}>
<li{% if not menu_item.permission in perms %} class="disabled"{% endif %}> {% if menu_item.buttons %}
{% else %} <div class="buttons pull-right">
<li> {% for button in menu_item.buttons %}
{% endif %} {% if not button.permissions or request.user|has_perms:button.permissions %}
{% if menu_item.buttons %} <a href="{% url button.link %}" class="btn btn-xs btn-{{ button.color }}" title="{{ button.title }}"><i class="fa {{ button.icon_class }}"></i></a>
<div class="buttons pull-right"> {% endif %}
{% for button in menu_item.buttons %} {% endfor %}
{% if not button.permission or button.permission in perms %} </div>
<a href="{% url button.link %}" class="btn btn-xs btn-{{ button.color }}" title="{{ button.title }}"><i class="fa {{ button.icon_class }}"></i></a> {% endif %}
{% endif %} <a href="{% url menu_item.link %}">{{ menu_item.link_text }}</a>
{% endfor %} </li>
</div>
{% endif %}
<a href="{% url menu_item.link %}">{{ menu_item.link_text }}</a>
</li>
{% endfor %} {% endfor %}
{% if not forloop.last %} {% if not forloop.last %}
<li class="divider"></li> <li class="divider"></li>

View File

@ -201,6 +201,14 @@ def get_docs(model):
return mark_safe(content) return mark_safe(content)
@register.filter()
def has_perms(user, permissions_list):
"""
Return True if the user has *all* permissions in the list.
"""
return user.has_perms(permissions_list)
# #
# Tags # Tags
# #