Customization¶
Override default templates¶
Widgets have a template_name
attribute that points to the template that is
used when rendering the form. Default templates are provided for all
built-in widgets. In most cases the default
implementation of these templates have no specific behaviour and simply inherit
from floppyforms/input.html
. They are provided mainly to give an easy
way for a site-wide customization of how a specifig widget is rendered.
You can easily override these templates in your project-level
TEMPLATE_DIRS
, assuming they take precedence over app-level templates.
Custom widgets with custom templates¶
If you want to override the rendering behaviour only for a few widgets, you
can extend a Widget
class from FloppyForms and override the
template_name
attribute:
import floppyforms as forms
class OtherEmailInput(forms.EmailInput):
template_name = 'path/to/other_email.html'
Then, the output can be customized in other_email.html
:
<input type="email"
name="{{ name }}"
id="{{ attrs.id }}"
placeholder="john@example.com"
{% if value %}value="{{ value }}"{% endif %}>
Here we have a hardcoded placeholder without needing to instantiate the widget
with an attrs
dictionary:
class EmailForm(forms.Form):
email = forms.EmailField(widget=OtherEmailInput())
You can also customize the template_name
without subclassing, by passing it
as an argument when instantiating the widget:
class EmailForm(forms.Form):
email = forms.EmailField(
widget=forms.EmailInput(template_name='path/to/other_email.html'))
For advanced use, you can even customize the template used per-render, by
passing a template_name
argument to the widget’s render()
method.
Adding more template variables¶
There is also a way to add extra context. This is done by subclassing the
widget class and extending the get_context()
method:
class OtherEmailInput(forms.EmailInput):
template_name = 'path/to/other.html'
def get_context(self, name, value, attrs):
ctx = super(OtherEmailInput, self).get_context(name, value, attrs)
ctx['foo'] = 'bar'
return ctx
And then the other.html
template can make use of the {{ foo }}
context
variable.
get_context()
takes name
, value
and attrs
as arguments, except
for all Select
widgets which take an additional choices
argument.
In case you don’t need the arguments passed to get_context()
, you can
extend get_context_data()
which doesn’t take any arguments:
class EmailInput(forms.EmailInput):
def get_context_data(self):
ctx = super(EmailInput, self).get_context_data()
ctx.update({
'placeholder': 'hello@example.com',
})
return ctx
Altering the widget’s attrs
¶
All widget attibutes except for type
, name
, value
and required
are put in the attrs
context variable, which you can extend in
get_context()
:
def get_context(self, name, value, attrs):
ctx = super(MyWidget, self).get_context(name, value, attrs)
ctx['attrs']['class'] = 'mywidget'
return ctx
This will render the widget with an additional class="mywidget"
attribute.
If you want only the attribute’s key to be rendered, set it to True
:
def get_context(self, name, value, attrs):
ctx = super(MyWidget, self).get_context(name, value, attrs)
ctx['attrs']['awesome'] = True
return ctx
This will simply add awesome
as a key-only attribute.