spec.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.plugins.spec
  4. ~~~~~~~~~~~~~~~~~~~~~~~
  5. This module provides the core FlaskBB plugin hook definitions
  6. :copyright: (c) 2017 by the FlaskBB Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. from pluggy import HookspecMarker
  10. spec = HookspecMarker('flaskbb')
  11. # Setup Hooks
  12. @spec
  13. def flaskbb_extensions(app):
  14. """Hook for initializing any plugin loaded extensions."""
  15. @spec
  16. def flaskbb_load_translations():
  17. """Hook for registering translation folders."""
  18. @spec
  19. def flaskbb_load_migrations():
  20. """Hook for registering additional migrations."""
  21. @spec
  22. def flaskbb_load_blueprints(app):
  23. """Hook for registering blueprints."""
  24. @spec
  25. def flaskbb_request_processors(app):
  26. """Hook for registering pre/post request processors."""
  27. @spec
  28. def flaskbb_errorhandlers(app):
  29. """Hook for registering error handlers."""
  30. @spec
  31. def flaskbb_jinja_directives(app):
  32. """Hook for registering jinja filters, context processors, etc."""
  33. @spec
  34. def flaskbb_additional_setup(app, pluggy):
  35. """Hook for any additional setup a plugin wants to do after all other
  36. application setup has finished.
  37. For example, you could apply a WSGI middleware::
  38. @impl
  39. def flaskbb_additional_setup(app):
  40. app.wsgi_app = ProxyFix(app.wsgi_app)
  41. """
  42. @spec
  43. def flaskbb_cli(cli):
  44. """Hook for registering CLI commands."""
  45. @spec
  46. def flaskbb_shell_context():
  47. """
  48. Hook for registering shell context handlers
  49. Expected to return a single callable function that returns a dictionary or
  50. iterable of key value pairs.
  51. """
  52. # Form hooks
  53. @spec
  54. def flaskbb_form_new_post(form):
  55. """Hook for modyfing the ReplyForm.
  56. For example::
  57. @impl
  58. def flaskbb_form_new_post(form):
  59. form.example = TextField("Example Field", validators=[
  60. DataRequired(message="This field is required"),
  61. Length(min=3, max=50)])
  62. :param form: The ``ReplyForm`` class.
  63. """
  64. @spec
  65. def flaskbb_form_new_post_save(form):
  66. """Hook for modyfing the ReplyForm.
  67. This hook is called while populating the post object with
  68. the data from the form. The post object will be saved after the hook
  69. call.
  70. :param form: The form object.
  71. :param post: The post object.
  72. """
  73. # Template Hooks
  74. @spec
  75. def flaskbb_tpl_before_navigation():
  76. """Hook for registering additional navigation items.
  77. in :file:`templates/layout.html`.
  78. """
  79. @spec
  80. def flaskbb_tpl_after_navigation():
  81. """Hook for registering additional navigation items.
  82. in :file:`templates/layout.html`.
  83. """
  84. @spec
  85. def flaskbb_tpl_before_user_nav_loggedin():
  86. """Hook for registering additional user navigational items
  87. which are only shown when a user is logged in.
  88. in :file:`templates/layout.html`.
  89. """
  90. @spec
  91. def flaskbb_tpl_after_user_nav_loggedin():
  92. """Hook for registering additional user navigational items
  93. which are only shown when a user is logged in.
  94. in :file:`templates/layout.html`.
  95. """
  96. @spec
  97. def flaskbb_tpl_before_registration_form():
  98. """This hook is emitted in the Registration form **before** the first
  99. input field but after the hidden CSRF token field.
  100. in :file:`templates/auth/register.html`.
  101. """
  102. @spec
  103. def flaskbb_tpl_after_registration_form():
  104. """This hook is emitted in the Registration form **after** the last
  105. input field but before the submit field.
  106. in :file:`templates/auth/register.html`.
  107. """
  108. @spec
  109. def flaskbb_tpl_before_user_details_form():
  110. """This hook is emitted in the Change User Details form **before** an
  111. input field is rendered.
  112. in :file:`templates/user/change_user_details.html`.
  113. """
  114. @spec
  115. def flaskbb_tpl_after_user_details_form():
  116. """This hook is emitted in the Change User Details form **after** the last
  117. input field has been rendered but before the submit field.
  118. in :file:`templates/user/change_user_details.html`.
  119. """
  120. @spec
  121. def flaskbb_tpl_profile_settings_menu():
  122. """This hook is emitted on the user settings page in order to populate the
  123. side bar menu. Implementations of this hook should return a list of tuples
  124. that are view name and display text. The display text will be provided to
  125. the translation service so it is unnecessary to supply translated text.
  126. A plugin can declare a new block by setting the view to None. If this is
  127. done, consider marking the hook implementation with `trylast=True` to
  128. avoid capturing plugins that do not create new blocks.
  129. For example::
  130. @impl(trylast=True)
  131. def flaskbb_tpl_profile_settings_menu():
  132. return [
  133. (None, 'Account Settings'),
  134. ('user.settings', 'General Settings'),
  135. ('user.change_user_details', 'Change User Details'),
  136. ('user.change_email', 'Change E-Mail Address'),
  137. ('user.change_password', 'Change Password')
  138. ]
  139. Hookwrappers for this spec should not be registered as FlaskBB
  140. supplies its own hookwrapper to flatten all the lists into a single list.
  141. in :file:`templates/user/settings_layout.html`
  142. """
  143. @spec
  144. def flaskbb_tpl_admin_settings_menu(user):
  145. """This hook is emitted in the admin panel and used to add additional
  146. navigation links to the admin menu.
  147. Implementations of this hook should return a list of tuples
  148. that are view name, display text and optionally an icon.
  149. The display text will be provided to the translation service so it
  150. is unnecessary to supply translated text.
  151. For example::
  152. @impl(hookwrapper=True, tryfirst=True)
  153. def flaskbb_tpl_admin_settings_menu():
  154. # only add this item if the user is an admin
  155. if Permission(IsAdmin, identity=current_user):
  156. return [
  157. ("myplugin.foobar", "Foobar", "fa fa-foobar")
  158. ]
  159. Hookwrappers for this spec should not be registered as FlaskBB
  160. supplies its own hookwrapper to flatten all the lists into a single list.
  161. in :file:`templates/management/management_layout.html`
  162. """
  163. # Event hooks
  164. @spec
  165. def flaskbb_event_after_post(post, is_new):
  166. """Hook for handling a post after it has been saved.
  167. :param flaskbb.forum.models.Post post: The post which triggered the event
  168. :param bool is_new: True if the post is new, False if it is an edit
  169. """
  170. @spec
  171. def flaskbb_tpl_profile_sidebar_stats(user):
  172. """This hook is emitted on the users profile page below the standard
  173. information. For example, it can be used to add additional items
  174. such as a link to the profile.
  175. in :file:`templates/user/profile_layout.html`
  176. :param user: The user object for whom the profile is currently visited.
  177. """
  178. @spec
  179. def flaskbb_tpl_before_post_author_info(user, post):
  180. """This hook is emitted before the information about the
  181. author of a post is displayed (but after the username).
  182. in :file:`templates/forum/topic.html`
  183. :param user: The user object of the post's author.
  184. :param post: The post object.
  185. """
  186. @spec
  187. def flaskbb_tpl_after_post_author_info(user, post):
  188. """This hook is emitted after the information about the
  189. author of a post is displayed (but after the username).
  190. in :file:`templates/forum/topic.html`
  191. :param user: The user object of the post's author.
  192. :param post: The post object.
  193. """
  194. @spec
  195. def flaskbb_tpl_form_new_post_before(form):
  196. """Hook for inserting a new form field before the first field is
  197. rendered.
  198. For example::
  199. @impl
  200. def flaskbb_tpl_form_new_post_after(form):
  201. return render_template_string(
  202. \"""
  203. <div class="form-group">
  204. <div class="col-md-12 col-sm-12 col-xs-12">
  205. <label>{{ form.example.label.text }}</label>
  206. {{ form.example(class="form-control",
  207. placeholder=form.example.label.text) }}
  208. {%- for error in form.example.errors -%}
  209. <span class="help-block">{{error}}</span>
  210. {%- endfor -%}
  211. </div>
  212. </div>
  213. \"""
  214. in :file:`templates/forum/new_post.html`
  215. :param form: The form object.
  216. """
  217. @spec
  218. def flaskbb_tpl_form_new_post_after(form):
  219. """Hook for inserting a new form field after the last field is
  220. rendered (but before the submit field).
  221. :param form: The form object.
  222. """