32

I have a custom post type called "visningshus", and also a Page with that slug. This is as it should (must) be.

Currently, "http://my-site.com/visningshus" lists all posts of that type. I want to show the page that has that permalink slug instead.

How can I make Wordpress not make the post type name take precedence, but instead the permalink, and show the Page?

0

8 Answers 8

51
+50

The easiest would be to just disable the archive page for this CPT:

register_post_type( 'visningshus',
    array(
        [...]
        'has_archive' => false,
        [...]
    )
);

Don't forget to refresh you permalinks afterwards at "Settings > Permalinks"

3
  • 1
    Worked perfectly - but now all permalinks starting with the custom post type's name give a 404, despite that they're correct in wp-admin and there seems no rewrite taking place. That is to say, all permalinks are correct on the site, but all custom posts give a 404. Can you help with that? :) Mar 11, 2014 at 15:44
  • @HenrikErlandsson Maybe your post type have the same name of the page. In this case I recommend you to change your post type name. Example: Custom post type name - Before: products After: cpt_products. Apr 6, 2016 at 17:08
  • Very intelligent. Solves a bunch of problems
    – bysanchy
    Apr 9, 2017 at 15:08
12

I'm not high enough reputation to comment on @Carl's post, but his is the correct answer (at least to this situation of keeping the page slug and custom post type slug the same and not using an archive.php file)

But his answer would give errors with pagination. To avoid pagination errors:

add_rewrite_rule('^visningshus/page/([0-9]+)','index.php?pagename=visningshus&paged=$matches[1]', 'top');

This looks at the pagination, grabs the page number, and then on the flip side forces it to use the page with the matching slug, and then inserts the page variable.

This in addition to 'has_archive' => false, posted above should achieve the desired functionality.

As others stated, be sure to flush the rewrite rules by visiting Settings > Permalinks after making this change.

Hope this helps someone, because I know this stumped me for a really long time.

5

Tjena Henrik!

I think all you need to do is to add a rewrite rule to the Wordpress Rewrite rules that have already been created. Add this code snippet to your functions.php of your theme or include it as a separate pugin...

add_action('init', function () {
     add_rewrite_rule('visningshus/?$','index.php?pagename=visningshus', 'top');
     flush_rewrite_rules();
}, 1000);
3
  • 6
    If anyone uses this, remove flush_rewrite_rules(); You shouldn't change the rewrite rules on init every time. Reload once then remove it, or manually flush permalinks by going to the permalink settings in admin dashboard and click "Save Changes"
    – tehlivi
    Jun 14, 2017 at 18:10
  • Out of all the answers here, this one worked for me !!! Tysm. Jun 11, 2020 at 16:12
  • RE: flush_rewrite_rules() - it's really not a great idea to use this function in an init hook - or any other hook that runs frequently. This will make your WordPress installation flush the rewrite rules from the database and insert them again for every single page load which is a suuuuper unnecessary overhead, which is why WordPress does not do it itself. After creating the rewrite rule, just go to Settings > Permalinks and click save - this will manually flush the rewrite rules a single time, which is all that is necessary.
    – bosco
    Jun 12, 2021 at 2:36
4

If you registered the post type yourself, you can change the archive status and URL in your theme or plugin.

'has_archive' => true, enables the archive in post-type-permalink. so change that to

'has_archive' => false, will disable the archive.

'has_archive' => 'custom-slug', will enable the archive in custom slug(http://my-site.com/custom-slug/).

If a plugin or your theme register it, you can disable it with the way krafter did. You can also use custom slug for the archive.

register_post_type( 'visningshus',
    array(
        [...]
        'has_archive' => 'custom-slug', 
        [...]
    )
);

If you need both the page and the archive the best way would be to put the archive in a different custom slug.

0

I solved it without solving the conflict. Create a page with slug visningshus and write whatever you want in it. Take note on the ID of this page.

Create and customize the archive-custom-post-type.php template in whatever way you like (most likely you will just use a page template) but replace the loop part with

$recent = new WP_Query("page_id=your-page-id");  
while($recent->have_posts()) : $recent->the_post();
    the_content();
endwhile;

Then when you'll go to http://my-site.com/visningshus youll see the content managed by the page at the correct url.

Let me know it it works.

4
  • Nice idea, but this is overly complicated. Did you try my solution?
    – kraftner
    Feb 19, 2014 at 10:32
  • @kraftner no, I didn't. I'll give it a try next time. Thanks!
    – molokom
    Feb 19, 2014 at 10:55
  • This also has some side effects like the header and everything still being created as if it was an archive page and not a page. I wouldn't advise on using that solution.
    – kraftner
    Feb 19, 2014 at 11:00
  • What if page ID changes? This is not safe.
    – Joel James
    Feb 6, 2017 at 7:19
0

Not allowed to vote, but + for Carls solution, register_post_type should have

'has_archive' => false

Simple. However, when you face pagination problems, take a look at

add_rewrite_rule
0

What Fixed it for me was setting archive as false but also Setting the Hierarchical to false when setting up my custom post type!

0

Here is a general solution to prioritize pagination over custom post types content for ANY custom post type slug.

// prioritize pagination over displaying custom post type content
add_action('init', function() {
  add_rewrite_rule(
    '(.?.+?)/page/?([0-9]{1,})/?$',
    'index.php?pagename=$matches[1]&paged=$matches[2]',
    'top'
  );
});

Besides adding this snippet, you should also make sure that your custom post type has archive = false

and last but not least go to the Permalinks settings page Settings > Permalinks (/wp/wp-admin/options-permalink.php) and save current settings to refresh links structure on the page.

Your Answer

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

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