Browse Source

Add hook for adding custom links to the admin settings sidebar

See the test-mail plugin for an example.
Peter Justin 6 years ago
parent
commit
a54dadd260

+ 1 - 0
docs/development/hooks/template.rst

@@ -34,3 +34,4 @@ Template Hooks
 .. autofunction:: flaskbb_tpl_post_menu_after
 .. autofunction:: flaskbb_tpl_post_menu_after
 .. autofunction:: flaskbb_tpl_topic_controls
 .. autofunction:: flaskbb_tpl_topic_controls
 .. autofunction:: flaskbb_tpl_admin_settings_menu
 .. autofunction:: flaskbb_tpl_admin_settings_menu
+.. autofunction:: flaskbb_tpl_admin_settings_sidebar

+ 11 - 0
flaskbb/management/plugins.py

@@ -30,3 +30,14 @@ def flaskbb_tpl_admin_settings_menu(user):
 
 
     outcome = yield
     outcome = yield
     outcome.force_result(chain(results, *outcome.get_result()))
     outcome.force_result(chain(results, *outcome.get_result()))
+
+
+@impl(hookwrapper=True, tryfirst=True)
+def flaskbb_tpl_admin_settings_sidebar():
+    """
+    Flattens the lists that come back from the hook
+    into a single iterable that can be used to populate
+    the menu
+    """
+    outcome = yield
+    outcome.force_result(chain(*outcome.get_result()))

+ 29 - 0
flaskbb/plugins/spec.py

@@ -882,6 +882,35 @@ def flaskbb_tpl_admin_settings_menu(user):
 
 
 
 
 @spec
 @spec
+def flaskbb_tpl_admin_settings_sidebar(user):
+    """This hook is emitted in the admin panels setting tab and used
+    to add additional navigation links to the sidebar settings menu.
+
+    Implementations of this hook should return a list of tuples
+    that are view name and display text.
+    The display text will be provided to the translation service so it
+    is unnecessary to supply translated text.
+
+    For example::
+
+        @impl(trylast=True)
+        def flaskbb_tpl_admin_settings_menu():
+            return [
+                ("myplugin.foobar", "Foobar")
+            ]
+
+    Only admins can view the Settings tab.
+
+    Hookwrappers for this spec should not be registered as FlaskBB
+    supplies its own hookwrapper to flatten all the lists into a single list.
+
+    in :file:`templates/management/settings.html`
+
+    :param user: The current user object.
+    """
+
+
+@spec
 def flaskbb_tpl_profile_sidebar_stats(user):
 def flaskbb_tpl_profile_sidebar_stats(user):
     """This hook is emitted on the users profile page below the standard
     """This hook is emitted on the users profile page below the standard
     information. For example, it can be used to add additional items
     information. For example, it can be used to add additional items

+ 10 - 4
flaskbb/templates/macros.html

@@ -337,7 +337,14 @@
 {% macro sidebar(items, extra_class="") %}
 {% macro sidebar(items, extra_class="") %}
 {% if items %}
 {% if items %}
 <ul class="nav {% if extra_class %}{{ extra_class }}{% endif %}">
 <ul class="nav {% if extra_class %}{{ extra_class }}{% endif %}">
-    {% for item in items %}
+    {{ sidebaritems(items) }}
+</ul>
+{% endif %}
+{% endmacro %}
+
+
+{% macro sidebaritems(items) %}
+{% for item in items %}
     {% if item.content_type == NavigationContentType.link %}
     {% if item.content_type == NavigationContentType.link %}
     {{ navlink(item.endpoint, item.name, item.icon, item.active, item.urlforkwargs) }}
     {{ navlink(item.endpoint, item.name, item.icon, item.active, item.urlforkwargs) }}
     {% elif item.content_type == NavigationContentType.external_link %}
     {% elif item.content_type == NavigationContentType.external_link %}
@@ -349,11 +356,10 @@
     {% else %}
     {% else %}
     {# skip unknown #}
     {# skip unknown #}
     {% endif %}
     {% endif %}
-    {% endfor %}
-</ul>
-{% endif %}
+{% endfor %}
 {% endmacro %}
 {% endmacro %}
 
 
+
 {% macro tablink_href(endpoint, name, active=False) %}
 {% macro tablink_href(endpoint, name, active=False) %}
 <li {% if endpoint == request.endpoint or active %}class="active"{% endif %} >
 <li {% if endpoint == request.endpoint or active %}class="active"{% endif %} >
     <a href={{ endpoint }} role="tab" data-toggle="tab">{{ name }}</a>
     <a href={{ endpoint }} role="tab" data-toggle="tab">{{ name }}</a>

+ 8 - 8
flaskbb/templates/management/settings.html

@@ -11,8 +11,8 @@
 {% endblock %}
 {% endblock %}
 
 
 {% block management_content %}
 {% block management_content %}
-{% from theme('macros.html') import render_boolean_field, render_select_field, render_field, navlink with context %}
-
+{% from theme('macros.html') import render_boolean_field, render_select_field, render_field, sidebaritems %}
+{% set extra_setting_links = run_hook("flaskbb_tpl_admin_settings_sidebar", user=current_user, is_markup=False) %}
 
 
 <div class="col-md-3 settings-col">
 <div class="col-md-3 settings-col">
     <div class="nav-sidebar">
     <div class="nav-sidebar">
@@ -25,15 +25,15 @@
                 <li><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
                 <li><a href="{{ url_for('management.settings', slug=group.key) }}">{{ group.name }}</a></li>
             {% endif %}
             {% endif %}
         {% endfor %}
         {% endfor %}
-        {% if all_plugins %}
+        {% if all_plugins or extra_setting_links|length %}
         <li class="nav-header">Plugin Settings</li>
         <li class="nav-header">Plugin Settings</li>
         {% for plugin in all_plugins %}
         {% for plugin in all_plugins %}
-            {% if plugin.name == active_nav.get('key') %}
-                <li class="active"><a href="{{ url_for('management.settings', plugin=plugin.name) }}">{{ plugin.name.title() }}</a></li>
-            {% else %}
-                <li><a href="{{ url_for('management.settings', plugin=plugin.name) }}">{{ plugin.name.title() }}</a></li>
-            {% endif %}
+            <li {% if plugin.name == active_nav.get('key') %}class="active"{% endif %}>
+                <a href="{{ url_for('management.settings', plugin=plugin.name) }}">{{ plugin.name.title() }}</a>
+            </li>
         {% endfor %}
         {% endfor %}
+
+        {{ sidebaritems(extra_setting_links) }}
         {% endif %}
         {% endif %}
         </ul>
         </ul>
     </div>
     </div>