forms: use a template to render widgets (#17964)

This commit is contained in:
Frédéric Péters 2017-07-23 17:02:38 +02:00
parent db4d477898
commit 3bdbe38a1b
5 changed files with 67 additions and 42 deletions

View File

@ -9,3 +9,4 @@ recursive-include data/themes/alto/ *.html *.css *.png *.gif *.jpg *.js *.ezt *.
recursive-include data/vendor/ *.dat
recursive-include wcs/qommon/static/ *.css *.png *.gif *.jpg *.js *.eot *.svg *.ttf *.woff
recursive-include wcs/templates *.html
recursive-include wcs/qommon/templates *.html

View File

@ -62,6 +62,10 @@ from quixote.form import *
from quixote.html import htmltext, htmltag, htmlescape, TemplateIO
from quixote.util import randbytes
from django.template import RequestContext
from django.utils.safestring import mark_safe
from .template import render as render_template
from wcs.portfolio import has_portfolio
from qommon import _, ngettext
@ -114,48 +118,30 @@ def render_title(self, title):
def render(self):
# quixote/form/widget.py, Widget::render
r = TemplateIO(html=True)
classnames = '%s widget' % self.__class__.__name__
if hasattr(self, 'extra_css_class') and self.extra_css_class:
classnames += ' ' + self.extra_css_class
if self.get_error():
classnames += ' widget-with-error'
if self.get_message():
classnames += ' widget-with-message'
if self.is_required():
classnames += ' widget-required'
else:
classnames += ' widget-optional'
if self.is_prefilled():
classnames += ' widget-prefilled'
attributes = {}
if hasattr(self, 'div_id') and self.div_id:
attributes['data-valuecontainerid'] = 'form_%s' % self.name
if hasattr(self, 'prefill_attributes') and self.prefill_attributes:
for k, v in self.prefill_attributes.items():
attributes['data-' + k] = v
if hasattr(self, 'div_id') and self.div_id:
attributes['id'] = self.div_id
for attr in ('data-dynamic-display-child-of', 'data-dynamic-display-value'):
if attr in self.attrs:
attributes[attr] = self.attrs.pop(attr)
attributes['class'] = classnames
r += htmltext('<div %s>' % ' '.join(['%s="%s"' % x for x in attributes.items()]))
r += self.render_title(self.get_title())
classnames = 'content'
if hasattr(self, 'content_extra_css_class') and self.content_extra_css_class:
classnames += ' ' + self.content_extra_css_class
r += htmltext('<div class="%s">' % classnames)
r += self.render_error(self.get_error())
r += self.render_content()
r += self.render_hint(self.get_hint())
r += self.render_message(self.get_message())
r += htmltext('</div>')
r += htmltext('</div>')
if self.render_br:
r += htmltext('<br class="%s" />') % classnames
r += htmltext('\n')
return r.getvalue()
def safe(text):
return mark_safe(str(htmlescape(text)))
self.class_name = self.__class__.__name__
self.rendered_title = lambda: safe(self.render_title(self.get_title()))
self.rendered_error = lambda: safe(self.render_error(self.get_error()))
self.rendered_hint = lambda: safe(self.render_hint(self.get_hint()))
self.rendered_message = lambda: safe(self.render_message(self.get_message()))
context = RequestContext(get_request(), {'widget': self})
template_names = []
widget_template_name = getattr(self, 'template_name', None)
for extra_css_class in (getattr(self, 'extra_css_class', '') or '').split():
if not extra_css_class.startswith('template-'):
continue
template_name = extra_css_class.split('-', 1)[1]
# full template
template_names.append('qommon/form/widgets/%s.html' % template_name)
if widget_template_name:
# widget specific variation
template_names.append(widget_template_name.replace(
'.html', '--%s.html' % template_name))
if widget_template_name:
template_names.append(widget_template_name)
template_names.append('qommon/forms/widget.html')
return htmltext(render_template(template_names, context))
Widget.get_error = get_i18n_error
Widget.render = render

View File

@ -0,0 +1,31 @@
{% load qommon %}
<div class="widget {{widget.class_name}} {{widget.extra_css_class}}
{% if widget.get_error %}widget-with-error{% endif %}
{% if widget.get_message %}widget-with-message{% endif %}
{% if widget.is_required %}widget-required{% else %}widget-optional{% endif %}
{% if widget.is_prefilled %}widget-prefilled{% endif %}"
{% if widget.div_id %}id="{{widget.div_id}}"{% endif %}
{% for attr in widget.prefill_attributes %}
data-{{attr}}="{{widget.prefill_attributes|get:attr}}"
{% endfor %}
{% if "data-dynamic-display-child-of" in widget.attrs %}
data-dynamic-display-child-of="{{widget.attrs|get:"data-dynamic-display-child-of"}}"
{% endif %}
{% if "data-dynamic-display-value" in widget.attrs %}
data-dynamic-display-value="{{widget.attrs|get:"data-dynamic-display-value"}}"
{% endif %}>
{% block widget-title %}
{{widget.rendered_title}}
{% endblock %}
{% block widget-content %}
<div class="content {{widget.content.content_extra_css_class}}">
{% block widget-error %}{{widget.rendered_error}}{% endblock %}
{% block widget-control %}{{widget.render_content|safe}}{% endblock %}
{% block widget-hint %}{{widget.rendered_hint}}{% endblock %}
{% block widget-message %}{{widget.rendered_message}}{% endblock %}
</div>
{% endblock %}
{% if widget.render_br %}
<br class="content {{widget.content.content_extra_css_class}}">
{% endif %}
</div>

View File

View File

@ -0,0 +1,7 @@
from django import template
register = template.Library()
@register.filter
def get(mapping, key):
return mapping.get(key)