URL категорий возвращают 404 после установки основы категории на ‘.’.

Вопрос или проблема

Я хочу удалить /category из URL. Я установил базу категорий в “.”

У меня есть некоторые “ссылки категорий”, которые ранее выглядели как /category/category-name/sub-category-name. Теперь они /category-name/sub-category-name. Эти URL ранее отображали страницы, которые перечисляли все записи, прикрепленные к этой категории. Теперь они возвращают 404 ошибки.

Где я могу искать, чтобы отладить это?

Попробуйте сбросить постоянные ссылки, перейдите в (Настройки > Постоянные ссылки) и нажмите “сохранить”, не внося изменений.

Иногда вам нужно написать новые действия. Чтобы решить проблему базы категорий, вам нужно добавить и удалить некоторые действия. Вы можете попробовать этот код как пользовательский плагин. Возможно, это решит вашу проблему. Код полностью удаляет базу /category/.

Добавьте этот код в functions.php вашей темы или создайте пользовательский плагин с этим кодом.

/**
 * Добавьте некоторые действия для сброса правил перезаписи
 */

add_action('created_category', 'flush_rewrite_rules_f_custom');
add_action('delete_category', 'flush_rewrite_rules_f_custom');
add_action('edited_category', 'flush_rewrite_rules_f_custom');

// Инициализация функции

add_action('init', 'remove_url_perma_cat');

function flush_rewrite_rules_f_custom()
{
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

function remove_url_perma_cat()
{
    global $wp_rewrite;
    $wp_rewrite->extra_permastructs['category'][0] = '%category%';
}

/**
 * Добавьте фильтр для перенаправления
 */

add_filter('category_rewrite_rules', 'remo_rew_rul_c');
add_filter('query_vars', 'remo_q_vars_c');
add_filter('request', 'remo_crw_req');

/**
 * Удаление базы категорий и перенаправление
 */
function remo_rew_rul_c($category_rewrite)
{
    global $wp_rewrite;

    $category_rewrite = array();

    $categories = get_categories(array( 'hide_empty' => false ));

    foreach ($categories as $category) {
        $category_nicename = $category->slug;
        if ($category->parent == $category->cat_ID) {
            $category->parent = 0;
        } elseif (0 != $category->parent) {
            $category_nicename = get_category_parents($category->parent, false, "https://wordpress.stackexchange.com/", true) . $category_nicename;
        }
        $category_rewrite[ '(' . $category_nicename . ')/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
        $category_rewrite[ '(' . $category_nicename . ')/page/?([0-9]{1,})/?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[2]';
        $category_rewrite[ '(' . $category_nicename . ')/?$' ] = 'index.php?category_name=$matches[1]';
    }

    $old_category_base = get_option('category_base') ? get_option('category_base') : 'category';
    $old_category_base = trim($old_category_base, "https://wordpress.stackexchange.com/");
    $category_rewrite[ $old_category_base . '/(.*)$' ] = 'index.php?crw=$matches[1]';

    return $category_rewrite;
}

/**
 * Новая переменная запроса : crw
 */
function remo_q_vars_c($public_query_vars)
{
    $public_query_vars[] = 'crw';

    return $public_query_vars;
}

/**
 * Перенаправление на основе crw
 */
function remo_crw_req($query_vars)
{
    if (isset($query_vars['crw'])) {
        $catlink = trailingslashit(get_option('home')) . user_trailingslashit($query_vars['crw'], 'category');
        status_header(301);
        header("Location: $catlink");
        exit;
    }
}

Если вы используете Apache, добавьте следующее в конец .htaccess в корне вашей установки WordPress. Это автоматически выполнит перенаправление для вас.

Примечание: Замените http://www.example.com на URL вашего сайта.

RewriteRule ^category/(.+)$ http://www.example.com/$1 [R=301,L]

Вы пробовали фильтровать объект $wp_query? Вы можете использовать этот фрагмент кода, чтобы искать слаг категории прямо в базе данных:

function pm_detect_term_slugs($query) {
    global $wpdb;

    // Не выполняется, когда открыт Elementor
    if((!empty($_REQUEST['action']) && strpos($_REQUEST['action'], 'elementor') !== false) || isset($_REQUEST['elementor-preview'])) {
        return $query;
    }

    // 1. Получите слаг
    if(!empty($query['pagename'])) {
        $slug = $query['pagename'];
    } else if(!empty($query['name'])) {
        $slug = $query['name'];
    } else if(!empty($query['attachment'])) {
        $slug = $query['attachment'];
    }

    if(!empty($slug)) {
        $slug = basename($slug);

        // 2. Проверьте, назначен ли слаг какому-либо элементу поста
        $sql_query = "SELECT t.slug, t.term_id, tt.taxonomy FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON(tt.term_id = tt.term_id) WHERE 1=1 AND slug = %s";
        $term = $wpdb->get_row($wpdb->prepare($sql_query, array($slug)));

        // 3. Отфильтруйте запрос, если термин найден
        if(!empty($term->taxonomy)) {
            $page = (!empty($query['paged'])) ? $query['paged'] : 1;

            $new_query = array(
                'term' => $term->slug,
                'taxonomy' => $term->taxonomy,
                'paged' => $page
            );

            // 4. Отключите каноническое перенаправление
            remove_action('template_redirect', 'wp_old_slug_redirect');
            remove_action('template_redirect', 'redirect_canonical');
            add_filter('wpml_is_redirected', '__return_false', 99, 2);
            add_filter('pll_check_canonical_url', '__return_false', 99, 2);

            return $new_query;
        }
    }
    return $query;
}
add_filter('request', 'pm_detect_term_slugs', 9999);

В качестве альтернативы можете использовать мой плагин Permalink Manager Pro для фильтрации постоянных ссылок категории:
https://permalinkmanager.pro/docs/basics/bulk-edit-wordpress-permalinks

Ответ или решение

Для вашей задачи — устранения ошибки 404 при использовании категории URL после удаления префикса "/category" в WordPress, требуется подойти к решению проблемы с пониманием внутренних механизмов работы движка WordPress и его структуры URL.

Теория

Одной из основных причин проблемы является изменение структуры URL категорий. Когда вы устанавливаете базу категории на ".", WordPress пытается обрабатывать все URL с учетом новых параметров. Однако, без правильного обновления и применения правил перезаписи (rewrite rules), система, возможно, не сможет найти нужные страницы, что и вызывает ошибку 404. Стандартная структура URL включает в себя базу категории, и её внезапное удаление требует корректной настройки правил перезаписи.

Также важно понимать, что система перезаписей URL в WordPress привносит собственные сложности. Когда вы меняете структуру URL, система должна обновить rewrite rules, чтобы учесть эти изменения. Данный процесс включает изменение в базе данных и файловой системе (например, через обновление .htaccess в случае использования сервера Apache).

Пример

Допустим, у вас была категория со старым URL /category/category-name/sub-category-name. После изменения базы категории на ".", WordPress ожидает, что вы обновите правила перезаписи, чтобы новые URL, такие как /category-name/sub-category-name, правильно интерпретировались. Если правила перезаписи не будут обновлены, WordPress не найдет соответствие для этих запросов, ведя к ошибке 404.

Вы предоставили пример кода, который прямо нацелен на устранение этой проблемы путем добавления и удаления определенных действий через файл functions.php или создание плагина:

add_action('init', 'remove_url_perma_cat');

function remove_url_perma_cat() {
    global $wp_rewrite;
    $wp_rewrite->extra_permastructs['category'][0] = '%category%';
}

Этот код устраняет базу категории, что позволяет категориям функционировать без префикса /category.

Применение

Для решения вашей проблемы настоятельно рекомендую выполнить следующие шаги:

  1. Очистите пермалинки: Перейдите в раздел Настройки > Пермалинки и сохраните настройки без изменения параметров. Это принудит WordPress заново записать правила перезаписи в файле .htaccess.

  2. Используйте код для манипуляции с перезаписями: В случае, если переписка пермалинков не помогла, добавьте предоставленный код в файл functions.php вашей темы или создайте собственный плагин. Это обеспечит перезапись правил и устранение необходимости использования базы категории.

  3. Индексация URL: Убедитесь, что новый формат URL правильно индексируется поисковыми системами, используя временные редиректы, если необходимо. Например, через файл .htaccess, добавив правило:

RewriteRule ^category/(.+)$ http://www.yoursite.com/$1 [R=301,L]

Это перенаправит старые URL с использованием /category на новый формат.

  1. Проверка растаскивания запросов: В случае постоянных проблем, возможно, потребуется глубже изучить сущность запросов, используя фильтры, такие как query_vars и request, чтобы убедиться, что система правильно понимает ваш формат URL.

  2. Плагины и дополнительное ПО: Также, подумайте об установке плагина, как Permalink Manager Pro, для более тонкой кастомизации правил перезаписи и обеспечения корректного функционирования всех ссылок на вашем сайте.

Каждое из этих действий поможет не только устранить текущую проблему, но и предотвратить возникновение подобных проблем в будущем при изменении структуры URL. Если суть ваших URL является критически важной, не забывайте об аккуратной перенастройке плагинов кэширования и SEO-настроек.

Оцените материал
Добавить комментарий

Капча загружается...