diff --git a/wagtail/core/rich_text/__init__.py b/wagtail/core/rich_text/__init__.py
index 2066ff2d0..f44971b7d 100644
--- a/wagtail/core/rich_text/__init__.py
+++ b/wagtail/core/rich_text/__init__.py
@@ -67,7 +67,10 @@ class EntityHandler:
"""
@staticmethod
def get_model():
- return NotImplementedError
+ """
+ If supported, returns the type of model able to be handled by this handler, e.g. Page.
+ """
+ raise NotImplementedError
@classmethod
def get_instance(cls, attrs: dict) -> Model:
diff --git a/wagtail/core/rich_text/feature_registry.py b/wagtail/core/rich_text/feature_registry.py
index 9bef84be0..2319ceff8 100644
--- a/wagtail/core/rich_text/feature_registry.py
+++ b/wagtail/core/rich_text/feature_registry.py
@@ -1,4 +1,7 @@
+from warnings import warn
+
from wagtail.core import hooks
+from wagtail.utils.deprecation import RemovedInWagtail27Warning
class FeatureRegistry:
@@ -68,16 +71,40 @@ class FeatureRegistry:
except KeyError:
return None
- def register_link_type(self, handler):
- self.link_types[handler.identifier] = handler
+ def register_link_type(self, identifier_or_handler_obj, handler_fn=None):
+ if handler_fn is not None:
+ # invoked as register_link_type(identifier, handler_function) - deprecated
+ identifier = identifier_or_handler_obj
+ warn(
+ 'FeatureRegistry.register_link_type(link_type, handler_function) is deprecated. '
+ 'Use FeatureRegistry.register_link_type(handler_object) instead',
+ category=RemovedInWagtail27Warning
+ )
+ self.link_types[identifier] = self.function_as_entity_handler(identifier, handler_fn)
+ else:
+ # invoked as register_link_type(handler_object)
+ handler = identifier_or_handler_obj
+ self.link_types[handler.identifier] = handler
def get_link_types(self):
if not self.has_scanned_for_features:
self._scan_for_features()
return self.link_types
- def register_embed_type(self, handler):
- self.embed_types[handler.identifier] = handler
+ def register_embed_type(self, identifier_or_handler_obj, handler_fn=None):
+ if handler_fn is not None:
+ # invoked as register_embed_type(identifier, handler_function) - deprecated
+ identifier = identifier_or_handler_obj
+ warn(
+ 'FeatureRegistry.register_embed_type(link_type, handler_function) is deprecated. '
+ 'Use FeatureRegistry.register_embed_type(handler_object) instead',
+ category=RemovedInWagtail27Warning
+ )
+ self.embed_types[identifier] = self.function_as_entity_handler(identifier, handler_fn)
+ else:
+ # invoked as register_embed_type(handler_object)
+ handler = identifier_or_handler_obj
+ self.embed_types[handler.identifier] = handler
def get_embed_types(self):
if not self.has_scanned_for_features:
@@ -96,3 +123,11 @@ class FeatureRegistry:
return self.converter_rules_by_converter[converter_name][feature_name]
except KeyError:
return None
+
+ @staticmethod
+ def function_as_entity_handler(identifier, fn):
+ """Supports legacy registering of entity handlers as functions."""
+ return type('EntityHandlerRegisteredAsFunction', (object,), {
+ 'identifier': identifier,
+ 'expand_db_attributes': staticmethod(fn),
+ })
diff --git a/wagtail/core/tests/test_rich_text.py b/wagtail/core/tests/test_rich_text.py
index 95b1547d8..2d62e2677 100644
--- a/wagtail/core/tests/test_rich_text.py
+++ b/wagtail/core/tests/test_rich_text.py
@@ -1,5 +1,6 @@
from unittest.mock import patch
+from django.contrib.auth import get_user_model
from django.test import TestCase
from wagtail.core.rich_text import RichText, expand_db_html
@@ -95,6 +96,36 @@ class TestFeatureRegistry(TestCase):
features.get_editor_plugin('hallo', 'made_up_feature')
)
+ def test_legacy_register_link_type(self):
+ User = get_user_model()
+ User.objects.create(username='wagtail', email='hello@wagtail.io')
+
+ def user_expand_db_attributes(attrs):
+ user = User.objects.get(username=attrs['username'])
+ return '' % user.email
+
+ features = FeatureRegistry()
+ features.register_link_type('user', user_expand_db_attributes)
+
+ handler = features.get_link_types()['user']
+ self.assertEqual(
+ handler.expand_db_attributes({'username': 'wagtail'}),
+ ''
+ )
+
+ def test_legacy_register_embed_type(self):
+ def embed_expand_db_attributes(attrs):
+ return 'embedded content: %s
' % attrs['content']
+
+ features = FeatureRegistry()
+ features.register_embed_type('mock_embed', embed_expand_db_attributes)
+
+ handler = features.get_embed_types()['mock_embed']
+ self.assertEqual(
+ handler.expand_db_attributes({'content': 'foo'}),
+ 'embedded content: foo
'
+ )
+
class TestLinkRewriterTagReplacing(TestCase):
def test_should_follow_default_behaviour(self):