Announcing the New Profanity Filter Plugin 'Curses!' for Craft CMS

Announcing the New Profanity Filter Plugin 'Curses!' for Craft CMS

Valerie Gaudette
Valerie Gaudette
December 12, 2025
Last updated : February 21, 2026
December 12, 2025

Good Work, the same team behind the Pwny password-breach plugin, just released Curses! A dedicated profanity-filtering plugin for Craft CMS. Version 1.0.0 dropped on December 3, 2025, and it's the first store-listed plugin in the Craft ecosystem built specifically for detecting and masking offensive language in user-generated content.

For teams managing community features, comment sections, or any site where users can submit text, this fills a gap that's existed in Craft's plugin library for years.

Why This Matters for the Craft Ecosystem

Craft CMS has always had solid options for spam prevention. Honeypot by Foster Commerce catches bots through hidden fields and timing checks. CleanTalk's Anti-Spam plugin connects to their external service for automated filtering. But neither of these tools addresses what happens when real humans submit content you'd rather not display on your site.

Before Curses!, handling profanity in Craft meant one of three approaches: building custom validation logic, integrating third-party moderation APIs, or just hoping your audience behaves. Each approach has drawbacks (custom code requires maintenance, external APIs add costs and dependencies, and hoping rarely works out).

Curses! sits in a different category entirely. Rather than blocking spam or protecting against security vulnerabilities, it works at the text content level, giving developers a native way to filter language without leaving the Craft ecosystem.

What Curses! Actually Does

The initial release keeps things focused. Based on the official changelog, version 1.0.0 includes:

Profanity Detection Engine

The plugin identifies offensive language in strings. The specific detection method, whether it uses simple wordlists, regex patterns, or something more sophisticated, isn't detailed in the public documentation yet.

Twig Filters for Template Integration

This is where Curses! shines for Craft developers. Instead of requiring PHP-level customization or control panel configuration, the plugin provides Twig filters you can apply directly in your templates.

The changelog mentions "content masking and detection," which suggests filter patterns like:

{# Mask profanity with asterisks or similar characters #}
{{ comment|curses_mask }}

{# Check if content contains profanity #}
{% if comment|curses_has_profanity %}
    {# Handle flagged content #}
{% endif %}

The exact filter names may differ, but the pattern follows standard Craft plugin conventions for Twig APIs.

Craft 4 and 5 Compatibility

The plugin supports both major versions at launch. This matters because many production sites still run Craft 4, while new projects typically target Craft 5. Supporting both means teams don't have to delay adoption while waiting for version-specific builds.

What's Not Confirmed Yet

Since this is a fresh release, some details remain unclear from public sources:

  • Custom wordlist configuration: Can you add or remove words from the detection list? Is this done through the control panel or config files?
  • Multi-language support: Does the plugin ship with dictionaries beyond English?
  • Logging or analytics: Is there a dashboard showing filtered content or detection patterns?
  • Form validation integration: Can you use the detection engine during form submission to reject content before saving?

These features are plausible additions for future versions, but they're not documented in the 1.0.0 release notes.

How This Affects Craft Development Projects

We've found that profanity filtering comes up more often than you might expect, especially for sites with community features, user reviews, or public-facing comment systems. The typical request sounds simple: "we don't want swear words on the site", but the implementation has historically been messier than it should be.

With Curses!, the typical workflow looks more straightforward:

For Display-Time Masking

Apply the masking filter when rendering user-generated fields. The original content stays intact in your database, but what visitors see gets cleaned up:

    {{ entry.userComment|curses_mask }}

This approach preserves the original submission for moderation review while keeping your public-facing pages clean.

For Moderation Workflows

Use detection filters to flag content that needs human review:

{% if entry.userComment|curses_has_profanity %}
    ⚠️ Review needed
{% endif %}

Pair this with Craft's native permissions system to build a lightweight moderation queue without additional plugins.

For Submission-Time Validation

While not explicitly documented, developers can intercept form data in module code, run detection checks, and return validation errors before content gets saved. This requires more setup than template-level filtering but gives tighter control over what enters your database.

How Curses! Compares to Other Options

To understand where Curses! fits, here's how it stacks up against existing Craft tools:

Honeypot (Foster Commerce): Focuses on bot detection through honeypot fields and submission timing. Good for stopping automated spam, but doesn't analyze content from real users.

Anti-Spam by CleanTalk: Connects to CleanTalk's external service using an access key. Effective spam filtering, but requires an external account and doesn't specifically target profanity.

Pwny (Good Work): Also by Good Work, checks passwords against the Have I Been Pwned database. Different purpose entirely, security rather than content filtering, but shows the developer's experience building privacy-conscious plugins with external data sources.

Custom Code: Always an option, but requires ongoing maintenance as dictionaries evolve and edge cases emerge.

Curses! differentiates itself by operating at the text content level through Twig filters, making it flexible enough to apply across different element types, form plugins, and display contexts without significant custom development.

Professional Perspective on Implementation

Our approach involves evaluating plugins like Curses! based on how well they fit existing project architecture. A few considerations stand out for this release:

Template-Level Integration Is Genuinely Useful

By exposing functionality through Twig filters rather than requiring control panel configuration or PHP customization, Curses! lets front-end developers handle filtering without backend changes. This matches how many Craft projects are structured, with template developers handling display logic independently.

Storage vs. Display Trade-offs Matter

The masking approach, storing original content but displaying filtered versions, makes sense for most use cases. You keep evidence of what was submitted while showing cleaned content publicly. Teams that need stricter policies might want to prevent storage entirely, which would require custom validation rather than template filtering.

Version 1.0.0 Expectations

First releases typically cover core functionality. The lack of detailed configuration options in the documentation suggests Curses! is starting simple and will expand based on community feedback. This is a reasonable approach, but teams with specific requirements (custom dictionaries, multi-language support) should verify capabilities before committing.

Next Steps for Craft Teams

We typically suggest the following approach for evaluating new plugins:

For Sites Already Handling User-Generated Content

If you have an existing Craft site with comments, reviews, or community features, test Curses! in a staging environment first. Apply the masking filter to a few representative content types and verify it catches what you expect without false positives on legitimate content.

For New Projects Planning Community Features

Include Curses! in your initial plugin stack and build filtering into your templates from the start. It's easier to establish content standards early than to retrofit filtering after users have already submitted content.

For Sites Without User Input

If your Craft site doesn't accept user-generated content, Curses! probably isn't relevant to your project. Focus on security fundamentals and spam prevention instead.

For Teams Needing Advanced Moderation

Curses! handles detection and masking, not complete moderation workflows. If you need approval queues, automated escalation, or integration with external moderation services, plan for custom development alongside the plugin.

Keep an eye on Good Work's updates. They have a track record of maintaining their Craft plugins (Pwny has received consistent updates since launch), so expanded features and documentation will likely follow as the plugin matures.

Wrapping Up

Curses! addresses a specific need in the Craft ecosystem: native, template-level profanity filtering without external dependencies or extensive custom code. For sites managing user-generated content, it offers a cleaner path than the existing alternatives.

The 1.0.0 release covers the essentials (detection, masking, and Twig integration) while leaving room for the configuration and multi-language features that broader adoption would require. Good Work's track record with Craft plugins suggests those additions will come as the community provides feedback.

Content moderation decisions involve more than just technical implementation. You're also making choices about community standards, user experience, and brand presentation. If you're building community features in Craft CMS and want to talk through how filtering fits into your broader content approach, we can help you evaluate the right balance for your specific audience and goals.

Share this article