PHPackages                             gokepelemo/wpgraphql-content-filter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. gokepelemo/wpgraphql-content-filter

ActiveWordpress-plugin

gokepelemo/wpgraphql-content-filter
===================================

WordPress plugin that filters and sanitizes content in WPGraphQL and REST API responses with configurable HTML stripping, Markdown conversion, and custom tag allowlists.

50PHP

Since Sep 26Pushed 7mo agoCompare

[ Source](https://github.com/gokepelemo/wpgraphql-content-filter)[ Packagist](https://packagist.org/packages/gokepelemo/wpgraphql-content-filter)[ RSS](/packages/gokepelemo-wpgraphql-content-filter/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)DependenciesVersions (1)Used By (0)

WPGraphQL Content Filter Plugin
===============================

[](#wpgraphql-content-filter-plugin)

A WordPress plugin that cleans and filters HTML content in both WPGraphQL and REST API responses according to customizable settings. The plugin features a modern, responsive admin interface with intelligent conditional UI that adapts based on your filtering preferences. It includes comprehensive WordPress multisite support, allowing network administrators to set default filtering rules with complete settings parity and enforcement controls that individual site administrators can customize for their specific needs.

This plugin is particularly valuable in two scenarios: when migrating from a traditional themed WordPress site to a headless architecture, and when a themed WordPress site needs to serve clean content to external applications via API. In both cases, existing content may contain unwanted HTML markup that needs to be filtered or sanitized before being consumed by other systems.

**Version 2.1.25** features a completely refactored modular architecture with professional-grade HTML processing libraries. Integrated `league/html-to-markdown` for robust HTML-to-Markdown conversion and `ezyang/htmlpurifier` for comprehensive HTML sanitization with XSS protection. The plugin now handles all HTML tag attributes completely, including id, classes, data-\* attributes, and other complex attributes. Recent versions include enhanced multisite network administration with improved error handling and yoast\_head field filtering support.

The plugin was developed using Claude 4 Sonnet.

Features
--------

[](#features)

- **Multiple Filter Modes:**

    - None (no filtering)
    - Strip All HTML (using HTMLPurifier for comprehensive sanitization)
    - Convert to Markdown (using league/html-to-markdown for professional conversion)
    - Custom Allowed Tags (with HTMLPurifier-based filtering)
- **Intelligent Conditional UI:**

    - Markdown options dynamically shown/hidden based on selected filter mode
    - Clean, responsive admin interface with professional styling
    - Real-time form field visibility updates
- **Configurable Options:**

    - Apply filtering to content and/or excerpt fields
    - Preserve line breaks when stripping HTML
    - Selective Markdown conversion (headings, links, lists, emphasis)
    - Custom allowed HTML tags
- **Advanced Multisite Support:**

    - Complete network-level administration with enforcement controls
    - All site-level settings available at network level
    - Bulk settings synchronization across all sites
    - Override protection and inheritance system
- **API Integration:**

    - Automatically works with all post types registered with WPGraphQL
    - Works with WordPress REST API for all public post types
    - Filters the main `content` field in place
    - Filters the `excerpt` field (optional)
    - Filters the `yoast_head` field (removes HTML comments and applies content filtering)
    - Supports custom post types out of the box
- **Performance Optimizations:**

    - Built-in caching system for improved performance
    - Memory usage optimization and batch processing
    - Professional-grade libraries with optimized HTML parsing
    - Graceful fallbacks to regex-based methods when libraries unavailable
    - Enhanced security through HTMLPurifier's XSS protection

Installation
------------

[](#installation)

### Recommended: GitHub Release (Easiest)

[](#recommended-github-release-easiest)

1. Download the latest release from [GitHub Releases](https://github.com/gokepelemo/wpgraphql-content-filter/releases)
2. Upload the plugin ZIP file through WordPress admin (**Plugins &gt; Add New &gt; Upload Plugin**)
3. Activate the plugin through the 'Plugins' menu
4. Go to **Settings &gt; GraphQL Content Filter** to configure your filtering options

### Composer Installation

[](#composer-installation)

If you manage WordPress plugins with Composer, you can install the plugin directly from Packagist:

```
composer require gokepelemo/wpgraphql-content-filter
```

Then activate the plugin through the WordPress admin and configure as above.

### Manual Installation

[](#manual-installation)

1. Download the complete plugin package from [GitHub Releases](https://github.com/gokepelemo/wpgraphql-content-filter/releases)
2. Extract the ZIP file and upload the entire `wpgraphql-content-filter` folder to your `/wp-content/plugins/` directory
3. Activate the plugin through the 'Plugins' menu in WordPress
4. Go to **Settings &gt; GraphQL Content Filter** to configure your filtering options

**Important:** The plugin uses a modular architecture and requires all files to be present:

- Main plugin file: `wpgraphql-content-filter.php`
- Core classes in `includes/` directory:
    - `WPGraphQL_Content_Filter` (main orchestrator)
    - `WPGraphQL_Content_Filter_Admin` (admin interface)
    - `WPGraphQL_Content_Filter_Content_Filter` (filtering engine)
    - `WPGraphQL_Content_Filter_Options_Manager` (settings management)
    - `WPGraphQL_Content_Filter_REST_Hook_Manager` (REST API integration)
    - `WPGraphQL_Content_Filter_GraphQL_Hook_Manager` (WPGraphQL integration)
- Language files in `languages/` directory
- Test files in `tests/` directory (optional for production)

### Development Installation

[](#development-installation)

For developers who want to contribute or modify the plugin:

1. Clone the repository:

    ```
    git clone https://github.com/gokepelemo/wpgraphql-content-filter.git
    ```
2. Install dependencies:

    ```
    composer install
    ```
3. Copy to your WordPress plugins directory
4. Activate and configure as above

Requirements
------------

[](#requirements)

- WordPress 5.0+
- PHP 7.4+
- **WPGraphQL plugin** (required for GraphQL filtering functionality)
- Custom post types must be registered with WPGraphQL to be filtered in GraphQL (REST API works with all public post types)

**Dependencies:** The plugin includes all required Composer dependencies (`league/html-to-markdown` and `ezyang/htmlpurifier`) in the release packages, so no manual installation is required.

**Note:** While the plugin can function without WPGraphQL for REST API filtering only, it is designed primarily for WPGraphQL integration and will display notices if WPGraphQL is not installed.

**Multisite Support:** Full network administration capabilities are available for WordPress multisite installations, with enhanced error handling and debug logging in recent versions.

Usage
-----

[](#usage)

### Admin Configuration

[](#admin-configuration)

Navigate to **Settings &gt; GraphQL Content Filter** in your WordPress admin to configure:

1. **Filter Mode**: Choose how to process content
    - When "Convert to Markdown" is selected, additional Markdown-specific options will appear
    - Other modes hide Markdown options for a cleaner interface
2. **Apply to Fields**: Select which fields to filter (content, excerpt)
3. **Markdown Options**: Configure Markdown conversion (automatically shown/hidden based on filter mode)
    - Preserve Line Breaks
    - Convert Headings to Markdown
    - Convert Links to Markdown
    - Convert Lists to Markdown
    - Convert Emphasis to Markdown
4. **Custom Tags**: Define allowed HTML tags (for custom mode)

#### Multisite Network Administration

[](#multisite-network-administration)

For multisite installations, network administrators can access **Network Admin &gt; Settings &gt; GraphQL Content Filter** to:

- Set network-wide default settings for all sites
- Enable enforcement to prevent individual sites from overriding settings
- Configure all the same options available at the site level
- Bulk synchronize settings across all sites in the network
- Access enhanced error handling and debug logging for troubleshooting

The network admin interface includes the same conditional UI behavior, ensuring a consistent experience across both site-level and network-level administration. Recent improvements include better error handling, comprehensive debug logging, and optimized form processing to prevent blank page issues.

### Performance Settings

[](#performance-settings)

The plugin includes several performance optimization features:

#### Cache Settings

[](#cache-settings)

- **Enable Cache**: Enables content filtering cache for improved performance by storing processed results
- **Cache TTL (seconds)**: Controls how long cached results are kept (default: 3600 seconds / 1 hour)

#### Batch Processing

[](#batch-processing)

- **Batch Processing Size**: Controls how many items are processed together in bulk operations
    - **Default**: 100 items per batch
    - **Range**: 10-1000 items per batch
    - **Purpose**: Prevents memory exhaustion and timeouts during large-scale operations
    - **Tuning**:
        - Lower values (10-50): Better for shared hosting or limited resources
        - Higher values (200-500): Suitable for dedicated servers with more processing power
        - Default (100): Good balance for most WordPress installations

This setting is particularly important for:

- Bulk content filtering operations
- Cache warming processes
- Mass content updates that trigger the content filter
- Any operation processing multiple posts/pages at once

### API Queries

[](#api-queries)

The plugin filters content in place, so your existing queries work without changes. It works with both GraphQL and REST API:

#### GraphQL (requires WPGraphQL plugin)

[](#graphql-requires-wpgraphql-plugin)

```
query GetContent {
  # Regular posts
  posts {
    nodes {
      id
      title
      content      # Filtered based on plugin settings
      excerpt      # Filtered if enabled in settings
    }
  }

  # Custom post types (example: products)
  products {
    nodes {
      id
      title
      content      # Also filtered based on plugin settings
      excerpt      # Also filtered if enabled
    }
  }
}
```

#### REST API

[](#rest-api)

```
# Get posts via REST API (content will be filtered)
GET /wp-json/wp/v2/posts

# Get custom post type via REST API (content will be filtered)
GET /wp-json/wp/v2/products

# Response structure (filtered content):
{
  "id": 123,
  "title": {"rendered": "Post Title"},
  "content": {"rendered": "Filtered content here..."},  # Filtered
  "excerpt": {"rendered": "Filtered excerpt..."},        # Filtered if enabled
  "yoast_head": "Filtered meta tags..."                  # Filtered (HTML comments removed)
}
```

Filter Modes
------------

[](#filter-modes)

### Strip All HTML

[](#strip-all-html)

Uses HTMLPurifier for comprehensive HTML sanitization and tag removal:

```
Hello world!
↓
Hello world!
```

**Features:**

- Complete HTML tag and attribute removal
- XSS protection through HTMLPurifier
- Malformed HTML handling
- Unicode content preservation

### Convert to Markdown

[](#convert-to-markdown)

Uses league/html-to-markdown for professional HTML-to-Markdown conversion:

```
TitleHello world!
↓
## Title

Hello **world**!
```

**Features:**

- Complete HTML attribute handling (id, class, data-\*, etc.)
- Robust nested structure processing
- Configurable conversion options
- Fallback to regex patterns if library unavailable

### Custom Allowed Tags

[](#custom-allowed-tags)

Uses HTMLPurifier for precise tag allowlisting with comprehensive attribute handling:

```
Settings: p,strong,em
Hello world! alert('x')
↓
Hello world! alert('x')
```

**Features:**

- Complete HTML attribute preservation for allowed tags
- XSS protection against malicious content
- Configurable attribute allowlists
- Professional-grade HTML parsing

Advanced Usage
--------------

[](#advanced-usage)

### Plugin Architecture

[](#plugin-architecture)

The plugin uses a **modular architecture** with clean separation of concerns and dependency injection (v2.1.0+):

**Core Bootstrap Class:**

- `WPGraphQL_Content_Filter` - Main plugin orchestrator that coordinates all components

**Manager Classes:**

- `WPGraphQL_Content_Filter_Options_Manager` - Handles all plugin settings, caching, and multisite support
- `WPGraphQL_Content_Filter_Content_Filter` - Universal content filtering engine with multiple modes
- `WPGraphQL_Content_Filter_GraphQL_Hook_Manager` - WPGraphQL integration and hook management
- `WPGraphQL_Content_Filter_REST_Hook_Manager` - WordPress REST API integration
- `WPGraphQL_Content_Filter_Admin` - Complete admin interface with conditional UI

**Key Benefits:**

- **Singleton Pattern**: Consistent performance across all managers
- **Dependency Injection**: Clean dependency management between components
- **Separation of Concerns**: Each class has a single, well-defined responsibility
- **Maintainability**: Modular code is easier to debug, test, and extend
- **Error Prevention**: Proper initialization sequence eliminates potential fatal errors

**Legacy Architecture (pre-v2.1.0):**Previous versions used a monolithic structure. The v2.1.0 refactor maintains complete backward compatibility while providing a foundation for future development.

### Custom Post Type Support

[](#custom-post-type-support)

The plugin automatically detects and filters content for:

**GraphQL**: All post types registered with WPGraphQL
**REST API**: All public post types (built-in WordPress functionality)

No additional configuration is needed - if your custom post type is public or registered with GraphQL, the content filtering will be applied.

**Example custom post types that work:**

- Products (WooCommerce)
- Events
- Portfolio items
- Testimonials
- Any custom post type with `public => true` (REST API) or `show_in_graphql => true` (GraphQL)

### REST API vs GraphQL

[](#rest-api-vs-graphql)

The plugin works slightly differently for each API:

- **REST API**: Filters all public post types automatically
- **GraphQL**: Only filters post types explicitly registered with WPGraphQL
- **Settings**: Same filtering options apply to both APIs
- **Fields**: Both APIs filter `content` and `excerpt` fields

### Programmatic Filtering

[](#programmatic-filtering)

You can also filter content programmatically using the new modular architecture:

```
// Get manager instances (v2.1.0+)
$options_manager = WPGraphQL_Content_Filter_Options_Manager::get_instance();
$content_filter = WPGraphQL_Content_Filter_Content_Filter::get_instance();

// Get current options
$options = $options_manager->get_options();

// Apply custom filtering directly
$filtered_content = $content_filter->filter_field_content(
    $raw_content,
    'content',
    $options
);

// Hook into GraphQL filtering
add_filter('graphql_post_object_content', function($content, $post, $context) {
    if ($post->post_type === 'custom_post_type') {
        $content_filter = WPGraphQL_Content_Filter_Content_Filter::get_instance();
        $options = WPGraphQL_Content_Filter_Options_Manager::get_instance()->get_options();
        return $content_filter->filter_field_content($content, 'content', $options);
    }
    return $content;
}, 5, 3); // Priority 5 to run before the plugin's filter
```

### Conditional Filtering

[](#conditional-filtering)

You can apply different filters based on context:

```
add_filter('wpgraphql_content_filter_options', function($options) {
    // Change filter mode based on user role or other conditions
    if (current_user_can('edit_posts')) {
        $options['filter_mode'] = 'none'; // No filtering for editors
    }
    return $options;
});
```

Hooks and Filters
-----------------

[](#hooks-and-filters)

### Filters

[](#filters)

- `wpgraphql_content_filter_options` - Modify plugin options
- `wpgraphql_content_filter_before_apply` - Modify content before filtering
- `wpgraphql_content_filter_after_apply` - Modify content after filtering

### Actions

[](#actions)

- `wpgraphql_content_filter_loaded` - Fired when plugin is loaded
- `wpgraphql_content_filter_settings_saved` - Fired when settings are saved

For detailed version history and release notes, see [CHANGELOG.md](CHANGELOG.md).

License
-------

[](#license)

This plugin is licensed under the GPL v2 or later.

```
WPGraphQL Content Filter
Copyright (C) 2025 Goke Pelemo

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

```

Support
-------

[](#support)

For issues and feature requests, please visit the plugin repository.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance44

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/6c45a93ae6c6edbedf1b8fb6e82768f53c74b288037a5af63f8a9c2a9aee8954?d=identicon)[gokepelemo](/maintainers/gokepelemo)

---

Top Contributors

[![gokepelemo](https://avatars.githubusercontent.com/u/51683468?v=4)](https://github.com/gokepelemo "gokepelemo (98 commits)")

### Embed Badge

![Health badge](/badges/gokepelemo-wpgraphql-content-filter/health.svg)

```
[![Health](https://phpackages.com/badges/gokepelemo-wpgraphql-content-filter/health.svg)](https://phpackages.com/packages/gokepelemo-wpgraphql-content-filter)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
