Force WordPress to Show Pages Instead of Category

I am trying to create a SILO structure on one of my WordPress site.

I have always checked this option on Yoast SEO plugin “Strip the category base (usually /category/) from the category URL.”

Read More

So my category pages have this URL: sitename.com/apple/ (where “apple” is the category page)

Now I want to create a new “page” with the same slug, apple.

I can create a new “apple” page easily, however, when I go to sitename.com/apple/ the category page is displayed — instead of the newly created page.

My question: Is there a way to “override” the default priority of category over a page? I’d like to show page because I will have control over it — I can customize, add more content, and change them easily (plus, pages are going to help me structure my site better)

Appreciate your help!

Related posts

7 comments

  1. One possible solution is to not change the category base and leave as-is, but instead modify any output of a category link to strip the category base via a filter. This of course will result in a 404 if you haven’t created a page in place of where these links point, so creating a page for every category is required.

    function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
        if( 'category' != $taxonomy ) return $termlink;
    
        return str_replace( '/category', '', $termlink );
    }
    add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );
    

    You’ll probably want to test this thoroughly for any side-effects, use at your own risk!

    EDIT – altering just top level category links:

    function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
        if( 'category' == $taxonomy && 0 == $term->parent ){
            return str_replace( '/category', '', $termlink );
        }
        return $termlink;
    }
    add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );
    
  2. I created the following, fairly simple function in order to make the pages a higher importance than categories when loading the content.

    (Note: this may not the best, but a simple way. I found an issue, when using the Advanced Custom Fields plugin, it doesn’t insert the custom fields neither of the old, nor of the new page by default. Adding get_queried_object()->ID as the ACF get_field()‘s second parameter solved this. Test it carefully in your WP environment.)

    function loadPageFirst() {
        // get the actual category
        $actualCategory = get_category( get_query_var('cat') );
        // get the page with the same slug
        $matchingPage = get_page_by_path( $actualCategory->slug );
    
        // If no match, load the normal listing template and exit (edit if you are using a custom listing template, eg. category.php)
        if (!$matchingPage) {
            include( get_template_directory() . '/archive.php');
            die();
        }
    
        // Make a new query with the page's ID and load the page template
        query_posts( 'page_id=' . $matchingPage->ID );
        include( get_template_directory() . '/page.php');
        die();
    }
    add_filter( 'category_template', 'loadPageFirst' );
    

    You can include it in your theme’s functions.php. This looks to work OK with the Yoast SEO plugin.

  3. There is a super simple and perfectly working answer here:
    https://stackoverflow.com/questions/32310453/make-wordpress-use-the-page-instead-of-category

    For the sack of completeness:

    Background

    • example.com is the domain
    • I have a WP page called “foobar” with content
    • I have a WP post category called “foobar”
    • I have a WP post entitled “fun things to do with foobars”, and the
      category is set to “foobar”

    Expectations

    • When I go to example.com/foobar, I want to see the page about
      foobars, not a WP category page that shows all blog posts with that
      category.
    • When I go to the blog post about fun things, the URL is
      example.com/foobar/fun-things-to-do-with-foobars/

    Setup

    Here’s my setup (it does not require any additional plugins or code edits) A couple of installed plugins are WP Rocket and Yoast on which I’ll focus in this thread.

    1. WP Dashboard->Settings->Permalinks

    2. Select “Custom Structure” and enter /%category%/%postname%/ in the field

    3. On the same page, change “Category base” to a single dot. “.” (no quotes, just a single dot/period/full stop

    I have Yoast installed, which I had set up to override the permalink settings, but I believe this messed up my task at hand.

    1. WP Dashboard->SEO->Advanced->Permalinks(tab)

    2. “Change URLs->Strip the category base…” = Keep

    3. Then you need to clear the cache. I use WP Rocket for caching, so I flushed the cache and everything now works the way it should.

    Edit: make sure you save your changes after steps 3 and 5

  4. Depends. If you’re trying to set 2 different page with the same URL it’s not a good idea. But if you do not care about category pages you can redirect them to your pages.

     RedirectMatch 301 ^/category/(.*)$ /$1
    

    This code goes in .htaccess and redirect /category/page to /page/

  5. The “WordPress way” to do this would be to create a custom php template for your category page, and apply your customizations there, rather than by creating a unique “Page.”

    There are also numerous plugins available that allow you to add images and other custom fields to the category archive page, which may be a better option if you would rather not modify theme files.

    Alternatively, I’d suggest adding a category base that is perhaps one of your primary target keywords

  6. First strip the category in yoast
    No-index the category in yoast but before doing that the permalink structure should be set as
    /%category%/%postname%/

  7. Sorry but y don’t have enought reputation for comment in @bencergazda answer.

    I find this the best solution. But i had a error with the image show in header theme, because don´t get the correct post-id.

    For solution i’ll add the text line in the code:
    “global $post; $post->ID = $matchingPage->ID;”

    The result

    function loadPageFirst() {
        // get the actual category
        $actualCategory = get_category( get_query_var('cat') );
        // get the page with the same slug
        $matchingPage = get_page_by_path( $actualCategory->slug );
    
        // If no match, load the normal listing template and exit (edit if you are using a custom listing template, eg. category.php)
        if (!$matchingPage) {
            include( get_template_directory() . '/archive.php');
            die();
        }
    
        // Make a new query with the page's ID and load the page template
        global $post; $post->ID = $matchingPage->ID;
        query_posts( 'page_id=' . $matchingPage->ID );
        include( get_template_directory() . '/page.php');
        die();
    }
    add_filter( 'category_template', 'loadPageFirst' );
    

    Best regards

Comments are closed.