Contentful Rich Text Renderer
The Contentful Rich Text Renderer is a Python library designed to serialize the RichText field type from Contentful into its corresponding HTML representation by default. It provides flexible rendering capabilities, allowing for full customization of node and mark rendering. It is commonly used alongside the Contentful Delivery SDK. The current version is 0.2.8, and releases are typically tied to updates in the Contentful ecosystem as needed.
Common errors
-
KeyError: 'embedded-entry-block'
cause Attempting to render a Rich Text document that contains an embedded entry block without providing a custom renderer for `BLOCKS.EMBEDDED_ENTRY`.fixDefine and register a custom renderer for `BLOCKS.EMBEDDED_ENTRY` within the `RichTextRenderer` constructor to handle how embedded entries should be displayed. -
rich_text_renderer.base_renderer.InvalidNodeException: Unknown node type: 'unknown-custom-block'
cause The Rich Text document contains a node type that the `RichTextRenderer` does not have a default or custom mapping for.fixProvide a custom renderer for the specific unknown node type, or register a fallback renderer for `None` to gracefully handle all unmapped node types. -
TypeError: render() missing 1 required positional argument: 'document'
cause Attempting to call the `render` method of `RichTextRenderer` without passing the Rich Text JSON `document` as an argument.fixEnsure the Rich Text JSON object is passed as the `document` argument to the `renderer.render()` method.
Warnings
- gotcha By default, the library only renders a generic `<div>str(entry)</div>` for embedded entries (`embedded-entry-block`). This is usually not sufficient for meaningful content.
- gotcha The renderer will raise an exception if it encounters an unknown node type in the Rich Text document (e.g., if your Contentful model defines a custom block that the renderer doesn't have a mapping for).
- gotcha The Contentful Rich Text field returns content as a JSON object, not raw HTML. Directly attempting to process this JSON as a simple string or using a generic HTML parser will fail.
Install
-
pip install rich-text-renderer
Imports
- RichTextRenderer
from rich_text_renderer import RichTextRenderer
- BLOCKS
from rich_text_renderer.base_renderer import BLOCKS
- MARKS
from rich_text_renderer.base_renderer import MARKS
- BaseNodeRenderer
from rich_text_renderer.base_node_renderer import BaseNodeRenderer
Quickstart
from rich_text_renderer import RichTextRenderer
# Example Rich Text document (typically obtained from Contentful API)
document = {
'nodeType': 'document',
'data': {},
'content': [
{
'nodeType': 'paragraph',
'data': {},
'content': [
{'nodeType': 'text', 'value': 'Hello, ', 'marks': []},
{'nodeType': 'text', 'value': 'Contentful Rich Text!', 'marks': [{'type': 'bold'}]}
]
}
]
}
renderer = RichTextRenderer()
html_output = renderer.render(document)
print(html_output)
# Example with a custom renderer for a specific block type (e.g., 'embedded-entry-block')
from rich_text_renderer.base_node_renderer import BaseNodeRenderer
from rich_text_renderer.base_renderer import BLOCKS
class MyEntryBlockRenderer(BaseNodeRenderer):
def render(self, node):
entry_id = node['data']['target']['sys']['id']
# In a real application, you would fetch entry data using the Contentful SDK
# For this example, we'll just return a placeholder HTML string.
return f'<div class="embedded-entry" data-entry-id="{entry_id}">Custom Embedded Entry: {entry_id}</div>'
custom_renderer = RichTextRenderer({
BLOCKS.EMBEDDED_ENTRY: MyEntryBlockRenderer()
})
document_with_entry = {
'nodeType': 'document',
'data': {},
'content': [
{
'nodeType': 'paragraph',
'data': {},
'content': [
{'nodeType': 'text', 'value': 'Here is an ', 'marks': []},
{'nodeType': 'text', 'value': 'embedded entry:', 'marks': [{'type': 'italic'}]}
]
},
{
'nodeType': 'embedded-entry-block',
'data': {
'target': {
'sys': {'id': 'my-custom-entry', 'type': 'Link', 'linkType': 'Entry'}
}
},
'content': []
}
]
}
html_output_custom = custom_renderer.render(document_with_entry)
print('\n--- With Custom Renderer ---')
print(html_output_custom)