Browse Source

Add hooks for adding new fields to reply form

Peter Justin 7 years ago
parent
commit
a5601af9e9

+ 4 - 0
flaskbb/forum/forms.py

@@ -13,6 +13,8 @@ from flask_wtf import FlaskForm
 from wtforms import (TextAreaField, StringField, SelectMultipleField,
 from wtforms import (TextAreaField, StringField, SelectMultipleField,
                      BooleanField, SubmitField)
                      BooleanField, SubmitField)
 from wtforms.validators import DataRequired, Optional, Length
 from wtforms.validators import DataRequired, Optional, Length
+
+from flask import current_app
 from flask_babelplus import lazy_gettext as _
 from flask_babelplus import lazy_gettext as _
 
 
 from flaskbb.forum.models import Topic, Post, Report, Forum
 from flaskbb.forum.models import Topic, Post, Report, Forum
@@ -48,6 +50,8 @@ class ReplyForm(FlaskForm):
 
 
         if self.track_topic.data:
         if self.track_topic.data:
             user.track_topic(topic)
             user.track_topic(topic)
+
+        current_app.pluggy.hook.flaskbb_form_new_post_save(form=self)
         return post.save(user=user, topic=topic)
         return post.save(user=user, topic=topic)
 
 
 
 

+ 12 - 3
flaskbb/forum/views.py

@@ -346,19 +346,24 @@ class ManageForum(MethodView):
 
 
 class NewPost(MethodView):
 class NewPost(MethodView):
     decorators = [allows.requires(CanPostReply), login_required]
     decorators = [allows.requires(CanPostReply), login_required]
-    form = ReplyForm
 
 
     def get(self, topic_id, slug=None):
     def get(self, topic_id, slug=None):
         topic = Topic.query.filter_by(id=topic_id).first_or_404()
         topic = Topic.query.filter_by(id=topic_id).first_or_404()
-        return render_template('forum/new_post.html', topic=topic, form=self.form())
+
+        return render_template(
+            'forum/new_post.html', topic=topic, form=self.form()
+        )
 
 
     def post(self, topic_id, slug=None):
     def post(self, topic_id, slug=None):
         topic = Topic.query.filter_by(id=topic_id).first_or_404()
         topic = Topic.query.filter_by(id=topic_id).first_or_404()
+
         form = self.form()
         form = self.form()
+
         if form.validate_on_submit():
         if form.validate_on_submit():
             if 'preview' in request.form:
             if 'preview' in request.form:
                 return render_template(
                 return render_template(
-                    'forum/new_post.html', topic=topic, form=form, preview=form.content.data
+                    'forum/new_post.html', topic=topic, form=form,
+                    preview=form.content.data
                 )
                 )
             else:
             else:
                 post = form.save(real(current_user), topic)
                 post = form.save(real(current_user), topic)
@@ -366,6 +371,10 @@ class NewPost(MethodView):
 
 
         return render_template('forum/new_post.html', topic=topic, form=form)
         return render_template('forum/new_post.html', topic=topic, form=form)
 
 
+    def form(self):
+        current_app.pluggy.hook.flaskbb_form_new_post(form=ReplyForm)
+        return ReplyForm()
+
 
 
 class ReplyPost(MethodView):
 class ReplyPost(MethodView):
     decorators = [allows.requires(CanPostReply), login_required]
     decorators = [allows.requires(CanPostReply), login_required]

+ 70 - 0
flaskbb/plugins/spec.py

@@ -78,6 +78,36 @@ def flaskbb_shell_context():
     """
     """
 
 
 
 
+# Form hooks
+@spec
+def flaskbb_form_new_post(form):
+    """Hook for modyfing the 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 ``ReplyForm`` class.
+    """
+
+
+@spec
+def flaskbb_form_new_post_save(form):
+    """Hook for modyfing the 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.
+    """
+
+
 # Template Hooks
 # Template Hooks
 
 
 @spec
 @spec
@@ -252,3 +282,43 @@ def flaskbb_tpl_after_post_author_info(user, post):
     :param user: The user object of the post's author.
     :param user: The user object of the post's author.
     :param post: The post object.
     :param post: The post 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).
+
+    :param form: The form object.
+    """

+ 7 - 0
flaskbb/templates/forum/new_post.html

@@ -40,10 +40,17 @@
 
 
                     <div class="form-group">
                     <div class="form-group">
                         <div class="col-md-12 col-sm-12 col-xs-12">
                         <div class="col-md-12 col-sm-12 col-xs-12">
+
                             <div class="editor-box">
                             <div class="editor-box">
+
+                                {{ run_hook("flaskbb_tpl_form_new_post_before", form=form) }}
+
                                 <div class="editor">
                                 <div class="editor">
                                     {{ render_quickreply(form.content, div_class="new-message", rows=7, cols=75, placeholder="", **{'data-provide': 'markdown', 'data-autofocus': 'false', 'class': 'flaskbb-editor'}) }}
                                     {{ render_quickreply(form.content, div_class="new-message", rows=7, cols=75, placeholder="", **{'data-provide': 'markdown', 'data-autofocus': 'false', 'class': 'flaskbb-editor'}) }}
                                 </div>
                                 </div>
+
+                                {{ run_hook("flaskbb_tpl_form_new_post_after", form=form) }}
+
                                 <div class="editor-submit">
                                 <div class="editor-submit">
                                     {{ render_submit_field(form.submit, input_class="btn btn-success pull-right") }}
                                     {{ render_submit_field(form.submit, input_class="btn btn-success pull-right") }}
                                 </div>
                                 </div>