Filters

Filters let you modify data before WordPress uses or displays it. They always receive a value and must return it (modified or not).

the_content

loop-content

Filters post content before display

the_content is the last chance to change post HTML before it reaches the template. Always return the string — filters that echo will break the page.

Signature

apply_filters( 'the_content', string $content );

Example

add_filter( 'the_content', function( $content ) {
    if ( is_single() ) {
        $content .= '<p><strong>Thanks for reading!</strong></p>';
    }
    return $content;
} );

Common Use Cases

  • Append/prepend content to posts
  • Transform shortcodes manually
  • Add schema markup to content
  • Strip or sanitize specific HTML
since 0.71wp-includes/post-template.php

the_title

loop-content

Filters the post title

the_title changes how a title is displayed, not the value in the database. Guard with post ID so menus and admin lists are not rewritten by accident.

Signature

apply_filters( 'the_title', string $title, int $id );

Example

add_filter( 'the_title', function( $title, $id ) {
    if ( get_post_type( $id ) === 'book' ) {
        return 'Book: ' . $title;
    }
    return $title;
}, 10, 2 );

Common Use Cases

  • Prefix/suffix titles by post type
  • Truncate long titles
  • Add icons or labels to titles
  • Translate titles dynamically
since 0.71wp-includes/post-template.php

wp_title

head-meta

Filters the document <title> tag

wp_title is the classic document-title filter. Modern themes should prefer document_title_parts — this hook remains for older title tags.

Signature

apply_filters( 'wp_title', string $title, string $sep, string $seplocation );

Example

add_filter( 'wp_title', function( $title, $sep ) {
    return $title . $sep . get_bloginfo( 'name' );
}, 10, 2 );

Common Use Cases

  • Customize SEO page titles on legacy themes
  • Append site name to titles
  • Set title format for specific pages
  • Override title for 404 pages
since 0.71wp-includes/general-template.php

body_class

head-meta

Filters the CSS classes on <body>

body_class lets CSS target context without extra wrappers. Return the array — do not echo class names.

Signature

apply_filters( 'body_class', string[] $classes, string[] $css_class );

Example

add_filter( 'body_class', function( $classes ) {
    if ( is_user_logged_in() ) {
        $classes[] = 'user-logged-in';
    }
    return $classes;
} );

Common Use Cases

  • Add role-based body classes
  • Target specific page templates via CSS
  • Add device detection classes
  • Inject A/B test variant classes
since 2.8.0wp-includes/post-template.php

excerpt_length

loop-content

Controls the auto-generated excerpt word count

excerpt_length only affects auto excerpts, not the Excerpt box in the editor. Return an integer word count.

Signature

apply_filters( 'excerpt_length', int $number );

Example

add_filter( 'excerpt_length', function( $length ) {
    return 30;
} );

Common Use Cases

  • Shorten excerpts for card layouts
  • Lengthen excerpts for search results
  • Vary length by post type
  • Control reading time estimates
since 2.7.0wp-includes/formatting.php

login_url

auth

Filters the login page URL

login_url is how membership and white-label sites hide wp-login.php. Return a full URL, not a path fragment.

Signature

apply_filters( 'login_url', string $login_url, string $redirect, bool $force_reauth );

Example

add_filter( 'login_url', function( $url ) {
    return home_url( '/my-login/' );
} );

Common Use Cases

  • Custom login page URL
  • Hide wp-login.php from bots
  • Membership site login flow
  • White-label WordPress projects
since 2.8.0wp-includes/general-template.php

the_excerpt

loop-content

Filters the displayed post excerpt

the_excerpt filters the final excerpt string, whether it was typed manually or auto-generated — use excerpt_length/excerpt_more to shape the auto version instead.

Signature

apply_filters( 'the_excerpt', string $post_excerpt );

Example

add_filter( 'the_excerpt', function( $excerpt ) {
    return '<div class="excerpt-wrap">' . $excerpt . '</div>';
} );

Common Use Cases

  • Wrap excerpts in custom markup
  • Append a 'read more' link consistently
  • Strip shortcodes left in excerpts
since 0.71wp-includes/post-template.php

excerpt_more

loop-content

Filters the '[...]' string appended to auto-generated excerpts

excerpt_more only changes the trailing string on auto-generated excerpts — it does nothing to a manually written excerpt.

Signature

apply_filters( 'excerpt_more', string $more_string );

Example

add_filter( 'excerpt_more', function() {
    return ' <a href="' . get_permalink() . '">Read more →</a>';
} );

Common Use Cases

  • Replace the ellipsis with a Read More link
  • Localize the trailing string
  • Add an icon after trimmed excerpts
since 1.8.0wp-includes/formatting.php

post_class

loop-content

Filters the CSS classes on a single post's wrapper element

post_class runs once per post inside the loop — unlike body_class, which runs once per page — so keep the callback fast if you're looping many posts.

Signature

apply_filters( 'post_class', string[] $classes, string[] $css_class, int $post_id );

Example

add_filter( 'post_class', function( $classes, $css_class, $post_id ) {
    if ( has_post_thumbnail( $post_id ) ) {
        $classes[] = 'has-thumbnail';
    }
    return $classes;
}, 10, 3 );

Common Use Cases

  • Add a class for featured-image presence
  • Highlight sticky or featured posts
  • Add taxonomy-term-based classes
  • Alternate row classes for grid layouts
since 2.7.0wp-includes/post-template.php

document_title_parts

head-meta

Filters the parts that build the <title> tag on modern themes

document_title_parts is the modern replacement for wp_title — it works with an array of parts, not a raw string, so you edit pieces instead of parsing text.

Signature

apply_filters( 'document_title_parts', array $title );

Example

add_filter( 'document_title_parts', function( $title ) {
    if ( is_singular( 'book' ) ) {
        $title['title'] .= ' | Book Review';
    }
    return $title;
} );

Common Use Cases

  • Customize SEO page titles per post type
  • Remove the tagline/site name segment
  • Add dynamic segments (category, search term)
  • Override the title on 404 pages
since 4.4.0wp-includes/general-template.php

wp_nav_menu_items

loop-content

Filters the HTML list items of a rendered nav menu

wp_nav_menu_items lets you append or alter menu markup without editing the menu in the admin — useful for injecting a login/cart link at the end.

Signature

apply_filters( 'wp_nav_menu_items', string $items, stdClass $args );

Example

add_filter( 'wp_nav_menu_items', function( $items, $args ) {
    if ( 'primary' !== $args->theme_location ) {
        return $items;
    }
    $items .= is_user_logged_in()
        ? '<li><a href="' . wp_logout_url() . '">Log out</a></li>'
        : '<li><a href="' . wp_login_url() . '">Log in</a></li>';
    return $items;
}, 10, 2 );

Common Use Cases

  • Append a login/cart/search item to a menu
  • Inject a CTA button into navigation
  • Conditionally add items by user role
since 3.0.0wp-includes/nav-menu-template.php

wp_mail_from

admin

Filters the from-address used by wp_mail()

wp_mail_from fixes the wordpress@yourdomain.com sender WordPress uses by default — pair it with wp_mail_from_name to fully brand outgoing mail.

Signature

apply_filters( 'wp_mail_from', string $from_email );

Example

add_filter( 'wp_mail_from', function() {
    return 'no-reply@example.com';
} );
add_filter( 'wp_mail_from_name', function() {
    return get_bloginfo( 'name' );
} );

Common Use Cases

  • Fix deliverability by using a real domain address
  • Brand transactional emails with the site name
  • Route different email types from different addresses
since 2.2.3wp-includes/pluggable.php

upload_mimes

media

Filters the list of file types allowed for upload

upload_mimes controls what get_allowed_mime_types() and the uploader accept — adding a type here does not make it safe by itself; WordPress still runs its own file-content checks.

Signature

apply_filters( 'upload_mimes', array $mime_types, WP_User|int|null $user );

Example

add_filter( 'upload_mimes', function( $mimes ) {
    $mimes['svg'] = 'image/svg+xml';
    return $mimes;
} );

Common Use Cases

  • Allow SVG or other blocked file types
  • Restrict uploads to a smaller set of types by role
  • Add support for a niche file format
since 2.0.0wp-includes/functions.php

comment_text

comments

Filters the displayed text of a single comment

comment_text is where you'd add nofollow to links, auto-linkify text, or moderate content on display — it doesn't change what's stored in the database.

Signature

apply_filters( 'comment_text', string $comment_text, WP_Comment|null $comment, array $args );

Example

add_filter( 'comment_text', function( $comment_text, $comment ) {
    if ( $comment && ! $comment->user_id ) {
        $comment_text .= '<span class="guest-badge">Guest</span>';
    }
    return $comment_text;
}, 10, 2 );

Common Use Cases

  • Add badges/labels to comment output
  • Auto-link mentions or hashtags in comments
  • Strip disallowed markup on display
since 0.71wp-includes/comment-template.php

template_include

loop-content

Filters the final template file path WordPress is about to load

template_include is the very last stop in the template hierarchy — return an absolute path to a PHP file and WordPress loads exactly that, bypassing the rest of the hierarchy.

Signature

apply_filters( 'template_include', string $template );

Example

add_filter( 'template_include', function( $template ) {
    if ( is_singular( 'book' ) ) {
        $custom = plugin_dir_path( __FILE__ ) . 'templates/single-book.php';
        if ( file_exists( $custom ) ) {
            return $custom;
        }
    }
    return $template;
} );

Common Use Cases

  • Ship custom templates from a plugin
  • Override a theme's template for a specific condition
  • Serve a completely custom page (landing pages, builders)
since 1.5.0wp-includes/template-loader.php

admin_footer_text

admin

Filters the text shown in the bottom-left of every admin page

admin_footer_text is a lightweight branding hook — agencies commonly use it to replace WordPress's default footer credit with their own support link.

Signature

apply_filters( 'admin_footer_text', string $text );

Example

add_filter( 'admin_footer_text', function() {
    return 'Managed by Acme Agency — <a href="https://example.com/support">Get support</a>';
} );

Common Use Cases

  • White-label the admin footer for clients
  • Add a support/help link
  • Show the current plugin/theme version
since 2.8.0wp-admin/includes/template.php

script_loader_tag

enqueue

Filters the final <script> tag markup for an enqueued script

script_loader_tag is how you add async/defer or a nonce to a specific enqueued script without touching the theme's enqueue logic wholesale.

Signature

apply_filters( 'script_loader_tag', string $tag, string $handle, string $src );

Example

add_filter( 'script_loader_tag', function( $tag, $handle ) {
    if ( 'my-script' !== $handle ) {
        return $tag;
    }
    return str_replace( ' src', ' defer src', $tag );
}, 10, 2 );

Common Use Cases

  • Add async/defer to specific scripts
  • Add a nonce or crossorigin attribute
  • Remove type="text/javascript" for cleaner markup
since 4.1.0wp-includes/class-wp-scripts.php

render_block

loop-content

Filters the final HTML output of every rendered block

render_block runs for every block on the page, core and custom alike — check $block['blockName'] or it will touch content you didn't intend to change.

Signature

apply_filters( 'render_block', string $block_content, array $block );

Example

add_filter( 'render_block', function( $block_content, $block ) {
    if ( 'core/image' !== $block['blockName'] ) {
        return $block_content;
    }
    return str_replace( '<img', '<img loading="lazy"', $block_content );
}, 10, 2 );

Common Use Cases

  • Modify markup of one specific block type
  • Inject wrapper markup around blocks
  • Add tracking attributes to CTA blocks
since 5.0.0wp-includes/class-wp-block.php

rest_prepare_post

rest-api

Filters the REST API response for a single post before it's sent

rest_prepare_post lets you add or remove fields on the /wp/v2/posts response without touching register_rest_field — useful for last-mile shaping of what the API returns.

Signature

apply_filters( 'rest_prepare_post', WP_REST_Response $response, WP_Post $post, WP_REST_Request $request );

Example

add_filter( 'rest_prepare_post', function( $response, $post ) {
    $response->data['reading_time'] = ceil( str_word_count( $post->post_content ) / 200 );
    return $response;
}, 10, 2 );

Common Use Cases

  • Add computed/derived fields to the REST response
  • Strip sensitive fields from public API output
  • Reshape data for a headless front-end
since 4.7.0wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

wp_get_attachment_image_attributes

media

Filters the HTML attributes of an image rendered by wp_get_attachment_image()

wp_get_attachment_image_attributes touches every image WordPress renders through its own media functions — including inside blocks and thumbnails — so scope changes carefully.

Signature

apply_filters( 'wp_get_attachment_image_attributes', array $attr, WP_Post $attachment, string|array $size );

Example

add_filter( 'wp_get_attachment_image_attributes', function( $attr ) {
    $attr['loading'] = 'lazy';
    $attr['decoding'] = 'async';
    return $attr;
} );

Common Use Cases

  • Add loading="lazy" or fetchpriority attributes
  • Override alt text site-wide
  • Add custom data-* attributes for a lightbox script
since 2.8.0wp-includes/media.php

cron_schedules

cron

Registers custom cron interval schedules

cron_schedules is the only way to add a custom recurring interval — WordPress ships with hourly, twicedaily, and daily only.

Signature

apply_filters( 'cron_schedules', array $schedules );

Example

add_filter( 'cron_schedules', function( $schedules ) {
    $schedules['every_fifteen_minutes'] = [
        'interval' => 15 * MINUTE_IN_SECONDS,
        'display'  => 'Every 15 Minutes',
    ];
    return $schedules;
} );

Common Use Cases

  • Add a custom recurring interval (e.g. every 15 minutes)
  • Register a weekly or non-standard interval
  • Match a plugin's own scheduled task frequency
  • Support finer-grained sync/polling than core's daily/hourly options
since 2.1.0wp-includes/cron.php

authenticate

auth

The core WordPress login/authentication filter

authenticate is the chain that decides whether login credentials are valid — every auth method, from core's own password check to SSO plugins, hooks into this same filter.

Signature

apply_filters( 'authenticate', WP_User|WP_Error|null $user, string $username, string $password );

Example

add_filter( 'authenticate', function( $user, $username ) {
    if ( 'blocked_user' === $username ) {
        return new WP_Error( 'blocked', 'This account is disabled.' );
    }
    return $user;
}, 30, 3 );

Common Use Cases

  • Add a second authentication factor before allowing login
  • Block specific usernames or patterns
  • Integrate an SSO/external identity provider
  • Log failed or suspicious login attempts
since 2.8.0wp-includes/user.php

rest_pre_dispatch

rest-api

Short-circuits a REST API request before routing

rest_pre_dispatch lets you intercept a REST API request before WordPress even matches it to a route — the earliest point to block or fake a response.

Signature

apply_filters( 'rest_pre_dispatch', mixed $result, WP_REST_Server $server, WP_REST_Request $request );

Example

add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
    if ( str_starts_with( $request->get_route(), '/my-plugin/v1' ) && ! is_user_logged_in() ) {
        return new WP_Error( 'forbidden', 'Login required', [ 'status' => 401 ] );
    }
    return $result;
}, 10, 3 );

Common Use Cases

  • Block REST API access globally or per-route before any processing
  • Serve a cached response without running the real route logic
  • Rate-limit or IP-block at the earliest possible point
  • Mock or A/B test an endpoint's response
since 4.4.0wp-includes/rest-api/class-wp-rest-server.php

manage_posts_columns

admin

Adds or removes columns on the admin post list table

manage_posts_columns controls what shows up in wp-admin's post list table — add a custom column here, then fill it with manage_posts_custom_column.

Signature

apply_filters( 'manage_posts_columns', string[] $columns );

Example

add_filter( 'manage_posts_columns', function( $columns ) {
    $columns['word_count'] = 'Word Count';
    return $columns;
} );

Common Use Cases

  • Show custom field values in the post list at a glance
  • Remove default columns you don't need (Author, Comments)
  • Control column display order
  • Build a lightweight custom dashboard view
since 2.5.0wp-admin/includes/class-wp-posts-list-table.php