Allow Widgets templates to be specified in a FormRenderer class
- Dominant language
- No language data
- Stars
- 188
- Forks
- 7
- PR merge metrics
- No merged PRs in 30d
Description
### Code of Conduct
- [x] I agree to follow Django's Code of Conduct
### Feature Description
Optionally allow Widget templates to be specified on a custom FormRenderer class. For example:
```py
class MyFormRenderer(TemplatesSetting):
form_template_name = "forms/my_form.html"
field_template_name = "forms/my_field.html"
# This is new - specific widget template
select_template_name = "forms/my_widget.html#select"
```
### Problem
We currently have the FormRenderer API which allows customisation of form rendering a variety of levels of specificity (settings, form class, form instance) via the following templates:
```
form_template_name = "django/forms/div.html"
formset_template_name = "django/forms/formsets/div.html"
field_template_name = "django/forms/field.html"
```
Currently to override Widgets at a global level, requires monkey-patching the `template_name` class attribute which then means there are possible clashes and bugs between the user facing styles and admin styles.
### Request or proposal
proposal
### Additional Details
_No response_
### Implementation Suggestions
Looking at the base `Widget` class it has two methods that deal with rendering. `render` and `_render`
I would propose adding a `get_template_name` method instead of calling `self.template_name` directly in this method, which would take a `renderer` argument. Off the top of my head something like this:
```py
class Widget:
def get_template_name(self, renderer, template_name):
renderer_widget_attr_name = f"{self.__class__.__name__}_template_name"
renderer_template_name = getattr(renderer, renderer_widget_attr_name, None)
if renderer_template_name:
return renderer_template_name
return template_name
def _render(self, template_name, context, renderer=None):
if renderer is None:
renderer = get_default_renderer()
template_name = self.get_template_name(renderer, template_name)
return mark_safe(renderer.render(template_name, context))
```
Perhaps there is a bit of a refactor of `render` and `_render`, but that is not necessary.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.