-
-
Save blturner/244334 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<li class="formrow formrow_{{ field.name }}{% if errors %} has_errors{% endif %}{% if not field.field.required %} optional{% else %} required{% endif %}"> | |
<label for="{{ field.auto_id }}">{{ field.label }}{% if not field.field.required %}<em> (optional)</em>{% endif %}</label> | |
{{ errors }} | |
{{ field }} | |
<small class="help_text">{{ help_text }}</small>{{ hiddenfields }} | |
</li> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This is only here temporarily until I have a chance to move it to GH and give it | |
attention. It's plumbing I'm stealing from myself. -- Xian | |
""" | |
from django import template | |
from django.forms import Form, BaseForm | |
from django.forms.forms import BoundField | |
from django.template import Context, Template, TemplateDoesNotExist | |
from django.template.loader import select_template | |
from django.utils.encoding import force_unicode | |
from django.utils.html import escape | |
from django.utils.safestring import mark_safe | |
register = template.Library() | |
@register.filter | |
def get_fields(form, field_names): | |
""" | |
Returns the named fields from a Form as a list of BoundFields. Usage: | |
{% for field in form|get_fields:"field1,field2,field3" %} | |
""" | |
fields = [] | |
if not isinstance(form, BaseForm): | |
return fields | |
else: | |
field_names = field_names.split(',') | |
for name in field_names: | |
fields.append(BoundField(form, form.fields[name], name)) | |
return fields | |
@register.filter | |
def exclude_fields(form, field_names): | |
""" | |
Returns the fields of a Form excluding the named fields. Usage: | |
{% for field in form|exclude_fields:"field1,field2,field3" %} | |
""" | |
fields = [] | |
if isinstance(form, BaseForm): | |
field_names = field_names.split(',') | |
for field in form.fields: | |
if field not in field_names: | |
fields.append(BoundField(form, form.fields[field], field)) | |
return fields | |
## the next couple of fuctions are messier than they should be but they work | |
def _get_field_context(bf, bf_errors, error_list_format=None): | |
"""A helper method for for setting up the context for for a field""" | |
form = bf.form | |
if bf.label: | |
label = escape(force_unicode(bf.label)) | |
# Only add the suffix if the label does not end in punctuation. | |
# This should probably be in the label_tag method | |
if form.label_suffix: | |
if label[-1] not in ':?.!': | |
label += form.label_suffix | |
label = bf.label_tag(label) or '' | |
else: | |
label = '' | |
if bf.help_text: | |
help_text = bf.help_text | |
else: | |
help_text = u'' | |
if error_list_format: | |
try: | |
bf_errors = force_unicode(getattr(bf_errors, error_list_format)()) | |
except AttributeError: | |
bf_errors = force_unicode(bf_errors) | |
return {'errors': bf_errors, 'label': label, 'field': bf, 'help_text': help_text } | |
def form_output_filter_helper(form_or_field, template, error_list_format=None): | |
"Helper function for outputting HTML. Used by for form output filters" | |
output, hidden_fields, row_contexts = [], [], [] | |
if isinstance(form_or_field, BoundField): | |
bf = form_or_field | |
form = form_or_field.form | |
bf_errors = form.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable. | |
row_contexts.append(_get_field_context(bf, bf_errors, error_list_format)) | |
elif isinstance(form_or_field, BaseForm): | |
form = form_or_field | |
for bf in form: | |
bf_errors = form.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable. | |
if bf.is_hidden: | |
hidden_fields.append(unicode(bf)) | |
else: | |
row_contexts.append(_get_field_context(bf, bf_errors, error_list_format)) | |
else: | |
return form_or_field | |
if hidden_fields: # Insert any hidden fields in the last row. | |
str_hidden = u''.join(hidden_fields) | |
if row_contexts: | |
# Add hidden fields to the last row's context. | |
last_row = row_contexts[-1] | |
last_row['hidden_fields'] = str_hidden | |
if output: | |
output[-1] = last_row | |
else: # If there aren't any rows in the output, just append the hidden fields. | |
output.append(str_hidden) | |
if row_contexts: | |
if not isinstance(template, Template): | |
template = Template(template) | |
for row in row_contexts: | |
output.append(template.render(Context(row))) | |
return mark_safe(u'\n'.join(output)) | |
@register.filter | |
def as_table(form_or_field): | |
"Returns this form rendered as HTML <tr>s -- excluding the <table></table>." | |
row = """<tr><td colspan="2">{{ errors }}</td></tr> | |
<tr><th>{{ label }}</th><td>{{ field }} {% if help_text %}<br>{{ help_text }}{% endif %} {{ hidden_fields }}</td></tr>""" | |
return form_output_filter_helper(form_or_field, row) | |
# This one shows off the template advantage in that it's easy to do things like | |
# add the field_name as a class to each row and adding a has_error class when appropriate | |
@register.filter | |
def as_ul(form_or_field): | |
"Returns this form rendered as HTML <li>s -- excluding the <ul></ul>." | |
row = """<li class="{{ field.name }}{% if errors %} has_errors"{% endif %}> | |
{{ errors }}{{ label }} {{ field }} {{ help_text }}{{ hiddenfields }} | |
</li> | |
""" | |
return form_output_filter_helper(form_or_field, row) | |
# This one shows off that you can pass a format type to the error list class | |
@register.filter | |
def as_p(form_or_field): | |
"Returns this form rendered as HTML <p>s." | |
row = """{{ errors }} | |
<p>{{ label }} {{ field }} {{ help_text }}{{ hiddenfields }}</p>""" | |
return form_output_filter_helper(form_or_field, row, 'as_text') | |
@register.filter | |
def as_template(form_or_field, templatename="forms/as_template.html"): | |
""" | |
Returns this form or field using the django template specified for each row. | |
Uses `forms/as_template.html` by default but can be passed one more more | |
template paths (comma separated) to render. | |
""" | |
templatenames = templatename.split(',') | |
try: | |
row_template = select_template(templatenames) | |
except TemplateDoesNotExist: | |
return "" | |
return form_output_filter_helper(form_or_field, row_template) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{ form|as_template }} | |
{{ form.email|as_template }} | |
{% for field in form|get_fields:"name,email,phone" %} | |
{{ field|as_template }} | |
{% endfor %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment