diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0dd255f..b306703 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,10 @@ Next version ~~~~~~~~~~~~ - Allowed installing the package in Python 3.10 environments too. +- Tweaked the cleaning methods of ``ProseEditorField`` and + ``SanitizedProseEditorField`` to produce empty strings when no content is + entered. Previously they would produce an empty paragraph (``

``) since + our ProseMirror schema says that there exists always one or more block nodes. 0.3 (2024-04-09) diff --git a/django_prose_editor/fields.py b/django_prose_editor/fields.py index 35fcd1c..e83a3cf 100644 --- a/django_prose_editor/fields.py +++ b/django_prose_editor/fields.py @@ -1,3 +1,5 @@ +import re + from django import forms from django.db import models from django.utils.html import strip_tags @@ -6,13 +8,21 @@ from django_prose_editor.widgets import ProseEditorWidget -def _identity(x): +def _actually_empty(x): + """ + ProseMirror's schema always adds at least one empty paragraph + + We want empty fields to actually be empty strings so that those field + values evaluate as ``False`` in a boolean context. + """ + if re.match(r"^<(?P\w+)>$", x): + return "" return x class ProseEditorField(models.TextField): def __init__(self, *args, **kwargs): - self.sanitize = kwargs.pop("sanitize", _identity) + self.sanitize = kwargs.pop("sanitize", _actually_empty) self.config = kwargs.pop("config", {}) super().__init__(*args, **kwargs) diff --git a/django_prose_editor/sanitized.py b/django_prose_editor/sanitized.py index 1e0a81e..52fedce 100644 --- a/django_prose_editor/sanitized.py +++ b/django_prose_editor/sanitized.py @@ -1,10 +1,14 @@ -from django_prose_editor.fields import ProseEditorField +from django_prose_editor.fields import ProseEditorField, _actually_empty + + +def _nh3_sanitizer(): + from nh3 import clean + + return lambda x: _actually_empty(clean(x)) class SanitizedProseEditorField(ProseEditorField): def __init__(self, *args, **kwargs): if "sanitize" not in kwargs: - from nh3 import clean - - kwargs["sanitize"] = clean + kwargs["sanitize"] = _nh3_sanitizer() super().__init__(*args, **kwargs) diff --git a/tests/testapp/test_prose_editor.py b/tests/testapp/test_prose_editor.py index a8b30fa..afcfc0c 100644 --- a/tests/testapp/test_prose_editor.py +++ b/tests/testapp/test_prose_editor.py @@ -2,12 +2,33 @@ from django.db import models from django.test.utils import isolate_apps +from django_prose_editor.fields import ProseEditorField from django_prose_editor.sanitized import SanitizedProseEditorField class Test(test.TestCase): @isolate_apps() - def test_field(self): + def test_standard_field(self): + class Model(models.Model): + description = ProseEditorField() + + def __str__(self): + return self.description + + m = Model(description="

") + m.full_clean() + self.assertEqual(m.description, "") + + m = Model(description="

") + m.full_clean() + self.assertEqual(m.description, "") + + m = Model(description="

hello

") + m.full_clean() + self.assertEqual(m.description, "

hello

") + + @isolate_apps() + def test_sanitized_field(self): class Model(models.Model): description = SanitizedProseEditorField() @@ -17,3 +38,15 @@ def __str__(self): m = Model(description="

Hello

") m.full_clean() self.assertEqual(m.description, "

Hello

") + + m = Model(description="

") + m.full_clean() + self.assertEqual(m.description, "") + + m = Model(description="

") + m.full_clean() + self.assertEqual(m.description, "") + + m = Model(description="

hello

") + m.full_clean() + self.assertEqual(m.description, "

hello

")