17 Dec 2025

feedDjango community aggregator: Community blog posts

Rich text editors: How restrictive can we be?

Rich text editors: How restrictive can we be?

How restrictive should a rich text editor be? It's a question I keep coming back to as I work on FeinCMS and Django-based content management systems.

I published the last blog post on django-prose-editor specifically in August 2025, Menu improvements in django-prose-editor. The most interesting part of the blog post was the short mention of the TextClass extension at the bottom which allows adding a predefined list of CSS classes to arbitrary spans of text.

In the meantime, I have spent a lot of time working on extensions that try to answer this question: the TextClass extension for adding CSS classes to inline text, and more recently the NodeClass extension for adding classes to nodes and marks. It's high time to write a post about it.

Rich Text editing philosophy

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 shoot their own foot).

- Commit in the FeinCMS repository, August 2009, current version from django-content-editor design decisions

Should we let users shoot themselves in the foot?

Giving power users an HTML code button would have been somewhat fine if only the editors themselves were affected. Unfortunately, that was not the case.

As a team we have spent more time than we ever wanted debugging strange problems only to find out that the culprit was a blob of CSS or JavaScript inserted directly into an unsanitized rich text editor field. We saw everything from a few reasonable and well scoped lines of CSS to hundreds of KiBs of hotlinked JavaScript code that broke layouts, caused performance issues, and possibly even created security vulnerabilities.

We have one more case of Betteridge's law of headlines here.

The pendulum swings

The first version of django-prose-editor which replaced the venerable CKEditor 4 in our project was much more strict and reduced - no attributes, no classes, just a very short list of allowlisted HTML tags in the schema.

We quickly hit some snags. When users needed similar headings with different styles, we worked around it by using H2 and H3 - not semantic at all. I wasn't exactly involved in this decision; I just didn't want to rock the boat too much, since I was so happy that we were even able to use the more restricted editor at all in this project.

Everything was good for a while, but more and more use cases crept up until it was clear that something had to be done about it. First, the TextClass extension was introduced to allow adding classes to inline text, and later also the NodeClass extension mentioned above. This was a compromise: The customer wanted inline styles, we wanted as little customizability as possible without getting in the way.

That said, we obviously had to move a bit. After all, going back to a less strict editor or even offering a HTML blob injection would be worse. If we try to be too restrictive we will probably have to go back to allowing everything some way or the other, after all:

The more you tighten your grip, Tarkin, the more star systems will slip through your fingers.

- Princess Leia

Combining CSS classes

The last words are definitely not spoken just yet. As teased on Mastodon at the beginning of this month I am working on an even more flexible extension which unifies the NodeClass and TextClass extensions into a single ClassLoom extension.

The code is getting real world use now, but I'm not ready to integrate it yet into the official repository. However, you can use it if you want, it's 1:1 the version from a project repository. Get the ClassLoom extension here.

This extension also allows combining classes on a single element. If you have 5 colors and 3 text styles, you'd have to add 15 combinations if you were only able to apply a single class. Allowing combinations brings the number of classes down to manageable levels.

Conclusion

So, back to the original question: How restrictive can we be?

The journey from CKEditor 4's permissiveness through django-prose-editor's initial strictness to today's ClassLoom extension has been one of finding that balance. Each extension - TextClass, NodeClass, and now ClassLoom - represents a step toward controlled flexibility: giving content editors the styling options they need while keeping the content structured, maintainable, and safe.

17 Dec 2025 6:00pm GMT

12 Dec 2025

feedDjango community aggregator: Community blog posts

Django News - DjangoCon Europe 2026 CFPs - Dec 12th 2025

News

DjangoCon Europe 2026: Call for Proposals

Submit talk proposals for DjangoCon Europe 2026 in Athens by February 8, 2026, to present technical or community-focused Django and Python topics.

djangocon.eu

Python Insider: Python 3.14.2 and 3.13.11 are now available!

Python 3.14.2 and 3.13.11 release expedited maintenance updates fixing regressions in multiprocessing, dataclasses, regex and insertdict plus security fixes including CVE-2025-12084.

blogspot.com

Django Software Foundation

Django Code of Conduct Transparency Report 2025

The Django Software Foundation Code of Conduct working group published a 2025 transparency report detailing four reports, two suspensions, process changes, and new liaisons.

djangoproject.com

Online Community Working Group GitHub repo and project

Django Online Community Working Group launched a GitHub repository and project to centralise, track, and triage suggestions across Django's online platforms.

djangoproject.com

Django Fellow Reports

Fellow Report - Natalia

Big week. I issued security releases early in the week, and then the Django 6.0 final release right after. Getting both out the door smoothly took most of my focus, and it felt good to see them completed.

The flow of LLM driven contributions is becoming hard to ignore, across PRs, tickets, and even security reports. Skynet would be proud (?). This week was also heavy on meetings and coordinations.

djangoproject.com

Fellow Report - Jacob

An exciting week with Django 6.0 released and several security issues put to bed. Another highlight was merging Rim Choi's work making custom user models work better with fixture serialization.

djangoproject.com

Wagtail CMS News

Wagtail Wrapped 2025

Wagtail released four updates in 2025, including a 7.0 LTS aligned with Django, improved editor UX, AI package features, and autosave roadmap for 2026.

wagtail.org

Up next on the roadmap

Wagtail 7.3 (Feb 2026) will add a StreamField block settings, content AI checks, model search enhancements, autosave draft, llms.txt docs to improve editor and developer workflows, and more!

wagtail.org

Sponsored Link 1

Sleep tight with HackSoft and our Django services!

While you recharge, we keep your software running smoothly - secure, stable, and ready for tomorrow. We are HackSoft - your Django development partner, beyond code. Learn more!

hacksoft.io

Articles

Introducing Django RAPID Architecture: Patterns for Real‑World Django Codebases

A post on the new online and free Django RAPID Architecture guide.

dabapps.com

Build a RAG App With Django MongoDB Backend in 30 minutes

A fast, step-by-step guide to building a holiday-movie RAG search app in 30 minutes using Django, MongoDB, Voyage AI embeddings, and LangChain.

dev.to

Deprecations via warnings don't work for Python libraries

DeprecationWarning is ignored by default, so Python libraries cannot rely on it for API breakage notices and should use visible warnings or stricter versioning.

sethmlarson.dev

Django: implement HTTP basic authentication

Implement HTTP Basic authentication in Django by decoding Basic Authorization headers, securely validating credentials with secrets.compare_digest, and returning 401 with WWW authenticate header.

adamj.eu

The Autobiography of a Python Object

Explains Python object lifecycle, special methods like __repr__ and __iter__, attribute handling, and reference counting leading to garbage collection, with illustrative examples.

thepythoncodingstack.com

Events

PyCon US 2026 - Registration, Hotels, Travel Grants & More!

PyCon US 2026 registration is open for May 13, 2026 to May 19, 2026 in Long Beach, offering early bird rates, housing and travel grants.

blogspot.com

Tutorials

How to send email with Django: Complete SMTP guide

Guide explains configuring Django's SMTP backend, using send_mail, EmailMessage, and send_mass_mail for plain, HTML, attachment, and bulk email sending while securing credentials via environment variables.

dev.to

Podcasts

Django 6.0 - Natalia Bidart

Natalia is a Django Fellow and the release manager for the just-released 6.0 version. We talk about the new release, major features including template partials that Carlton helped usher in, queues, CSP support, modern email API, and the current work on Django 6.1.

djangochat.com

Django Job Board

Django News Jobs is now the Django Job Board and has a new domain: https://djangojobboard.com

New Django and Python roles this week span application security, backend development, and staff-level engineering.

Python/Django Senior Application Security Engineer at Energy Solutions

Python / Django Developer at Client of Foxley Talent

Staff Software Engineer at Bluebird Kids Health

Django Newsletter

Projects

FarhanAliRaza/django-repl

Run Django in the browser.

github.com

codingjoe/django-crontask: Cron style scheduler for Django's task framework

Cron style scheduler for Django's task framework. Contribute to codingjoe/django-crontask development by creating an account on GitHub.

github.com


This RSS feed is published on https://django-news.com/. You can also subscribe via email.

12 Dec 2025 5:00pm GMT

11 Dec 2025

feedDjango community aggregator: Community blog posts

Django 6.0 - Natalia Bidart

Sponsor

This episode was brought to you by HackSoft, your development partner beyond code. From custom software development to consulting, team augmentation, or opening an office in Bulgaria, they're ready to take your Django project to the next level!

11 Dec 2025 11:05pm GMT