Question about repurposing WordPress 404 handler

Here is the tested code, you can use it as a mu-plugin:

<?php
/**
 * Filters whether to short-circuit default header status handling.
 *
 * Returning a non-false value from the filter will short-circuit the handling
 * and return early.
 *
 * @param bool     $preempt  Whether to short-circuit default header status handling. Default false.
 * @param WP_Query $wp_query WordPress Query object.
 *
 * @return bool
 * @since 4.5.0
 */
function pre_handle_404_filter( bool $preempt, WP_Query $wp_query ) {
    global $parsed_address, $api_results;

    $parsed_address = get_parsed_address();

    if ( ! $parsed_address ) {
        return $preempt;
    }

    // Make a request to  API, get status.
    $status      = true; // For debug purposes.
    $api_results = null;

    if ( $status ) {
        // Save results to $api_results.
        // Return true to avoid 404 processing by WP.
        return true;
    }

    return $preempt;
}

add_filter( 'pre_handle_404', 'pre_handle_404_filter', 10, 2 );

/**
 * Handle 404.
 */
function handle_404() {
    global $parsed_address, $api_results, $wp_query;

    if ( ! $parsed_address ) {
        return;
    }

    // Set 404 here to prevent bugs in get_header().
    $wp_query->set_404();

    get_header();
    echo 'API Results'; // Output $api_results here.
    get_footer();
    exit();
}

add_action( 'template_redirect', 'handle_404', - PHP_INT_MAX );

/**
 * Get parsed address from the request URI.
 * Make sure we have an address in the URI, otherwise return an empty string.
 *
 * @return string
 */
function get_parsed_address() {
    $request_uri =
        isset( $_SERVER['REQUEST_URI'] ) ?
            filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_STRING ) :
            '';

    if ( url_to_postid( $request_uri ) ) {
        return '';
    }

    $path_parts = explode( "https://wordpress.stackexchange.com/", $request_uri );
    $part1      = isset( $path_parts[1] ) ? $path_parts[1] : '';

    if ( 'property' !== $part1 ) {
        return '';
    }

    $address = isset( $path_parts[2] ) ? $path_parts[2] : '';

    return str_replace( '-', ' ', $address );
}

/**
 * Filter page title.
 *
 * @param array $title_parts Title parts.
 *
 * @return mixed
 */
function theme_slug_filter_wp_title( $title_parts ) {
    global $parsed_address, $api_results, $wp_query;

    if ( ! $parsed_address ) {
        return $title_parts;
    }

    $title_parts['title'] = ucwords( $parsed_address ) . ' | AAA Real Estate';

    return $title_parts;
}

add_filter( 'document_title_parts', 'theme_slug_filter_wp_title' );

We catch 404 via pre_handle_404, make the API request and save results. Please note that it works when we have parsed address in the URI only.

Later, on template_redirect event, we check again that have parsed address and set back 404 status to prevent bugs in the get_header(). Please note that we intercept template_redirect as early as possible, at - PHP_INT_MAX priority to execute our code before standard template_redirect hook in the WP core.

Leave a Comment