Skip to content
wpperformancePublic

About

Disable native features of WordPress that you don't need.

Resources

Stars

10 stars

Watchers

1 watching

Forks

Latest commit

 

History

31 Commits

Folders and files

Repository files navigation

Deaktiver

WordPress plugin to disable native features you do not need (RSS, comments, jQuery, posts/blog, XML-RPC, etc.).

true means the feature is disabled.

Installation

Composer (Bedrock / similar):

composer require wp-performance/deaktiver

Or copy the plugin into wp-content/plugins/deaktiver (or web/app/plugins/deaktiver on Bedrock) and activate it.

Settings live under Settings → Deaktiver.

Configuration

Two sources, in this order:

  1. Theme file {theme}/config/deaktiver.php — if present, it wins. The admin form is then read-only (no database write).
  2. Database option deaktiver_config (admin UI), cached 24h in the transient deaktiver_config.

A copy of the default keys lives in this repo at config/deaktiver.php (false = leave WordPress default).

Example theme config:

<?php

return [
    'emoji' => true,
    'embed' => true,
    'feed' => true,
    'xmlrpc' => true,
    'jquery' => true,
    'jquery-migrate' => true,
    'version' => true,
    'powered-by' => true,
    'wlwmanifest' => true,
    'rsd_link' => true,
    'short_link' => true,
    'rest_link' => true,
    'comments' => true,
    'posts' => true,
    'rest_user' => true,
    'login_url' => true,
    'login_lang_selector' => true,
];

Labels and descriptions for the admin UI come from config/options.php.

Options

Key What it disables
emoji Emoji scripts, styles, TinyMCE plugin, SVG CDN
embed oEmbed discovery, rewrite rules, TinyMCE embed plugin
feed RSS/RDF/Atom feeds, extra feed links, comment feeds
xmlrpc XML-RPC, pingbacks, RSD; xmlrpc.php returns 403
jquery Front-end jQuery for guests (kept in admin, for logged-in users, and on wp-login.php)
jquery-migrate jquery-migrate dependency on the front
version generator meta / the_generator
powered-by HTTP X-Powered-By (skipped if headers are already sent, e.g. page cache)
wlwmanifest Windows Live Writer manifest link
rsd_link Really Simple Discovery link
short_link Shortlink in <head> and Link header
rest_link REST discovery <link> and Link header
comments Comments UI, widgets, admin screens, reply script
posts Native blog (posts, categories, tags) — custom post types stay available
rest_user /wp/v2/users for anonymous requests
login_url Login logo URL/title point to the current site
login_lang_selector Language dropdown on wp-login.php

Posts option

When posts is true:

  • Admin: hide Posts menu, block native post / category / tag screens (403), remove Quick Draft and “New Post” in the admin bar. Custom post types on post.php / post-new.php are not blocked.
  • Front: 301 to home for single posts, category/tag archives, the posts index (is_home), post-only author/date archives, post feeds, and post-only search.
  • Queries: exclude post from front search and secondary queries (Query Loop, etc.).
  • REST: drop /wp/v2/posts, /wp/v2/categories, /wp/v2/tags and sub-routes.
  • Widgets: unregister Recent Posts, Categories, Archives, Calendar, Tag Cloud.

Development

Layout:

deaktiver.php          Bootstrap (plugin header, init)
config/options.php     Admin labels
config/deaktiver.php   Example theme config
src/Deaktive/          One class per option (`Deaktive{Key}`)
src/Options/           Settings page + AJAX save
admin-app/             Alpine + Vite settings UI
tests/                 CLI unit tests (no WordPress boot)

A config key maps to a class: powered-by → Deaktiver\Deaktive\DeaktivePoweredBy (- / _ become camel case, prefix Deaktive).

Add an option

  1. Add the key to config/options.php (label + description) and config/deaktiver.php.
  2. Add a class src/Deaktive/Deaktive{Name}.php extending DeaktiveBase with disable(): void.
  3. Hook only when needed; guard header changes with headers_sent().
  4. Bump the plugin version in deaktiver.php and add a Changelog entry below.

Tests

composer test
# or
php tests/DeaktivePostsResolveTest.php

Admin app

cd admin-app
npm install
npm run dev    # Vite on https://localhost:9980 (HMR)
npm run build  # writes admin-app/dist

The public base path is derived from the plugin folder so Bedrock (/app/plugins/...) and classic (/wp-content/plugins/...) both work.


Changelog

1.5.3

  • Powered By: stop calling header_remove('x-powered-by') after output has started (page cache / millicache). Remove the header immediately at plugin load, then again on send_headers, and skip when headers_sent() is true to avoid PHP warnings.

1.5.2

  • Posts / blog: extract admin post type resolution (resolve_admin_post_type()) and add unit tests for CPT save vs native post block cases. Same allow/block behavior as 1.5.1.

1.5.1

  • Posts / blog: fix CPT save on post.php when posts is disabled — no longer 403 custom post types. Classic editor POSTs to post.php without a query string; resolve post_type from GET, then POST, then get_post_type() of the edited ID. Native posts, categories and tags stay blocked.

1.5.0

  • Posts / blog: new posts option to disable the native blog surface
    • Admin: hide Posts menu, block post/category/tag screens, remove Quick Draft and “New Post” admin bar item
    • Front: 301 redirect to home for single posts, category/tag archives, post-only author/date archives, post feeds, and post-only search
    • Queries: exclude post from front search and secondary queries (Query Loop, etc.)
    • REST: remove /wp/v2/posts, /wp/v2/categories, /wp/v2/tags and related sub-routes
    • Widgets: unregister Recent Posts, Categories, Archives, Calendar, Tag Cloud
  • Bootstrap: main plugin file renamed from index.php to deaktiver.php
  • Admin app: Vite upgraded to v8 (rolldownOptions, import.meta.dirname), dynamic public base path for Bedrock (/app/plugins/...) and classic (/wp-content/plugins/...), Biome config updated for 2.x

About

Disable native features of WordPress that you don't need.

Resources

Stars

10 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages