Form validation and rendering for Python web development.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
HTML rendering system with customizable widgets for different input types, from basic text inputs to complex multi-select components and custom layouts. Widgets handle the conversion of form fields into HTML markup with proper attributes and styling.
Core utilities for HTML generation and attribute handling.
def html_params(**kwargs) -> str:
"""
Generate HTML attributes from keyword arguments.
Parameters:
- **kwargs: Attribute name-value pairs
Returns:
str: HTML attribute string
Example:
html_params(id="myfield", class_="form-control", required=True)
# Returns: 'id="myfield" class="form-control" required'
"""Foundation widget classes that other widgets inherit from.
class Widget:
"""
Base widget class for HTML rendering.
"""
def __call__(self, field, **kwargs) -> str:
"""
Render field as HTML.
Parameters:
- field: Field instance to render
- **kwargs: Additional HTML attributes
Returns:
str: HTML markup
"""
class Input(Widget):
"""
Base class for HTML input elements.
Parameters:
- input_type: HTML input type attribute
"""
def __init__(self, input_type=None): ...
def __call__(self, field, **kwargs) -> str: ...Widgets for various text input types.
class TextInput(Input):
"""
Standard text input widget.
Renders: <input type="text" />
"""
def __init__(self): ...
class PasswordInput(Input):
"""
Password input widget (hides input value).
Renders: <input type="password" />
Parameters:
- hide_value: Whether to hide value in HTML (default: True)
"""
def __init__(self, hide_value=True): ...
class HiddenInput(Input):
"""
Hidden input widget.
Renders: <input type="hidden" />
"""
def __init__(self): ...
class TextArea(Widget):
"""
Multi-line textarea widget.
Renders: <textarea></textarea>
"""
def __call__(self, field, **kwargs) -> str: ...Modern HTML5 input types with enhanced validation and user experience.
class EmailInput(Input):
"""
HTML5 email input widget.
Renders: <input type="email" />
"""
def __init__(self): ...
class URLInput(Input):
"""
HTML5 URL input widget.
Renders: <input type="url" />
"""
def __init__(self): ...
class SearchInput(Input):
"""
HTML5 search input widget.
Renders: <input type="search" />
"""
def __init__(self): ...
class TelInput(Input):
"""
HTML5 telephone input widget.
Renders: <input type="tel" />
"""
def __init__(self): ...
class NumberInput(Input):
"""
HTML5 number input widget.
Renders: <input type="number" />
Parameters:
- step: Step value for numeric input
- min: Minimum value
- max: Maximum value
"""
def __init__(self, step=None, min=None, max=None): ...
class RangeInput(Input):
"""
HTML5 range input widget.
Renders: <input type="range" />
Parameters:
- step: Step value for range input
"""
def __init__(self, step=None): ...
class ColorInput(Input):
"""
HTML5 color input widget.
Renders: <input type="color" />
"""
def __init__(self): ...Widgets for date and time input with HTML5 support.
class DateInput(Input):
"""
HTML5 date input widget.
Renders: <input type="date" />
"""
def __init__(self): ...
class TimeInput(Input):
"""
HTML5 time input widget.
Renders: <input type="time" />
"""
def __init__(self): ...
class DateTimeInput(Input):
"""
HTML5 datetime input widget.
Renders: <input type="datetime" />
"""
def __init__(self): ...
class DateTimeLocalInput(Input):
"""
HTML5 datetime-local input widget.
Renders: <input type="datetime-local" />
"""
def __init__(self): ...
class MonthInput(Input):
"""
HTML5 month input widget.
Renders: <input type="month" />
"""
def __init__(self): ...
class WeekInput(Input):
"""
HTML5 week input widget.
Renders: <input type="week" />
"""
def __init__(self): ...Widgets for selecting from multiple options.
class CheckboxInput(Input):
"""
Checkbox input widget.
Renders: <input type="checkbox" />
"""
def __init__(self): ...
class RadioInput(Input):
"""
Radio input widget.
Renders: <input type="radio" />
"""
def __init__(self): ...
class Select(Widget):
"""
Select dropdown widget.
Renders: <select><option>...</option></select>
Parameters:
- multiple: Whether to allow multiple selections
"""
def __init__(self, multiple=False): ...
def __call__(self, field, **kwargs) -> str: ...
class Option(Widget):
"""
Option element for Select widget.
Renders: <option value="...">label</option>
"""
def __call__(self, field, **kwargs) -> str: ...Widgets for file uploads.
class FileInput(Input):
"""
File input widget.
Renders: <input type="file" />
Parameters:
- multiple: Whether to allow multiple file selection
"""
def __init__(self, multiple=False): ...Widgets for form submission and actions.
class SubmitInput(Input):
"""
Submit button widget.
Renders: <input type="submit" />
"""
def __init__(self): ...Widgets for organizing and grouping multiple fields.
class ListWidget(Widget):
"""
Container widget that renders fields as list items.
Used for RadioField and CheckboxField groups.
Parameters:
- html_tag: HTML tag for container (default: "ul")
- prefix_label: Whether to put label before input (default: True)
"""
def __init__(self, html_tag="ul", prefix_label=True): ...
def __call__(self, field, **kwargs) -> str: ...
class TableWidget(Widget):
"""
Container widget that renders fields in table format.
Used for FormField to organize nested forms.
Parameters:
- with_table_tag: Whether to wrap in <table> tag (default: True)
"""
def __init__(self, with_table_tag=True): ...
def __call__(self, field, **kwargs) -> str: ...from wtforms import Form, StringField
from wtforms.widgets import TextInput, TextArea
class MyForm(Form):
# Default widget (TextInput)
name = StringField('Name')
# Custom widget
bio = StringField('Biography', widget=TextArea())
# Widget with custom attributes
email = StringField('Email',
widget=TextInput(),
render_kw={'placeholder': 'Enter your email', 'class': 'form-control'}
)
# Render fields
form = MyForm()
print(form.name()) # <input id="name" name="name" type="text" value="" />
print(form.bio()) # <textarea id="bio" name="bio"></textarea>
print(form.email()) # <input class="form-control" id="email" name="email" placeholder="Enter your email" type="text" value="" />from wtforms import Form, StringField, IntegerField, DateField
from wtforms.widgets import EmailInput, NumberInput, DateInput, ColorInput
class ProfileForm(Form):
email = StringField('Email', widget=EmailInput())
website = StringField('Website', widget=URLInput())
age = IntegerField('Age', widget=NumberInput(min=13, max=120))
birth_date = DateField('Birth Date', widget=DateInput())
favorite_color = StringField('Favorite Color', widget=ColorInput())
# Range input with custom attributes
satisfaction = IntegerField('Satisfaction',
widget=RangeInput(step=1),
render_kw={'min': 1, 'max': 10}
)
# Generated HTML includes HTML5 validation attributes
form = ProfileForm()
print(form.age()) # <input id="age" max="120" min="13" name="age" type="number" value="" />from wtforms import Form, SelectField, SelectMultipleField
from wtforms.widgets import Select
class PreferencesForm(Form):
# Default Select widget
country = SelectField('Country', choices=[
('us', 'United States'),
('ca', 'Canada')
])
# Multiple selection
languages = SelectMultipleField('Languages',
choices=[
('en', 'English'),
('es', 'Spanish'),
('fr', 'French')
],
widget=Select(multiple=True)
)
form = PreferencesForm()
print(form.country())
# <select id="country" name="country">
# <option value="us">United States</option>
# <option value="ca">Canada</option>
# </select>
print(form.languages())
# <select id="languages" multiple name="languages">
# <option value="en">English</option>
# <option value="es">Spanish</option>
# <option value="fr">French</option>
# </select>from wtforms import Form, RadioField
from wtforms.widgets import ListWidget, RadioInput
class SurveyForm(Form):
rating = RadioField('Rating',
choices=[
('1', 'Poor'),
('2', 'Fair'),
('3', 'Good'),
('4', 'Very Good'),
('5', 'Excellent')
],
widget=ListWidget(prefix_label=False),
option_widget=RadioInput()
)
form = SurveyForm()
print(form.rating())
# <ul id="rating">
# <li><input id="rating-0" name="rating" type="radio" value="1"> <label for="rating-0">Poor</label></li>
# <li><input id="rating-1" name="rating" type="radio" value="2"> <label for="rating-1">Fair</label></li>
# ...
# </ul>from wtforms import Form, FileField, MultipleFileField
from wtforms.widgets import FileInput
class UploadForm(Form):
single_file = FileField('Upload File', widget=FileInput())
multiple_files = MultipleFileField('Upload Files',
widget=FileInput(multiple=True)
)
form = UploadForm()
print(form.single_file()) # <input id="single_file" name="single_file" type="file" />
print(form.multiple_files()) # <input id="multiple_files" multiple name="multiple_files" type="file" />from wtforms.widgets import Widget
from wtforms import Form, StringField
class StarRatingWidget(Widget):
"""Custom star rating widget."""
def __call__(self, field, **kwargs):
kwargs.setdefault('id', field.id)
html = []
# Add star rating HTML
html.append(f'<div class="star-rating" id="{field.id}">')
for i in range(1, 6):
checked = 'checked' if field.data == str(i) else ''
html.append(f'''
<input type="radio" name="{field.name}" value="{i}" {checked} />
<label for="{field.id}-{i}">★</label>
''')
html.append('</div>')
return ''.join(html)
class ReviewForm(Form):
rating = StringField('Rating', widget=StarRatingWidget())
comment = StringField('Comment')
form = ReviewForm()
print(form.rating()) # Custom star rating HTMLfrom wtforms import Form, StringField, SelectField, SubmitField
from wtforms.widgets import TextInput, Select, SubmitInput
class BootstrapForm(Form):
name = StringField('Name',
widget=TextInput(),
render_kw={'class': 'form-control', 'placeholder': 'Enter your name'}
)
category = SelectField('Category',
choices=[('tech', 'Technology'), ('science', 'Science')],
widget=Select(),
render_kw={'class': 'form-select'}
)
submit = SubmitField('Submit',
widget=SubmitInput(),
render_kw={'class': 'btn btn-primary'}
)
form = BootstrapForm()
print(form.name())
# <input class="form-control" id="name" name="name" placeholder="Enter your name" type="text" value="" />from wtforms import Form, StringField
from wtforms.widgets import TextInput, TextArea
class DynamicForm(Form):
content = StringField('Content')
def __init__(self, use_textarea=False, *args, **kwargs):
super().__init__(*args, **kwargs)
# Choose widget based on condition
if use_textarea:
self.content.widget = TextArea()
else:
self.content.widget = TextInput()
# Usage
short_form = DynamicForm(use_textarea=False)
long_form = DynamicForm(use_textarea=True)
print(short_form.content()) # <input type="text" ... />
print(long_form.content()) # <textarea>...</textarea>from wtforms import Form, StringField
from wtforms.widgets import html_params
class CustomForm(Form):
username = StringField('Username')
# Render with custom attributes
form = CustomForm()
field = form.username
# Method 1: Using render_kw
field.render_kw = {'class': 'form-control', 'data-validate': 'true'}
print(field())
# Method 2: Passing attributes directly
print(field(class_='form-control', placeholder='Enter username'))
# Method 3: Using html_params utility
attrs = html_params(id=field.id, name=field.name, class_='form-control', required=True)
print(f'<input {attrs} />')from wtforms import Form, StringField, FormField
from wtforms.widgets import TableWidget
class AddressForm(Form):
street = StringField('Street')
city = StringField('City')
zipcode = StringField('Zip Code')
class UserForm(Form):
name = StringField('Name')
address = FormField(AddressForm, widget=TableWidget())
form = UserForm()
print(form.address())
# <table>
# <tr><th><label for="address-street">Street</label></th>
# <td><input id="address-street" name="address-street" type="text" value="" /></td></tr>
# <tr><th><label for="address-city">City</label></th>
# <td><input id="address-city" name="address-city" type="text" value="" /></td></tr>
# ...
# </table>from wtforms import Form, StringField, SelectField, BooleanField
from wtforms.widgets import CheckboxInput
class ThemedForm(Form):
# Material Design theme
name = StringField('Name', render_kw={
'class': 'mdc-text-field__input',
'placeholder': ' ' # Required for Material Design
})
# Tailwind CSS theme
category = SelectField('Category',
choices=[('a', 'Option A'), ('b', 'Option B')],
render_kw={
'class': 'block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500'
}
)
# Custom checkbox styling
agree = BooleanField('I agree',
widget=CheckboxInput(),
render_kw={
'class': 'h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded'
}
)
form = ThemedForm()
# Each field renders with appropriate CSS classesInstall with Tessl CLI
npx tessl i tessl/pypi-wtforms