Advanced 404-page snippet for WordPress
Andrew Lazarev
Posted on November 24, 2024
This PHP code is designed to handle custom 404 errors in a WordPress environment. Its main purpose is to improve the user experience by attempting to redirect users to the most relevant page or provide helpful suggestions if a requested URL cannot be found. Here's a detailed breakdown of what the code does:
Key Features:
1. Extract the Last Segment of the URL:
- The script retrieves the requested URL and isolates the last part of the path (e.g., for /some/path/example, it extracts example).
2. Search for Existing Paths:
- A function (find_existing_path) is used to check whether the extracted segment matches:
-- A published post slug.
-- A tag slug in the WordPress taxonomy.
- If a match is found, the function returns the URL of the corresponding post or tag.
- If no match is found in the primary database search, it checks a predefined list of folders (blog, category, etc.) for potential matches. If a match exists, it constructs and returns the appropriate URL.
3. Redirect to the Found Path:
- If a matching path is found in the search process, the user is redirected to it using a 301 permanent redirect.
4. Search for Similar Content:
- If no exact match is found, the script converts the last segment into a search query by replacing special characters (-, _, and %20) with +.
- It performs a WordPress search query to find up to 5 posts that might be relevant.
5. Display Search Results:
- If matching posts are found, it displays them to the user in the following way: -- A heading is shown in the appropriate language (Russian, Italian, or English), depending on the site's locale. -- Instead of plain links, the thumbnails of the suggested posts are displayed using a loop (get_template_part).
6. Fallback:
- If neither a matching path nor search results are found, the standard 404 error page will remain.
Purpose:
This script enhances WordPress’s default 404 error handling by:
- Redirecting users to relevant pages if possible.
- Providing search-based suggestions when exact matches are unavailable.
- Improving user navigation and potentially reducing bounce rates.
`
function handle_custom_404() {
// Get the requested URL path
$request_uri = $_SERVER['REQUEST_URI'];
$request_path = trim(urldecode($request_uri), '/');
// Extract only the last segment of the path
$last_segment = basename($request_path);
// Function to search for an existing path in other folders
function find_existing_path($path) {
global $wpdb;
// Perform a combined query to search for slugs in posts and tags without a LIMIT 1 restriction
$results = $wpdb->get_results($wpdb->prepare(
"(SELECT ID AS item_id, 'post' AS item_type FROM {$wpdb->posts}
WHERE post_name = %s AND post_status = 'publish')
UNION ALL
(SELECT t.term_id AS item_id, 'tag' AS item_type FROM {$wpdb->terms} t
INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id
WHERE t.slug = %s AND tt.taxonomy = 'post_tag')",
$path, $path
));
// If exactly one record is found, return its URL
if (count($results) === 1) {
$result = $results[0];
if ($result->item_type === 'post') {
return get_permalink($result->item_id);
} elseif ($result->item_type === 'tag') {
return get_tag_link($result->item_id);
}
}
// If multiple results or none are found, use the old logic
$paths_to_check = ['blog', 'category', 'news', 'tag', 'news/news-photo'];
foreach ($paths_to_check as $folder) {
$potential_path = $folder . '/' . $path;
// Check if a page exists at this path or a term exists in the required taxonomy
if (url_to_postid(site_url($potential_path)) != 0 || term_exists($path, $folder)) {
return site_url($potential_path);
}
}
return false;
}
// Check if a similar path exists in other folders
$existing_path = find_existing_path($last_segment);
if ($existing_path) {
// If a similar path is found, perform a redirect
wp_redirect($existing_path, 301);
exit;
}
// Search by keywords, replacing "-" and "_" with pluses
$search_query = str_replace(['-', '_', '%20'], '+', $last_segment);
// Perform a search by keywords
$search = new WP_Query([
's' => $search_query,
'posts_per_page' => 5
]);
// Output results if found
if ($search->have_posts()) {
echo '</br>';
$locale = get_locale();
if ($locale === 'ru_RU') {
echo '<h2>Возможно Вы искали это:</h2>';
} elseif ($locale === 'it_IT') {
echo '<h2>Forse stavi cercando questo:</h2>';
} else {
echo '<h2>Perhaps you were looking for this:</h2>';
}
echo '</br>';
echo '<div>';
// Instead of displaying links, output post thumbnails
while ($search->have_posts()) :
$search->the_post();
echo '<div class="post-thumbnail">';
get_template_part('content', get_post_format());
echo '</div>';
endwhile;
// Output pagination
// the_posts_pagination();
echo '</div>';
wp_reset_postdata();
}
}
`
This code on GitHub
Posted on November 24, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.