forms: use django templates to render form pages (#21627)

This commit is contained in:
Frédéric Péters 2018-02-04 14:35:43 +01:00
parent 055d6a29f3
commit 320dee2376
9 changed files with 70 additions and 29 deletions

View File

@ -43,7 +43,7 @@ from qommon.backoffice.menu import html_top
from qommon.admin.menu import error_page
from qommon.admin.cfg import cfg_submit
from qommon.admin.emails import EmailsDirectory
from qommon.admin.texts import TextsDirectory
from wcs.qommon.admin.texts import TextsDirectory
from qommon.admin.settings import SettingsDirectory as QommonSettingsDirectory
from qommon.admin.logger import LoggerDirectory
import qommon.ident

View File

@ -14,6 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from django.utils.safestring import mark_safe
from quixote import get_publisher, get_request, get_response, get_session, redirect
from quixote.directory import Directory
from quixote.html import TemplateIO, htmltext
@ -74,6 +76,9 @@ class FormFillPage(PublicFormFillPage):
_q_exports = ['', 'tempfile', 'autosave', 'code',
('remove', 'remove_draft')]
filling_templates = ['wcs/formdata_filling.html']
validation_templates = ['wcs/formdata_validation.html']
def __init__(self, *args, **kwargs):
super(FormFillPage, self).__init__(*args, **kwargs)
self.selected_submission_channel = None
@ -165,7 +170,7 @@ class FormFillPage(PublicFormFillPage):
r += htmltext('<div id="side">')
r += self.step(step_no, page_no, data=data)
r += htmltext('</div> <!-- #side -->')
return r.getvalue()
return mark_safe(str(r.getvalue()))
def submitted(self, form, *args):
filled = self.get_current_draft() or self.formdef.data_class()()

View File

@ -31,7 +31,7 @@ from qommon import template
from qommon import get_logger
from qommon.form import *
from qommon.admin.texts import TextsDirectory
from wcs.qommon.admin.texts import TextsDirectory
from qommon import errors
@ -102,7 +102,18 @@ class FilesDirectory(Directory):
return FileDirectory(self.formdata, reference=component)
class FormStatusPage(Directory):
class FormTemplateMixin(object):
def get_formdef_template_variants(self, template_names):
template_part_names = [(os.path.dirname(x), os.path.basename(x)) for x in template_names]
for dirname, basename in template_part_names:
for keyword in self.formdef.appearance_keywords_list:
yield os.path.join(dirname, 'appearance-' + keyword, basename)
if self.formdef.category_id:
yield os.path.join(dirname, 'category-' + self.formdef.category.url_name, basename)
yield os.path.join(dirname, basename)
class FormStatusPage(Directory, FormTemplateMixin):
_q_exports_orig = ['', 'download', 'json', 'action']
_q_extra_exports = []
form_page_class = None
@ -214,13 +225,6 @@ class FormStatusPage(Directory):
r += htmltext('</p>')
return r.getvalue()
def get_formdef_template_variants(self, template_names):
template_part_names = [(os.path.dirname(x), os.path.basename(x)) for x in template_names]
for dirname, basename in template_part_names:
for keyword in self.formdef.appearance_keywords_list:
yield os.path.join(dirname, 'appearance-' + keyword, basename)
yield os.path.join(dirname, basename)
def _q_index(self):
mine = self.check_auth()
get_logger().info('form %s - id: %s - view' % (self.formdef.name, self.filled.id))

View File

@ -25,6 +25,8 @@ try:
except ImportError:
qrcode = None
from django.utils.safestring import mark_safe
from quixote import (get_publisher, get_request, get_response, get_session,
get_session_manager, redirect)
from quixote.directory import Directory, AccessControlled
@ -44,10 +46,11 @@ from qommon import emails
from wcs.categories import Category
from wcs.formdef import FormDef
from wcs.formdata import FormData
from wcs.forms.common import FormTemplateMixin
from wcs.roles import logged_users_role
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef
from qommon.admin.texts import TextsDirectory
from wcs.qommon.admin.texts import TextsDirectory
class SubmittedDraftException(Exception):
@ -165,10 +168,13 @@ class TrackingCodesDirectory(Directory):
def _q_lookup(self, component):
return TrackingCodeDirectory(component, self.formdef)
class FormPage(Directory):
class FormPage(Directory, FormTemplateMixin):
_q_exports = ['', 'tempfile', 'schema', 'tryauth',
'auth', 'qrcode', 'autosave', 'code', 'removedraft']
filling_templates = ['wcs/front/formdata_filling.html', 'wcs/formdata_filling.html']
validation_templates = ['wcs/front/formdata_validation.html', 'wcs/formdata_validation.html']
def __init__(self, component):
try:
self.formdef = FormDef.get_by_urlname(component)
@ -277,7 +283,6 @@ class FormPage(Directory):
return r.getvalue()
def page(self, page_no, page_change=True, page_error_messages=None):
r = TemplateIO(html=True)
displayed_fields = []
session = get_session()
@ -387,8 +392,6 @@ class FormPage(Directory):
form.get_widget('f%s' % field.id).prefill_attributes = field.get_prefill_attributes()
self.html_top(self.formdef.name)
r += self.form_side(0, page_no, data=data, magictoken=magictoken)
r += get_session().display_message()
form.add_hidden('step', '0')
form.add_hidden('page', page_no)
@ -398,8 +401,18 @@ class FormPage(Directory):
form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft',
attrs={'style': 'display: none'})
r += form.render()
return r.getvalue()
context = {
'view': self,
'form': form,
'form_side': lambda: self.form_side(0, page_no, data=data, magictoken=magictoken),
'steps': lambda: self.step(0, page_no, data=data),
}
if self.formdef.enable_tracking_codes and data:
context['tracking_code_box'] = lambda: self.tracking_code_box(data, magictoken)
return template.render(
list(self.get_formdef_template_variants(self.filling_templates)),
context)
def form_side(self, step_no, page_no, data=None, magictoken=None):
'''Create the elements that typically appear aside the main form
@ -413,7 +426,7 @@ class FormPage(Directory):
r += self.tracking_code_box(data, magictoken)
r += self.step(step_no, page_no, data=data)
r += htmltext('</div> <!-- #side -->')
return r.getvalue()
return mark_safe(str(r.getvalue()))
def tracking_code_box(self, data, magictoken):
'''Create the tracking code box, it displays the current tracking code
@ -1060,11 +1073,6 @@ class FormPage(Directory):
def validating(self, data):
self.html_top(self.formdef.name)
r = TemplateIO(html=True)
r += htmltext('<div class="form-validation">')
r += self.form_side(step_no=1, page_no=None, data=data,
magictoken=get_request().form['magictoken'])
r += TextsDirectory.get_html_text('check-before-submit')
form = self.create_view_form(data)
token_widget = form.get_widget(form.TOKEN_NAME)
token_widget._parsed = True
@ -1085,9 +1093,17 @@ class FormPage(Directory):
form.add_hidden('step', '2')
magictoken = get_request().form['magictoken']
form.add_hidden('magictoken', magictoken)
r += form.render()
r += htmltext('</div>')
return r.getvalue()
context = {
'view': self,
'form': form,
'form_side': lambda: self.form_side(step_no=1, page_no=None, data=data,
magictoken=magictoken),
}
return template.render(
list(self.get_formdef_template_variants(self.validation_templates)),
context)
def tryauth(self):
return tryauth(self.formdef.get_url())

View File

@ -39,7 +39,7 @@ from qommon.admin.menu import command_icon
from qommon.backoffice.menu import html_top
from qommon.admin.emails import EmailsDirectory
from qommon.admin.texts import TextsDirectory
from wcs.qommon.admin.texts import TextsDirectory
from qommon.cron import CronJob
from qommon.afterjobs import AfterJob

View File

@ -27,7 +27,7 @@ from qommon import errors
import qommon.ident.password
from qommon.ident.password_accounts import PasswordAccount
from qommon.admin.texts import TextsDirectory
from wcs.qommon.admin.texts import TextsDirectory
# This module depends upon the following protocol from the user class:
#

View File

@ -16,7 +16,9 @@
from django import template
from django.utils import dateparse
from django.utils.safestring import mark_safe
from wcs.qommon import evalutils
from wcs.qommon.admin.texts import TextsDirectory
register = template.Library()
@ -54,3 +56,7 @@ def parse_time(time_string):
return dateparse.parse_time(time_string)
except ValueError:
return None
@register.simple_tag
def standard_text(text_id):
return mark_safe(TextsDirectory.get_html_text(str(text_id)))

View File

@ -0,0 +1,3 @@
{{ form_side|default:"" }}
{{ publisher.get_request.session.display_message|safe }}
{{ form.render|safe }}

View File

@ -0,0 +1,7 @@
{% load qommon %}
<div class="form-validation">
{{ form_side|default:"" }}
{% standard_text "check-before-submit" %}
{{ form.render|safe }}
</div>