0

I want to remove /category from URLs. I have set category base to "."

I have some "category urls" which previously looked like /category/category-name/sub-category-name They are now /category-name/sub-category-name These urls previously rendered pages that would list all the posts attached to that category. They now return 404s.

Where can I look to debug this?

2
  • Do you have access to your hosting to view your .htaccess file? It would be at the root directory and you might need to change your settings if viewing in an FTP client to "view hidden files." Also, do you have a caching plugin or caching on the server-level?
    – Megan Rose
    Dec 28, 2019 at 2:56
  • Duplicate: wordpress.stackexchange.com/questions/289691/… May 23, 2023 at 17:53

4 Answers 4

0

Try to flush permalinks by going to (Settings > Permalinks) and click save without making changes.

1
  • unfortunately that did not correct
    – kevzettler
    Dec 27, 2019 at 18:30
0

Sometimes you need to write new actions. To solve the category base problem you need to add and remove some actions. You can try this code as a custom plugin. Probably this can solve your problem. The code completely removes /category/ base.

Add this code to your theme's functions.php or create a custom plugin with this code.

/**
 * Add some actions to flush rewrite rules
 */

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');

// Init function

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 some filter for redirect
 */

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

/**
 * Remove catergory base and redirect
 */
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, '/', 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, '/');
    $category_rewrite[ $old_category_base . '/(.*)$' ] = 'index.php?crw=$matches[1]';

    return $category_rewrite;
}

/**
 * New Query Vars : crw
 */
function remo_q_vars_c($public_query_vars)
{
    $public_query_vars[] = 'crw';

    return $public_query_vars;
}

/**
 * Redirect based 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;
    }
}
1
  • I think this is the correct idea but the provided code here makes every URL render the root index.
    – kevzettler
    Jan 3, 2020 at 1:23
0

If you are using Apache then add the following to the end of .htaccess in the root of your WordPress installation. This will perform the redirection automatically for you.

Note: Replace http://www.example.com with your site URL.

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

Did you try to filter the $wp_query object? You can use this code snippet to search for the category slug directly in DB:

function pm_detect_term_slugs($query) {
    global $wpdb;

    // Do not run when Elementor is opened
    if((!empty($_REQUEST['action']) && strpos($_REQUEST['action'], 'elementor') !== false) || isset($_REQUEST['elementor-preview'])) {
        return $query;
    }

    // 1. Get the slug
    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. Check if the slug is assigned to any post item
        $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. Filter the query if any term was found
        if(!empty($term->taxonomy)) {
            $page = (!empty($query['paged'])) ? $query['paged'] : 1;

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

            // 4. Disable canonical redirect
            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);

Alternatively you can use my plugin Permalink Manager Pro to filter the category permalinks: https://permalinkmanager.pro/docs/basics/bulk-edit-wordpress-permalinks

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.