I would like to have a <ul>
inside the help_text
of a django form field.
Unfortunately django renders the help_text
inside a <span>
.
According to the HTML spec a <span>
must not contain a <ul>
. At least that is what my validation tool says.
Here is the source of django: https://github.com/django/django/blob/master/django/forms/forms.py#L283
def as_table(self):
"Return this form rendered as HTML <tr>s -- excluding the <table></table>."
return self._html_output(
normal_row='<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>',
error_row='<tr><td colspan="2">%s</td></tr>',
row_ender='</td></tr>',
help_text_html='<br><span class="helptext">%s</span>',
errors_on_separate_row=False)
What can I do to get <ul>
in the help_text
and valid html.
Overriding as_table()
does not work, since the form is from "core_app" and the field is from a plugin. Both are two different git repos and I don't want to modify the core just because of this.
As you already mentioned, in HTML there is a concept of block and inline elements.
In short block elements generate a new line and may contain other block and inline elements. Inline elements don't generate a new line and may contain other inline elements, but not block elements.
MDN web docs offers more information on block and inline elements.
Since span
is an inline element, you can't place ul
which is a block-level element inside. Or, you could, but then it's not a valid HTML, and that's not what you want.
Since you're using a third-party code, modifiying it could introduce other problems.
You could fork it, modify the parts you need and then use your fork. But when that third-party code gets updated, you have to repeat the whole process.
In cases like that you could just do monkey patching.
For your particular problem we could therefore do something like this:
from django import forms
class MyBaseForm(forms.BaseForm):
def as_table(self):
"Return this form rendered as HTML s -- excluding the ."
return self._html_output(
normal_row='%(label)s%(errors)s%(field)s%(help_text)s',
error_row='%s',
row_ender='',
help_text_html='<div class="helptext">%s</div>',
errors_on_separate_row=False)
BaseForm.as_table = MyBaseForm.as_table
You can place this code in your forms.py
or any other file that is suitable to you.
Now the help_text
will be rendered as a div
element, which is a block-level element. You can place an unordered list ul
inside and have a valid HTML.
Monkey patching isn't the most beautiful way of solving problems, but it is in my opinion a pragmatic way to overcome some tricky issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With