Skip to content

Instantly share code, notes, and snippets.

@aphillipo
Created March 9, 2015 17:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aphillipo/2b401a42b583ff900ba0 to your computer and use it in GitHub Desktop.
Save aphillipo/2b401a42b583ff900ba0 to your computer and use it in GitHub Desktop.
Bootstrap3 Jinja 2 WTForms Macros with Recursive Form Field rendering.
{# Renders field for bootstrap 3 standards.
Params:
field - WTForm field
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
#}
{% macro render_field(field, label_visible=true) -%}
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
{% if (field.type != 'HiddenField' or field.type !='CSRFTokenField') and label_visible %}
<label for="{{ field.id }}" class="control-label">{{ field.label.text }}</label>
{% endif %}
{{ field(class_='form-control', **kwargs) }}
{% if field.description %}
<p class="help-block">{{ field.description }}</p>
{% endif %}
{% if field.errors %}
{% for e in field.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
{%- endmacro %}
{# Renders checkbox fields since they are represented differently in bootstrap
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_checkbox_field(form.remember_me) }}
#}
{% macro render_checkbox_field(field) -%}
<div class="checkbox">
<label for="{{ field.id }}">{{ field(type='checkbox', **kwargs) }} {{ field.label.text }}</label>
{% if field.description %}
<p class="help-block">{{ field.description }}</p>
{% endif %}
</div>
{%- endmacro %}
{% macro render_multi_checkbox_field(field) -%}
{% if field %}
<div class="checkbox-group{% if field.errors %} has-error{% endif %}">
<ul>
{% for f in field %}
<li>
{{ render_checkbox_field(f) }}
</li>
{% endfor %}
</ul>
{% if field.errors %}
{% for e in field.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
{% endif %}
{%- endmacro %}
{# Renders radio field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_radio_field(form.answers) }}
#}
{% macro render_radio_field(field) -%}
{% for value, label, checked in field.iter_choices() %}
<div class="radio">
<input type="radio" name="{{ field.name }}" id="{{ field.id }}" value="{{ value }}"{% if checked %} checked=”true”{% endif %}>{{ label }}
</div>
{% endfor %}
{%- endmacro %}
{% macro render_form_fields(form, action_url, ignore_csrf_field=False, wrap_with_fieldset=False) -%}
{% if form.type and form.type == 'FormField' %}
{% set legend = form.label.text %}
{% set form = form.form %}
{% endif %}
{{ form.hidden_tag() if form.hidden_tag }}
{% if wrap_with_fieldset %}
<fieldset>
<legend>{{ legend }}</legend>
{% endif %}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{% if f.type == 'FormField' %}
{{ render_form_fields(f, ignore_csrf_field=True, wrap_with_fieldset=True) }}
{% elif f.type == 'MultiCheckboxField' %}
{{ render_multi_checkbox_field(f) }}
{% elif f.type == 'BooleanField' %}
{{ render_checkbox_field(f) }}
{% elif f.type == 'RadioField' %}
{{ render_radio_field(f) }}
{% elif f.type == 'CSRFTokenField' %}
{% if not ignore_csrf_field %}
{{ render_field(f, label_visible=False) }}
{% endif %}
{% else %}
{{ render_field(f) }}
{% endif %}
{% endfor %}
{% endif %}
{% if wrap_with_fieldset %}
</fieldset>
{% endif %}
{%- endmacro %}
{# Renders WTForm in bootstrap way. There are two ways to call function:
- as macros: it will render all field forms using cycle to iterate over them
- as call: it will insert form fields as you specify:
e.g. {% call macros.render_form(form, action_url=url_for('login_view'), action_text='Login',
class_='login-form') %}
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
{{ macros.render_field(form.password, placeholder='Input password', type='password') }}
{{ macros.render_checkbox_field(form.remember_me, type='checkbox') }}
{% endcall %}
Params:
form - WTForm class
action_url - url where to submit this form
action_text - text of submit button
class_ - sets a class for form
#}
{% macro render_form(form, action_url='', action_text='Submit', class_='', btn_class='btn btn-default') -%}
<form method="POST" action="{{ action_url }}" role="form" class="{{ class_ }}">
{{ render_form_fields(form=form, action_url=action_url) }}
<button type="submit" class="{{ btn_class }}">{{ action_text }} </button>
</form>
{%- endmacro %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment