Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9f094f5
Showing
11 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
include MANIFEST.in | ||
recursive-include formhelper/templates * |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
================= | ||
Django FormHelper | ||
================= | ||
|
||
Django FormHelper is a collection of templates and templatetags to ease the | ||
pain in building out web forms. It does this by breaking the form down into | ||
separate re-usable and customizable components. This allows you to only | ||
customize the parts you want, and let the rest happen automatically. | ||
|
||
|
||
Usage | ||
============= | ||
After installing django-formhelper, add ``formhelper`` to your ``INSTALLED_APPS`` in your ``settings.py``. | ||
|
||
In your template, you need to load ``formhelper``: | ||
|
||
... | ||
{% load formhelper %} | ||
... | ||
|
||
|
||
Template Tags | ||
============= | ||
|
||
---------- | ||
form_field | ||
---------- | ||
Render out a single form field. Uses the template ``formhelper/includes/field.html``. Example usage: | ||
|
||
{% form_field contact_form first_name %} | ||
|
||
If your form is in your view's context as the variable "form", you can omit the first argument: | ||
|
||
{% form_field first_name %} | ||
|
||
Otherwise, you can use the "with" templatetag | ||
|
||
{% with my_form as form %} | ||
... | ||
{% form_field first_name %} | ||
... | ||
{% endwith %} | ||
|
||
|
||
-------- | ||
form_row | ||
-------- | ||
Like form_field, but renders out multiple fields. Uses the template ``formhelper/includes/form_row.html``. Example usage: | ||
|
||
{% form_row first_name middle_name last_name %} | ||
|
||
|
||
---------- | ||
error_list | ||
---------- | ||
Render out the form error list as an unordered list. Uses the template ``formhelper/includes/error_list.html`` Example usage: | ||
|
||
{% error_list %} | ||
|
||
You may also render out only non-field errors or only field-specific errors: | ||
|
||
{% error_list non_field %} | ||
... or ... | ||
{% error_list field %} | ||
|
||
----------- | ||
class_names | ||
----------- | ||
Renders a list of useful class names for a field that includes the field name, the widget type, whether or not the field is requried, and whether or not the field has an error. | ||
|
||
For example, if your field was a textinput named "first_name" and it was required: | ||
|
||
<div class="{% field|class_names %}"> | ||
|
||
would result in: | ||
|
||
<div class="first_name text-input required"> | ||
|
||
if the field has an error: | ||
|
||
<div class="first_name text-input required error"> | ||
|
||
Templates | ||
========= | ||
``formhelper/includes/form.html`` | ||
|
||
``formhelper/includes/form_row.html`` | ||
|
||
``formhelper/includes/field.html`` | ||
|
||
``formhelper/includes/errorlist.html`` |
Empty file.
Empty file.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{% load formhelper %} | ||
{% if form.errors %} | ||
<ul class="errorlist non-field-errors"> | ||
{% if not only == "field" %} | ||
{% for err in form.non_field_errors %} | ||
<li>{{ err }}</li> | ||
{% endfor %} | ||
{% endif %} | ||
{% if not only == "non_field" %} | ||
{% for field in form %} | ||
{% if field.errors %}<li>{{ field|field_error }}</li>{% endif %} | ||
{% endfor %} | ||
{% endif %} | ||
</ul> | ||
{% endif %} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{% load formhelper %} | ||
<div class="field {{ field|class_names }}"> | ||
<label for="id_{{ field.name }}">{{ field.label }}{% if field.field.required %}<span>*</span>{% endif %}</label> | ||
{{ field.errors }} | ||
{{ field }} | ||
</div> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{% load formhelper %} | ||
{% error_list form %} | ||
{% for field in form %} | ||
{% form_field field %} | ||
{% endfor %} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{% load formhelper %} | ||
<div class="form-row"> | ||
{% for field in fields %} | ||
{% form_field form field %} | ||
{% endfor %} | ||
</div> |
Empty file.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
from django import template | ||
from django.template.loader import get_template | ||
from django import forms | ||
import re | ||
|
||
register = template.Library() | ||
first_cap_re = re.compile('(.)([A-Z][a-z]+)') | ||
all_cap_re = re.compile('([a-z0-9])([A-Z])') | ||
|
||
@register.filter | ||
def field_error(field): | ||
if field.errors: | ||
err = field.errors[0] | ||
if err == unicode(field.field.default_error_messages.get('required')): | ||
err = '%s is required' % field.label | ||
else: | ||
err = '%s: ' % field.label | ||
return err | ||
return '' | ||
|
||
@register.filter | ||
def class_names(field): | ||
class_names = [field.name.replace('_','-')] | ||
widget_class = pyclass_to_cssclass(field.field.widget.__class__.__name__) | ||
class_names.append(widget_class) | ||
if field.field.required: | ||
class_names.append('required') | ||
if field.errors: | ||
class_names.append('error') | ||
return ' '.join(class_names) | ||
|
||
class FormFieldNode(template.Node): | ||
def __init__(self, form, field): | ||
if not form: | ||
form = 'form' | ||
self.form = template.Variable(form) | ||
self.field = field | ||
|
||
def render(self, context): | ||
try: | ||
form = self.form.resolve(context) | ||
except template.VariableDoesNotExist: | ||
raise template.TemplateSyntaxError('a form must either be passed to form_field as first argument or must exist in context as "form"') | ||
tpl = get_template('formhelper/includes/field.html') | ||
field = _get_field(self.field, form, context) | ||
return tpl.render(template.Context({'form':form, 'field':field})) | ||
|
||
@register.tag | ||
def form_field(parser, token): | ||
args = token.split_contents()[1:] | ||
if not args: | ||
raise template.TemplateSyntaxError("form_field takes at least one argument") | ||
if len(args) == 1: | ||
return FormFieldNode(None, args[0]) | ||
return FormFieldNode(args[0], args[1]) | ||
|
||
class FormRowNode(template.Node): | ||
def __init__(self, args): | ||
self.args = args | ||
|
||
def render(self, context): | ||
tpl = get_template('formhelper/includes/form_row.html') | ||
if context.get(self.args[0]) and isinstance(context[self.args[0]], forms.Form): | ||
form = context[self.args[0]] | ||
field_list = self.args[1:] | ||
elif context.get('form'): | ||
form = context['form'] | ||
field_list = self.args | ||
else: | ||
raise template.TemplateSyntaxError('a form must either be passed to form_row as first argument or must exist in context as "form"') | ||
fields = [_get_field(f, form, context) for f in field_list] | ||
return tpl.render(template.Context({'form': form, 'fields': fields})) | ||
|
||
@register.tag | ||
def form_row(parser, token): | ||
args = token.split_contents()[1:] | ||
if not args: | ||
raise template.TemplateSyntaxError("form_row takes at least one argument") | ||
return FormRowNode(args) | ||
|
||
@register.inclusion_tag('formhelper/includes/errorlist.html') | ||
def error_list(form, only=''): | ||
return {'form':form, 'only':only} | ||
|
||
def _get_field(field, form, context): | ||
try: | ||
field = template.Variable(field).resolve(context) | ||
except template.VariableDoesNotExist: | ||
pass | ||
if isinstance(field, basestring): | ||
field = form[field] | ||
return field | ||
|
||
def pyclass_to_cssclass(name): | ||
s1 = first_cap_re.sub(r'\1-\2', name) | ||
return all_cap_re.sub(r'\1-\2', s1).lower() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from setuptools import setup, find_packages | ||
|
||
setup( | ||
name='formhelper', | ||
version='0.1', | ||
author='Ben Davis', | ||
author_email='bendavis78@gmail.com', | ||
url='http://github.com/bendavis78', | ||
description='Django FormHelper is a collection of templates and templatetags to ease the pain in building out web forms', | ||
keywords='django forms', | ||
classifiers = [ | ||
'Development Status :: 4 - Beta', | ||
'Intended Audience :: Developers', | ||
'Operating System :: OS Independent', | ||
'Programming Language :: Python', | ||
'Topic :: Software Development :: Libraries :: Python Modules' | ||
], | ||
packages = find_packages(), | ||
include_package_data = True | ||
) |