Metadata-Version: 2.1
Name: django-prose-editor
Version: 0.3.4
Summary: Prose editor for the Django admin based on ProseMirror
Project-URL: Homepage, https://github.com/matthiask/django-prose-editor/
Author-email: Matthias Kestenholz <mk@feinheit.ch>
License-Expression: BSD-3-Clause
License-File: LICENSE
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.10
Requires-Dist: django>=4.2
Provides-Extra: tests
Requires-Dist: coverage; extra == 'tests'
Requires-Dist: nh3; extra == 'tests'
Description-Content-Type: text/x-rst

===================
django-prose-editor
===================

Prose editor for the Django admin based on ProseMirror. `Announcement blog post <https://406.ch/writing/django-prose-editor-prose-editing-component-for-the-django-admin/>`__.


About rich text editors
=======================

Copied from the `django-content-editor documentation <https://django-content-editor.readthedocs.io/en/latest/>`__.

We have been struggling with rich text editors for a long time. To be honest, I do not think it was a good idea to add that many features to the rich text editor. Resizing images uploaded into a rich text editor is a real pain, and what if you’d like to reuse these images or display them using a lightbox script or something similar? You have to resort to writing loads of JavaScript code which will only work on one browser. You cannot really filter the HTML code generated by the user to kick out ugly HTML code generated by copy-pasting from word. The user will upload 10mb JPEGs and resize them to 50x50 pixels in the rich text editor.

All of this convinced me that offering the user a rich text editor with too much capabilities is a really bad idea. The rich text editor in FeinCMS only has bold, italic, bullets, link and headlines activated (and the HTML code button, because that’s sort of inevitable – sometimes the rich text editor messes up and you cannot fix it other than going directly into the HTML code. Plus, if someone really knows what they are doing, I’d still like to give them the power to shot their own foot).

If this does not seem convincing you can always add your own rich text plugin with a different configuration (or just override the rich text editor initialization template in your own project). We do not want to force our world view on you, it’s just that we think that in this case, more choice has the bigger potential to hurt than to help.


Installation
~~~~~~~~~~~~

Install the package:

.. code-block:: shell

    venv/bin/pip install django-prose-editor

Add ``django_prose_editor`` to ``INSTALLED_APPS``:

.. code-block:: python

    INSTALLED_APPS = [
        # ...
        "django_prose_editor",
    ]

Replace ``models.TextField`` with ``ProseEditorField`` where appropriate:

.. code-block:: python

    from django_prose_editor.fields import ProseEditorField

    class Project(models.Model):
        description = ProseEditorField()

Note! No migrations will be generated when switching from and to
``models.TextField``. That's by design. Those migrations are mostly annoying.


Security
~~~~~~~~

ProseMirror does a really good job of only allowing content which confirms to a
particular scheme. Of course users can submit what they want, they are not
constrainted by the HTML widgets you're using. You should still always sanitize
the HTML submitted on the server side. A good way to do this is by using the
``sanitize`` argument to the ``ProseEditorField``. You can use the following
snippet to always pass HTML through `nh3
<https://nh3.readthedocs.io/en/latest/>`__:

.. code-block:: python

    from django_prose_editor.sanitized import SanitizedProseEditorField

    description = SanitizedProseEditorField()


Convenience
~~~~~~~~~~~

Sometimes it may be useful to show an excerpt of the HTML field; the
``ProseEditorField`` automatically adds a ``get_*_excerpt`` method to models
which returns the truncated and stripped beginning of your HTML field's
content. The name would be ``Project.get_description_excerpt`` in the example
above.


Customization
~~~~~~~~~~~~~

It's possible to slightly customize the field or widget by passing an optional
``config`` dictionary. The default configuration is:

.. code-block:: python

    config = {
        "types": None,    # Allow all nodes and marks
        "history": True,  # Enable undo and redo
        "html": True,     # Add a button which allows editing the raw HTML
    }

If you only want to support paragraphs, strong, emphasis, sub- and superset and
no history or HTML editing you could add the following field:

.. code-block:: python

    text = SanitizedProseEditorField(
        config={"types": ["strong", "em", "sub", "sup"]},
    )

Paragraphs cannot be removed at the moment. Note that the backend doesn't
sanitize the content to ensure that the HTML doesn't contain only the provided
tags, that's out of scope for now.
