Add clean method to QuestionForm to unwrap single <p> tags from TinyMCE HTML fields
This commit is contained in:
@@ -22,6 +22,7 @@ from django.contrib.admin.widgets import FilteredSelectMultiple
|
|||||||
from django.forms.widgets import RadioSelect, TextInput, Textarea
|
from django.forms.widgets import RadioSelect, TextInput, Textarea
|
||||||
|
|
||||||
from tinymce.widgets import TinyMCE
|
from tinymce.widgets import TinyMCE
|
||||||
|
import re
|
||||||
|
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
from crispy_forms.helper import FormHelper
|
from crispy_forms.helper import FormHelper
|
||||||
@@ -160,6 +161,45 @@ class QuestionForm(ModelForm):
|
|||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
"""Strip a single wrapping <p>...</p> from TinyMCE-provided HTML fields.
|
||||||
|
|
||||||
|
This handles the common TinyMCE behaviour where the editor wraps
|
||||||
|
inline content in a root <p>. We only unwrap when the entire value
|
||||||
|
is a single <p> element (so multi-paragraph content is preserved).
|
||||||
|
"""
|
||||||
|
cleaned = super(QuestionForm, self).clean()
|
||||||
|
|
||||||
|
def _unwrap_single_p(html: str) -> str:
|
||||||
|
if not html or not isinstance(html, str):
|
||||||
|
return html
|
||||||
|
# Match a single <p ...>...</p> that spans the whole string
|
||||||
|
m = re.fullmatch(r"\s*<p\b[^>]*>(.*)</p>\s*", html, flags=re.DOTALL | re.IGNORECASE)
|
||||||
|
if m:
|
||||||
|
return m.group(1)
|
||||||
|
return html
|
||||||
|
|
||||||
|
fields_to_unwrap = [
|
||||||
|
"stem",
|
||||||
|
"feedback",
|
||||||
|
"a_answer",
|
||||||
|
"a_feedback",
|
||||||
|
"b_answer",
|
||||||
|
"b_feedback",
|
||||||
|
"c_answer",
|
||||||
|
"c_feedback",
|
||||||
|
"d_answer",
|
||||||
|
"d_feedback",
|
||||||
|
"e_answer",
|
||||||
|
"e_feedback",
|
||||||
|
]
|
||||||
|
|
||||||
|
for fname in fields_to_unwrap:
|
||||||
|
if fname in cleaned:
|
||||||
|
cleaned[fname] = _unwrap_single_p(cleaned.get(fname))
|
||||||
|
|
||||||
|
return cleaned
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Question
|
model = Question
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user