Skip to content

Commit 4df0d23

Browse files
authored
Node class extension (#52)
1 parent 649a5f4 commit 4df0d23

17 files changed

Lines changed: 759 additions & 25 deletions

File tree

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Change log
44
Next version
55
~~~~~~~~~~~~
66

7+
- Added a ``NodeClass`` extension for applying CSS classes to nodes.
8+
79

810
0.17 (2025-08-25)
911
~~~~~~~~~~~~~~~~~

django_prose_editor/config.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,43 @@ def process_color_highlight(config, shared_config):
152152
add_tags_and_attributes(shared_config, tags, attributes)
153153

154154

155+
def process_node_class(config, shared_config):
156+
"""Process NodeClass extension configuration."""
157+
if not isinstance(config, dict) or "cssClasses" not in config:
158+
return
159+
160+
css_classes = config["cssClasses"]
161+
if not isinstance(css_classes, dict):
162+
return
163+
164+
# Map of node types to their HTML tags that need class attributes
165+
node_type_tags = {
166+
"paragraph": ["p"],
167+
"heading": ["h1", "h2", "h3", "h4", "h5", "h6"],
168+
"table": ["table"],
169+
"tableRow": ["tr"],
170+
"tableCell": ["td", "th"],
171+
"tableHeader": ["th"],
172+
"listItem": ["li"],
173+
"bulletList": ["ul"],
174+
"orderedList": ["ol"],
175+
"blockquote": ["blockquote"],
176+
"codeBlock": ["pre"],
177+
}
178+
179+
# Collect all tags that need class attributes
180+
tags_needing_class = set()
181+
182+
for node_type, classes in css_classes.items():
183+
if node_type in node_type_tags and classes:
184+
tags_needing_class.update(node_type_tags[node_type])
185+
186+
# Add class attribute to all relevant tags
187+
if tags_needing_class:
188+
attributes = {tag: ["class"] for tag in tags_needing_class}
189+
add_tags_and_attributes(shared_config, [], attributes)
190+
191+
155192
# Default extension mapping with processors as the single source of truth
156193
EXTENSION_MAPPING = {
157194
# Core formatting
@@ -204,6 +241,7 @@ def process_color_highlight(config, shared_config):
204241
"Gapcursor": html_tags([]),
205242
"Menu": html_tags([]),
206243
"NoSpellCheck": html_tags([]),
244+
"NodeClass": process_node_class,
207245
"TextClass": html_tags(["span"], {"span": ["class"]}),
208246
"Placeholder": html_tags([]),
209247
}

django_prose_editor/static/django_prose_editor/editor.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

django_prose_editor/static/django_prose_editor/editor.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

django_prose_editor/static/django_prose_editor/editor.js

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

django_prose_editor/static/django_prose_editor/editor.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/custom_extensions.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Custom Extensions and Menu Integration
2-
===============================
2+
======================================
33

44
Creating custom extensions for django-prose-editor allows you to extend the editor with new functionality and integrate it with the menu system. This guide explains how to create custom extensions and add menu items for them.
55

66
Basic Extension Structure
7-
------------------------
7+
-------------------------
88

99
Extensions in django-prose-editor are based on Tiptap extensions. To create a custom extension:
1010

@@ -77,7 +77,7 @@ Extensions can integrate with the menu system by implementing the ``addMenuItems
7777
The Menu extension uses an ``items`` creator function instead of the old ``addItems`` function. This provides more flexibility for custom menu layouts. See :doc:`menu` for details on creating custom menu structures.
7878
7979
Menu Item Structure
80-
~~~~~~~~~~~~~~~~~~
80+
~~~~~~~~~~~~~~~~~~~
8181
8282
Menu items are defined using the ``defineItem`` method with the following properties:
8383
@@ -308,7 +308,7 @@ The base case of a hardcoded list of tags and attributes is handled by the
308308
]
309309
310310
Best Practices
311-
-------------
311+
--------------
312312
313313
1. **Group Related Items**: Use the menu group system to organize related items together
314314
2. **Conditional Display**: Use the ``hidden``, ``enabled``, and ``active`` methods to control when and how menu items appear

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ django-prose-editor[sanitize]``) the following should get you started:
3131
sanitization
3232
custom_extensions
3333
menu
34+
nodeclass
3435
textclass
3536
presets
3637
legacy

0 commit comments

Comments
 (0)