Расширенный фрагмент страницы 404 для WordPress
Этот PHP-код предназначен для обработки пользовательских ошибок 404 в среде WordPress. Его главная цель — улучшить пользовательский опыт, пытаясь перенаправить пользователей на наиболее релевантную страницу или предоставить полезные предложения, если запрошенный URL не может быть найден. Вот подробное описание того, что делает код:
1. Извлеките последний сегмент URL-адреса
Скрипт извлекает запрошенный URL-адрес и изолирует последнюю часть пути (например, для /some/path/example
он извлекает example
).
2. Поиск существующих путей
Функция find_existing_path
используется для проверки соответствия извлеченного сегмента:
- Если совпадение найдено, функция возвращает URL-адрес соответствующего поста или тега.
- Если при поиске в первичной базе данных совпадений не обнаружено, он проверяет предопределенный список папок (блог, категория и т.д.) на предмет потенциальных совпадений. Если совпадение существует, он создает и возвращает соответствующий URL.
3. Перенаправление на найденный путь
Если в процессе поиска найден соответствующий путь, пользователь перенаправляется на него с помощью постоянного редиректа 301.
4. Поиск похожего контента
Если точное совпадение не найдено, скрипт преобразует последний сегмент в поисковый запрос, заменяя специальные символы (-, _ и %20) на +
. Он выполняет поисковый запрос WordPress, чтобы найти до 5 публикаций, которые могут быть релевантны.
5. Отображение результатов поиска
Если соответствующие записи найдены, он отображает их пользователю следующим образом. Заголовок отображается на соответствующем языке (русский, итальянский или английский) в зависимости от локали сайта. Вместо простых ссылок с помощью цикла get_template_part
отображаются миниатюры предлагаемых записей.
6. Запасной вариант
Если не найдено ни соответствующего пути, ни результатов поиска, останется стандартная страница ошибки 404.
Вывод
Этот скрипт улучшает обработку ошибок 404 в WordPress по умолчанию следующим образом:
- Перенаправление пользователей на соответствующие страницы, если это возможно.
- Предоставление поисковых предложений при отсутствии точных совпадений.
- Улучшение навигации пользователей и потенциальное снижение показателя отказов.
function handle_custom_404() {
// Получаем запрашиваемый путь URL
$request_uri = $_SERVER['REQUEST_URI'];
$request_path = trim(urldecode($request_uri), '/');
// Извлекаем только последний сегмент пути
$last_segment = basename($request_path);
// Функция для поиска существующего пути в других папках
function find_existing_path($path) {
global $wpdb;
// Выполняем объединенный запрос для поиска слага в постах и тегах без ограничения LIMIT 1
$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
));
// Если найдена ровно одна запись, возвращаем её 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);
}
}
// Если результатов несколько или ничего не найдено, используем старую логику
$paths_to_check = ['blog', 'category', 'news', 'tag', 'news/news-photo'];
foreach ($paths_to_check as $folder) {
$potential_path = $folder . '/' . $path;
// Проверяем, существует ли страница по этому пути или термин в нужной таксономии
if (url_to_postid(site_url($potential_path)) != 0 || term_exists($path, $folder)) {
return site_url($potential_path);
}
}
return false;
}
// Проверка, существует ли похожий путь в других папках
$existing_path = find_existing_path($last_segment);
if ($existing_path) {
// Если найден похожий путь, выполняем редирект
wp_redirect($existing_path, 301);
exit;
}
// Поиск по ключевым словам, заменяя "-" и "_" на плюсы
$search_query = str_replace(['-', '_', '%20'], '+', $last_segment);
// Выполняем поиск по ключевым словам
$search = new WP_Query([
's' => $search_query,
'posts_per_page' => 5
]);
// Выводим результаты, если они найдены
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>';
// Вместо вывода ссылок, выводим миниатюры постов
while ($search->have_posts()) :
$search->the_post();
echo '<div class="post-thumbnail">';
get_template_part('content', get_post_format());
echo '</div>';
endwhile;
// Выводим пагинацию
// the_posts_pagination();
echo '</div>';
wp_reset_postdata();
}
}