Welcome to django-uswds-forms’s documentation!

Welcome to the django-uswds-forms documentation!

This package provides Django Forms integration with the U.S. Web Design Standards.

Introduction

Motivation

The U.S. Web Design Standards are awesome, but there’s a few barriers that make it difficult to use with django.forms.Form. For example:

  • The CSS classes used by Django’s default renderer for things like errors and help text are not the same as those used by USWDS.
  • Individual checkboxes and radio buttons have different HTML markup than that rendered by Django forms.
  • Dates are split up into three separate month/day/year fields.
  • Dates and sets of checkboxes and radios need to use either <legend> or ARIA group roles to be accessible.

We implemented solutions for the above issues in CALC but wanted to factor them out for reuse by other Django projects, so we created this package.

Philosophy

This package has the following core values:

  • Low cognitive overhead. Where possible, this package aims to build upon the shoulders of the django.forms.renderers API introduced in Django 1.11. This means that, aside from understanding that API, developers should have to learn as few new concepts as possible to build forms that follow the U.S. Web Design Standards.
  • Extensibility. The HTML markup generated by the package’s components should be easy to modify and extend, when possible.
  • Accessibility. Forms generated by the package should work across a variety of accessible technologies (ATs), such as screen readers and voice recognition systems, with a minimal amount of work on the part of the developer.

Quick start guide

Prerequisites

  • This package contains no static files. This means you need to bring in USWDS from somewhere else–use whatever your preferred method from the USWDS developer guide.

    You should be able to use any version of USWDS you want, as this package only really depends on the HTML structure and CSS classes of a handful of USWDS widgets.

    You’ll also need to make sure the USWDS CSS is included in whatever pages you want to display your forms on.

  • You’ll need Django 1.11.1 or later.

  • Your project needs to use either Django’s default DjangoTemplates or Jinja2 template engine.

    In a similar vein, your forms need to use either Django’s default DjangoTemplates or Jinja2 form renderer.

  • Your project needs to use Python 3.

Installation

This package isn’t on PyPI yet, so you’ll need to install it directly from GitHub for now:

pip install git+git://github.com/18F/django-uswds-forms

Required settings

Add uswds_forms to your INSTALLED_APPS setting, e.g.:

INSTALLED_APPS = (
    # ...
    'uswds_forms',
    # ...
)

Jinja2 setup (optional)

If you’re using Django’s default template backend, you don’t need to do any extra configuration. However, if you’re using the Jinja2 backend, you might want to add some of this package’s Jinja2 functions to your Jinja2 environment.

For example, you can create myproject/jinja2.py with this content:

from jinja2 import Environment
import uswds_forms


def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'fieldset': uswds_forms.fieldset,
    })
    return env

and in your settings.py, set the environment option of the Jinja2 template engine to point at it, like so:

TEMPLATES = [
    # ...
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'environment': 'myproject.jinja2.environment',
        }
    },
    # ...
]

This will allow you to use e.g. the fieldset() function from any Jinja2 template.

Getting started

One way to get started is by visiting the example gallery. It contains a number of examples in increasing complexity. Each example can be tinkered with, and you can also easily view its Python and Django template source code.

If you want to run the example gallery locally, see Developing django-uswds-forms.

Guidelines

These guidelines are generally followed by the aforementioned example gallery, so refer to that if you want to see these in action.

  • If possible, use the UswdsForm class for your form. It will make error listings “just work”, and its as_fieldsets() can get you by in a pinch; for more fine-grained display of form fields, see the fieldset template tag.

  • In general, Django’s built-in Field classes should work okay out-of-the-box. The major exceptions to these are radios and checkboxes, which use slightly different markup in USWDS than Django’s default, so you’ll want to use our specialized widgets to replace Django’s defaults.

  • If you want automatic indication of required fields in the style shown in the USWDS name form template, you can set the required_css_class attribute on your form to 'usa-input-required'.

    (Unfortunately, there isn’t currently an easy way to do the inverse of this, where only optional fields are called out.)

API reference

Template tags

Important

This section is for projects using Django’s default DjangoTemplates backend. For projects using Jinja2, see the Jinja2 functions section.

To use the following template tags, you’ll need to load this package’s custom template tag set in your templates like so:

{% load uswds_forms %}

fieldset

The {% fieldset %} tag can be used to render a form field using the <fieldset> element. The field’s label is also rendered, along with any associated form errors and help text.

Markup is also added to ensure that screen reader users will have an easy time navigating grouped lists of options.

Sample usage:

{% fieldset my_form.name %}
{% fieldset my_form.address %}
{% fieldset my_form.birthday %}

Jinja2 functions

Important

This section is for projects using Django’s Jinja2 backend. For projects using Django templates, see the Template tags section.

For details on how to register any of these functions with your Jinja2 environment, see Jinja2 setup (optional).

uswds_forms.fieldset(field)[source]

Render the given bound field as a <fieldset>. The field’s label is also rendered, along with any associated form errors and help text.

Once added to a Jinja2 environment, this function can be used from Jinja2 templates like so:

{{ fieldset(my_form.name) }}
{{ fieldset(my_form.address) }}
{{ fieldset(my_form.birthday) }}

Form

class uswds_forms.UswdsForm[source]

This is a subclass of django.forms.Form that provides some functionality for rendering USWDS forms. Its constructor takes the exact same arguments, but some defaults are changed:

  • error_class defaults to uswds_forms.UswdsErrorList, so that errors are formatted nicely.
  • label_suffix defaults to the empty string, since none of the USWDS example forms have colons after the label names.
as_fieldsets()[source]

Like other convenience methods such as as_p() and as_table(), this method renders all the form’s fields as a series of <fieldset> elements.

Under the hood, this just iterates over the form’s fields and renders them via the fieldset template tag, so you can use that if you need more granular control over rendering.

Form fields

These fields use the same core field arguments as core Django.

class uswds_forms.UswdsDateField(**kwargs)[source]

A django.forms.MultiValueField for a USWDS-style date. Its value normalizes to a Python datetime.date object.

For an example of how this looks in practice, see the USWDS date input example.

class uswds_forms.UswdsMultipleChoiceField(**kwargs)[source]

This is just a django.forms.MultipleChoiceField that uses the UswdsCheckboxSelectMultiple widget.

We’ve provided this field for convenience because the usability of the default django.forms.SelectMultiple is so terrible that you’ll probably never want to use it. Burn your select tags!

Widgets

All of the following widgets work with the DjangoTemplates and Jinja2 form renderers.

class uswds_forms.UswdsCheckboxSelectMultiple[source]

This subclass of django.forms.CheckboxSelectMultiple styles grouped checkboxes appropriately for USWDS.

You can use this in a django.forms.MultipleChoiceField to get a list of checkboxes instead of a <select multiple> element for your choices.

For an example of how this looks in practice, see the USWDS checkboxes example.

class uswds_forms.UswdsDateWidget[source]

A django.forms.MultiWidget for a USWDS-style date, with separate number fields for date, month, and year.

This widget is used automatically by uswds_forms.UswdsDateField, so you probably won’t need to use it directly. However, it can be subclassed in case you need to customize it.

get_context(name, value, attrs)[source]

Returns the context for the widget’s template. This returns a superset of what’s provided by its superclass’ get_context() implementation, adding the following keys to widget:

  • 'hint_id': The unique id of some hint text showing users an example of what they can enter.
  • 'subwidgets': This has the same iterable value described in the superclass documentation, but it has been enhanced such that its year, month, and day properties are aliases to its entries. Using these aliases can potentially make templates more readable.
template_name = 'uswds_forms/date.html'

This is the default template used by the widget, which can be overridden if needed.

class uswds_forms.UswdsRadioSelect[source]

This subclass of django.forms.RadioSelect styles radio buttons appropriately for USWDS.

You can use this in a django.forms.ChoiceField to get a list of radio buttons instead of a <select> element for your choices.

For an example of how this looks in practice, see the USWDS radio buttons example.

Other utilities

class uswds_forms.UswdsErrorList[source]

This is an error list formatter that renders errors in the style used by USWDS forms. For an example of how this makes errors look in practice, see the USWDS text inputs example.

Note that you probably don’t need to use this class directly, as UswdsForm uses it by default.

For more details on how to use this class, see the Django documentation on customizing the error list format.

Developing django-uswds-forms

Important

This section is about developing django-uswds-forms itself, not using it in your Django project. For details on the latter, see the Quick start guide.

First, clone the git repository:

git clone https://github.com/18F/django-uswds-forms

Then create a virtualenv for the project and install development dependencies:

virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements-dev.txt

Then install django-uswds-forms in development mode:

python setup.py develop

You will also need to download PhantomJS and put it somewhere on your PATH, as it’s required by the test suite.

Running tests

You can run all the tests with code coverage:

pytest

You can also ensure that there aren’t any linting errors:

flake8

To run all tests, linters, and other automated QA against all supported runtimes and dependencies, run:

tox

Writing documentation

If you want to work on documentation, you can run the development documentation server with:

python setup.py devdocs

Indices and tables