|
@@ -15,7 +15,6 @@ spec = HookspecMarker('flaskbb')
|
|
|
|
|
|
|
|
|
# Setup Hooks
|
|
|
-
|
|
|
@spec
|
|
|
def flaskbb_extensions(app):
|
|
|
"""Hook for initializing any plugin loaded extensions."""
|
|
@@ -33,44 +32,175 @@ def flaskbb_load_migrations():
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_load_blueprints(app):
|
|
|
- """Hook for registering blueprints."""
|
|
|
+ """Hook for registering blueprints.
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ """
|
|
|
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_request_processors(app):
|
|
|
- """Hook for registering pre/post request processors."""
|
|
|
+ """Hook for registering pre/post request processors.
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ """
|
|
|
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_errorhandlers(app):
|
|
|
- """Hook for registering error handlers."""
|
|
|
+ """Hook for registering error handlers.
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ """
|
|
|
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_jinja_directives(app):
|
|
|
- """Hook for registering jinja filters, context processors, etc."""
|
|
|
+ """Hook for registering jinja filters, context processors, etc.
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ """
|
|
|
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_additional_setup(app, pluggy):
|
|
|
"""Hook for any additional setup a plugin wants to do after all other
|
|
|
application setup has finished.
|
|
|
+
|
|
|
+ For example, you could apply a WSGI middleware::
|
|
|
+
|
|
|
+ @impl
|
|
|
+ def flaskbb_additional_setup(app):
|
|
|
+ app.wsgi_app = ProxyFix(app.wsgi_app)
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ :param pluggy: The pluggy object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_cli(cli, app):
|
|
|
+ """Hook for registering CLI commands.
|
|
|
+
|
|
|
+ For example::
|
|
|
+
|
|
|
+ @impl
|
|
|
+ def flaskbb_cli(cli):
|
|
|
+ @cli.command()
|
|
|
+ def testplugin():
|
|
|
+ click.echo("Hello Testplugin")
|
|
|
+
|
|
|
+ return testplugin
|
|
|
+
|
|
|
+ :param app: The application object.
|
|
|
+ :param cli: The FlaskBBGroup CLI object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_shell_context():
|
|
|
+ """Hook for registering shell context handlers
|
|
|
+ Expected to return a single callable function that returns a dictionary or
|
|
|
+ iterable of key value pairs.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+# Event hooks
|
|
|
+@spec
|
|
|
+def flaskbb_event_post_save_before(post):
|
|
|
+ """Hook for handling a post before it has been saved.
|
|
|
+
|
|
|
+ :param flaskbb.forum.models.Post post: The post which triggered the event.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_event_post_save_after(post, is_new):
|
|
|
+ """Hook for handling a post after it has been saved.
|
|
|
+
|
|
|
+ :param flaskbb.forum.models.Post post: The post which triggered the event.
|
|
|
+ :param bool is_new: True if the post is new, False if it is an edit.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_event_topic_save_before(topic):
|
|
|
+ """Hook for handling a topic before it has been saved.
|
|
|
+
|
|
|
+ :param flaskbb.forum.models.Topic topic: The topic which triggered the
|
|
|
+ event.
|
|
|
"""
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_cli(cli):
|
|
|
- """Hook for registering CLI commands."""
|
|
|
+def flaskbb_event_topic_save_after(topic, is_new):
|
|
|
+ """Hook for handling a topic after it has been saved.
|
|
|
+
|
|
|
+ :param flaskbb.forum.models.Topic topic: The topic which triggered the
|
|
|
+ event.
|
|
|
+ :param bool is_new: True if the topic is new, False if it is an edit.
|
|
|
+ """
|
|
|
|
|
|
|
|
|
@spec
|
|
|
def flaskbb_user_registered(username):
|
|
|
"""Hook for handling events after a user is registered"""
|
|
|
|
|
|
-# Template Hooks
|
|
|
+
|
|
|
+# Form hooks
|
|
|
+@spec
|
|
|
+def flaskbb_form_new_post(form):
|
|
|
+ """Hook for modifying the :class:`~flaskbb.forum.forms.ReplyForm`.
|
|
|
+
|
|
|
+ For example::
|
|
|
+
|
|
|
+ @impl
|
|
|
+ def flaskbb_form_new_post(form):
|
|
|
+ form.example = TextField("Example Field", validators=[
|
|
|
+ DataRequired(message="This field is required"),
|
|
|
+ Length(min=3, max=50)])
|
|
|
+
|
|
|
+ :param form: The :class:`~flaskbb.forum.forms.ReplyForm` class.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_form_new_post_save(form):
|
|
|
+ """Hook for modifying the :class:`~flaskbb.forum.forms.ReplyForm`.
|
|
|
+
|
|
|
+ This hook is called while populating the post object with
|
|
|
+ the data from the form. The post object will be saved after the hook
|
|
|
+ call.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ :param post: The post object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_form_new_topic(form):
|
|
|
+ """Hook for modifying the :class:`~flaskbb.forum.forms.NewTopicForm`
|
|
|
+
|
|
|
+ :param form: The :class:`~flaskbb.forum.forms.NewTopicForm` class.
|
|
|
+ """
|
|
|
+
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_before_navigation():
|
|
|
+def flaskbb_form_new_topic_save(form, topic):
|
|
|
+ """Hook for modifying the :class:`~flaskbb.forum.forms.NewTopicForm`.
|
|
|
+
|
|
|
+ This hook is called while populating the topic object with
|
|
|
+ the data from the form. The topic object will be saved after the hook
|
|
|
+ call.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ :param topic: The topic object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+# Template Hooks
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_navigation_before():
|
|
|
"""Hook for registering additional navigation items.
|
|
|
|
|
|
in :file:`templates/layout.html`.
|
|
@@ -78,7 +208,7 @@ def flaskbb_tpl_before_navigation():
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_after_navigation():
|
|
|
+def flaskbb_tpl_navigation_after():
|
|
|
"""Hook for registering additional navigation items.
|
|
|
|
|
|
in :file:`templates/layout.html`.
|
|
@@ -86,7 +216,7 @@ def flaskbb_tpl_after_navigation():
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_before_user_nav_loggedin():
|
|
|
+def flaskbb_tpl_user_nav_loggedin_before():
|
|
|
"""Hook for registering additional user navigational items
|
|
|
which are only shown when a user is logged in.
|
|
|
|
|
@@ -95,7 +225,7 @@ def flaskbb_tpl_before_user_nav_loggedin():
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_after_user_nav_loggedin():
|
|
|
+def flaskbb_tpl_user_nav_loggedin_after():
|
|
|
"""Hook for registering additional user navigational items
|
|
|
which are only shown when a user is logged in.
|
|
|
|
|
@@ -104,38 +234,46 @@ def flaskbb_tpl_after_user_nav_loggedin():
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_before_registration_form():
|
|
|
+def flaskbb_tpl_form_registration_before(form):
|
|
|
"""This hook is emitted in the Registration form **before** the first
|
|
|
input field but after the hidden CSRF token field.
|
|
|
|
|
|
in :file:`templates/auth/register.html`.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
"""
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_after_registration_form():
|
|
|
+def flaskbb_tpl_form_registration_after(form):
|
|
|
"""This hook is emitted in the Registration form **after** the last
|
|
|
input field but before the submit field.
|
|
|
|
|
|
in :file:`templates/auth/register.html`.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
"""
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_before_user_details_form():
|
|
|
+def flaskbb_tpl_form_user_details_before(form):
|
|
|
"""This hook is emitted in the Change User Details form **before** an
|
|
|
input field is rendered.
|
|
|
|
|
|
in :file:`templates/user/change_user_details.html`.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
"""
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_after_user_details_form():
|
|
|
+def flaskbb_tpl_form_user_details_after(form):
|
|
|
"""This hook is emitted in the Change User Details form **after** the last
|
|
|
input field has been rendered but before the submit field.
|
|
|
|
|
|
in :file:`templates/user/change_user_details.html`.
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
"""
|
|
|
|
|
|
|
|
@@ -169,14 +307,32 @@ def flaskbb_tpl_profile_settings_menu():
|
|
|
"""
|
|
|
|
|
|
|
|
|
-# Event hooks
|
|
|
-
|
|
|
@spec
|
|
|
-def flaskbb_event_after_post(post, is_new):
|
|
|
- """Hook for handling a post after it has been saved.
|
|
|
+def flaskbb_tpl_admin_settings_menu(user):
|
|
|
+ """This hook is emitted in the admin panel and used to add additional
|
|
|
+ navigation links to the admin menu.
|
|
|
+
|
|
|
+ Implementations of this hook should return a list of tuples
|
|
|
+ that are view name, display text and optionally an icon.
|
|
|
+ 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():
|
|
|
+ # only add this item if the user is an admin
|
|
|
+ if Permission(IsAdmin, identity=current_user):
|
|
|
+ return [
|
|
|
+ ("myplugin.foobar", "Foobar", "fa fa-foobar")
|
|
|
+ ]
|
|
|
|
|
|
- :param flaskbb.forum.models.Post post: The post which triggered the event
|
|
|
- :param bool is_new: True if the post is new, False if it is an edit
|
|
|
+ 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/management_layout.html`
|
|
|
+
|
|
|
+ :param user: The current user object.
|
|
|
"""
|
|
|
|
|
|
|
|
@@ -193,7 +349,7 @@ def flaskbb_tpl_profile_sidebar_stats(user):
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_before_post_author_info(user, post):
|
|
|
+def flaskbb_tpl_post_author_info_before(user, post):
|
|
|
"""This hook is emitted before the information about the
|
|
|
author of a post is displayed (but after the username).
|
|
|
|
|
@@ -205,7 +361,7 @@ def flaskbb_tpl_before_post_author_info(user, post):
|
|
|
|
|
|
|
|
|
@spec
|
|
|
-def flaskbb_tpl_after_post_author_info(user, post):
|
|
|
+def flaskbb_tpl_post_author_info_after(user, post):
|
|
|
"""This hook is emitted after the information about the
|
|
|
author of a post is displayed (but after the username).
|
|
|
|
|
@@ -214,3 +370,117 @@ def flaskbb_tpl_after_post_author_info(user, post):
|
|
|
:param user: The user object of the post's author.
|
|
|
:param post: The post object.
|
|
|
"""
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_post_content_before(post):
|
|
|
+ """Hook to do some stuff before the post content is rendered.
|
|
|
+
|
|
|
+ in :file:`templates/forum/topic.html`
|
|
|
+
|
|
|
+ :param post: The current post object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_post_content_after(post):
|
|
|
+ """Hook to do some stuff after the post content is rendered.
|
|
|
+
|
|
|
+ in :file:`templates/forum/topic.html`
|
|
|
+
|
|
|
+ :param post: The current post object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_post_menu_before(post):
|
|
|
+ """Hook for inserting a new item at the beginning of the post menu.
|
|
|
+
|
|
|
+ in :file:`templates/forum/topic.html`
|
|
|
+
|
|
|
+ :param post: The current post object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_post_menu_after(post):
|
|
|
+ """Hook for inserting a new item at the end of the post menu.
|
|
|
+
|
|
|
+ in :file:`templates/forum/topic.html`
|
|
|
+
|
|
|
+ :param post: The current post object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_topic_controls(topic):
|
|
|
+ """Hook for inserting additional topic moderation controls.
|
|
|
+
|
|
|
+ in :file:`templates/forum/topic_controls.html`
|
|
|
+
|
|
|
+ :param topic: The current topic object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_form_new_post_before(form):
|
|
|
+ """Hook for inserting a new form field before the first field is
|
|
|
+ rendered.
|
|
|
+
|
|
|
+ For example::
|
|
|
+
|
|
|
+ @impl
|
|
|
+ def flaskbb_tpl_form_new_post_after(form):
|
|
|
+ return render_template_string(
|
|
|
+ \"""
|
|
|
+ <div class="form-group">
|
|
|
+ <div class="col-md-12 col-sm-12 col-xs-12">
|
|
|
+ <label>{{ form.example.label.text }}</label>
|
|
|
+
|
|
|
+ {{ form.example(class="form-control",
|
|
|
+ placeholder=form.example.label.text) }}
|
|
|
+
|
|
|
+ {%- for error in form.example.errors -%}
|
|
|
+ <span class="help-block">{{error}}</span>
|
|
|
+ {%- endfor -%}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ \"""
|
|
|
+
|
|
|
+ in :file:`templates/forum/new_post.html`
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_form_new_post_after(form):
|
|
|
+ """Hook for inserting a new form field after the last field is
|
|
|
+ rendered (but before the submit field).
|
|
|
+
|
|
|
+ in :file:`templates/forum/new_post.html`
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_form_new_topic_before(form):
|
|
|
+ """Hook for inserting a new form field before the first field is
|
|
|
+ rendered (but before the CSRF token).
|
|
|
+
|
|
|
+ in :file:`templates/forum/new_topic.html`
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ """
|
|
|
+
|
|
|
+
|
|
|
+@spec
|
|
|
+def flaskbb_tpl_form_new_topic_after(form):
|
|
|
+ """Hook for inserting a new form field after the last field is
|
|
|
+ rendered (but before the submit button).
|
|
|
+
|
|
|
+ in :file:`templates/forum/new_topic.html`
|
|
|
+
|
|
|
+ :param form: The form object.
|
|
|
+ """
|