0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-25 05:02:57 +01:00

Update documentation for rich text element whitelisting

This commit is contained in:
Matt Westcott 2018-01-05 16:15:26 +00:00
parent 670bce0c4d
commit b9a548f424
3 changed files with 92 additions and 10 deletions

View File

@ -74,7 +74,7 @@ This can be achieved by passing a ``features`` keyword argument to ``RichTextFie
body = RichTextField(features=['h2', 'h3', 'bold', 'italic', 'link'])
The recognised feature identifiers are as follows (note that add-on modules may add to this list):
The feature identifiers provided on a default Wagtail installation are as follows:
* ``h1``, ``h2``, ``h3``, ``h4``, ``h5``, ``h6`` - heading elements
* ``bold``, ``italic`` - bold / italic text
@ -85,14 +85,27 @@ The recognised feature identifiers are as follows (note that add-on modules may
* ``image`` - embedded images
* ``embed`` - embedded media (see :ref:`embedded_content`)
Adding new features to this list is generally a two step process:
* Create a plugin that extends the editor with a new toolbar button for adding a particular HTML element
* Add that HTML element to the whitelist of elements that are permitted in rich text output
Both of these steps are performed through the ``register_rich_text_features`` hook (see :ref:`admin_hooks`). The hook function is triggered on startup, and receives a *feature registry* object as its argument; this object keeps track of the behaviours associated with each feature identifier.
This process for adding new features is described in the following sections.
.. _extending_wysiwyg:
Extending the WYSIWYG Editor (``hallo.js``)
-------------------------------------------
+++++++++++++++++++++++++++++++++++++++++++
Wagtail's rich text editor is built on ``hallo.js``, and its functionality can be extended through plugins. For information on developing custom ``hallo.js`` plugins, see the project's page: https://github.com/bergie/hallo
Once the plugin has been created, it should be registered as a rich text feature using the ``register_rich_text_features`` hook. For example, a plugin ``halloblockquote``, implemented in ``myapp/js/hallo-blockquote.js``, that adds support for the ``<blockquote>`` tag, would be registered under the feature name ``blockquote`` as follows:
Once the plugin has been created, it should be registered through the feature registry's ``register_editor_plugin(editor, feature_name, plugin)`` method. For a ``hallo.js`` plugin, the ``editor`` parameter should always be ``'hallo'``.
A plugin ``halloblockquote``, implemented in ``myapp/js/hallo-blockquote.js``, that adds support for the ``<blockquote>`` tag, would be registered under the feature name ``block-quote`` as follows:
.. code-block:: python
@ -102,17 +115,13 @@ Once the plugin has been created, it should be registered as a rich text feature
@hooks.register('register_rich_text_features')
def register_embed_feature(features):
features.register_editor_plugin(
'hallo', 'blockquote',
'hallo', 'block-quote',
HalloPlugin(
name='halloblockquote',
js=['myapp/js/hallo-blockquote.js'],
)
)
.. note::
When extending the rich text editor to support a new HTML element, it will also be necessary to update the HTML whitelisting rules, via the :ref:`construct_whitelister_element_rules` hook.
The constructor for ``HalloPlugin`` accepts the following keyword arguments:
* ``name`` - the plugin name as defined in the Javascript code. ``hallo.js`` plugin names are prefixed with the ``"IKS."`` namespace, but the name passed here should be without the prefix.
@ -130,10 +139,37 @@ To have a feature active by default (i.e. on ``RichTextFields`` that do not defi
@hooks.register('register_rich_text_features')
def register_blockquote_feature(features):
features.register_editor_plugin(
'hallo', 'blockquote',
'hallo', 'block-quote',
# ...
)
features.default_features.append('blockquote')
features.default_features.append('block-quote')
.. _whitelisting_rich_text_elements:
Whitelisting rich text elements
+++++++++++++++++++++++++++++++
After extending the editor to support a new HTML element, you'll need to add it to the whitelist of permitted elements - Wagtail's standard behaviour is to strip out unrecognised elements, to prevent editors from inserting styles and scripts (either deliberately, or inadvertently through copy-and-paste) that the developer didn't account for.
Elements can be added to the whitelist through the feature registry's ``register_converter_rule(converter, feature_name, ruleset)`` method. When the ``hallo.js`` editor is in use, the ``converter`` parameter should always be ``'editorhtml'``.
The following code will add the ``<blockquote>`` element to the whitelist whenever the ``block-quote`` feature is active:
.. code-block:: python
from wagtail.admin.rich_text.converters.editor_html import WhitelistRule
from wagtail.core.whitelist import allow_without_attributes
@hooks.register('register_rich_text_features')
def register_blockquote_feature(features):
features.register_converter_rule('editorhtml', 'block-quote', [
WhitelistRule('blockquote', allow_without_attributes),
])
``WhitelistRule`` is passed the element name, and a callable which will perform some kind of manipulation of the element whenever it is encountered. This callable receives the element as a `BeautifulSoup <http://www.crummy.com/software/BeautifulSoup/bs4/doc/>`_ Tag object.
The ``wagtail.core.whitelist`` module provides a few helper functions to assist in defining these handlers: ``allow_without_attributes``, a handler which preserves the element but strips out all of its attributes, and ``attribute_rule`` which accepts a dict specifying how to handle each attribute, and returns a handler function. This dict will map attribute names to either True (indicating that the attribute should be kept), False (indicating that it should be dropped), or a callable (which takes the initial attribute value and returns either a final value for the attribute, or None to drop the attribute).
.. _rich_text_image_formats:

View File

@ -266,11 +266,21 @@ Editor interface
Hooks for customising the editing interface for pages and snippets.
.. _register_rich_text_features:
``register_rich_text_features``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rich text fields in Wagtail work with a list of 'feature' identifiers that determine which editing controls are available in the editor, and which elements are allowed in the output; for example, a rich text field defined as ``RichTextField(features=['h2', 'h3', 'bold', 'italic', 'link'])`` would allow headings, bold / italic formatting and links, but not (for example) bullet lists or images. The ``register_rich_text_features`` hook allows new feature identifiers to be defined - see :ref:`rich_text_features` for details.
.. _construct_whitelister_element_rules:
``construct_whitelister_element_rules``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Deprecated.** This hook will be removed in Wagtail 2.2; please use :ref:`rich text features <rich_text_features>` to define whitelist rules instead.
Customise the rules that define which HTML elements are allowed in rich text areas. By default only a limited set of HTML elements and attributes are whitelisted - all others are stripped out. The callables passed into this hook must return a dict, which maps element names to handler functions that will perform some kind of manipulation of the element. These handler functions receive the element as a `BeautifulSoup <http://www.crummy.com/software/BeautifulSoup/bs4/doc/>`_ Tag object.
The ``wagtail.core.whitelist`` module provides a few helper functions to assist in defining these handlers: ``allow_without_attributes``, a handler which preserves the element but strips out all of its attributes, and ``attribute_rule`` which accepts a dict specifying how to handle each attribute, and returns a handler function. This dict will map attribute names to either True (indicating that the attribute should be kept), False (indicating that it should be dropped), or a callable (which takes the initial attribute value and returns either a final value for the attribute, or None to drop the attribute).

View File

@ -167,6 +167,42 @@ This repository has been created to provide a place for the community to collabo
legacy versions of the API until everyone has migrated to an officially supported version.
``construct_whitelister_element_rules`` hook is deprecated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``construct_whitelister_element_rules`` hook, used to specify additional HTML elements to be permitted in rich text, is deprecated. The recommended way of whitelisting elements is now to use rich text features - see :ref:`whitelisting_rich_text_elements`. For example, a whitelist rule that was previously defined as:
.. code-block:: python
from wagtail.core import hooks
from wagtail.core.whitelist import allow_without_attributes
@hooks.register('construct_whitelister_element_rules')
def whitelist_blockquote():
return {
'blockquote': allow_without_attributes,
}
can be rewritten as:
.. code-block:: python
from wagtail.admin.rich_text.converters.editor_html import WhitelistRule
from wagtail.core import hooks
from wagtail.core.whitelist import allow_without_attributes
@hooks.register('register_rich_text_features')
def blockquote_feature(features):
# register a feature 'blockquote' which whitelists the <blockquote> element
features.register_converter_rule('editorhtml', 'blockquote', [
WhitelistRule('blockquote', allow_without_attributes),
])
# add 'blockquote' to the default feature set
features.default_features.append('blockquote')
``wagtail.images.views.serve.generate_signature`` now returns a string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~