0

SOLVED

See my answer below; I cannot immediately accept it.


Original post

I made a custom post type of sector:

register_post_type( 'sector',
  array(
    'labels' => array(
      'name' => __( 'Sectors' ),
      'singular_name' => __( 'Sector' )
    ),
    'public' => true,
    'has_archive' => false,
    'rewrite' => array('slug' => 'sector')
  )
);

I have a sector called "Hotels & Hospitality" which resides at site.com/sector/hotels-hospitality/. I have other sectors that reside at other URLs.

I also have a normal Page called "Sector" (which resides at site.com/sector/) and a subpage called "Hotels & Hospitality" whose URL is also site.com/sector/hotels-hospitality/.

At the moment, when I navigate to site.com/sector/hotels-hospitality/ it's the post-type page that shows. Can I make it so that the normal Page shows instead? This is a special landing page for this sector.

I tried this in the functions.php of my theme:

flush_rewrite_rules();
add_rewrite_rule(
  'sector/hotels-hospitality/',
  'index.php?page_id=1700', // 1700 = post_id of the Page
  'top'
);

No luck so far! I have also tried it without the 'top' param and this seemed to make no difference.

Related Info

After this I also edited the "Hotels & Hospitality" sector post type slug from site.com/sector/hotels-hospitality/ to site.com/sector/hotels (thinking that that way, at least I would be able to see the other page), but now when I go to site.com/sector/hotels-hospitality/, I am redirected to site.com/sector/hotels/ and I can't undo it! I tried resaving permalinks...

I then tried renaming the Page to site.com/sector/hotels-hospitality-page/ and this is now going to a 404.

I am using a fresh install of Version 4.7.3.

Update

@WebElaine helped me delete the redirect from site.com/sector/hotels-hospitality to site.com/sector/hotels by deleting the _wp_old_slug field in wppostmeta.

site.com/sector/hotels-hospitality-page/ is still going to a 404.

Going to site.com/index.php?page_id=1700 is redirecting to site.com/sector/hotels-hospitality-page, giving a 404.

I guess the problem is the site is searching for a sector post with a slug of hotels-hospitality-page and not finding one... it's not getting as far as to check the pages.

  • If you flush rewrite rules, they get regenerated, but you haven't added your rule yet, this looks like a problem with order. Solve issue 1 first, it may solve issue 2, but focus the question on issue 1, then ask a second question afterwards ( we have a 1 question per question rule here ) – Tom J Nowell Apr 7 '17 at 18:28
  • I was going to remove the Issue 2 text after I saw your comment, but I've realised now I'm in a situation where it seems I can't flush the rewrites to get rid of the URL redirects I've created under Issue 2, so I may not be able to tell if Issue 1 is resolved. I changed it to Related Info instead for now. – Sarah Apr 7 '17 at 18:28
  • The "related" issue is because WordPress automatically redirects from an old slug to a new slug. If you look in the database you'll find a _wp_old_slug field - delete the one that matches your post ID and that will remove that redirect. – WebElaine Apr 7 '17 at 18:45
  • 1
    First find your post ID of the page you're trying to show but haven't been able to view. You can do this by editing the page - the ID is in the address bar. Next, in the database, go to your wp_postmeta table and do a Search. For post_id paste in your post ID and for meta_key paste in _wp_old_slug. It may find one or more results. Delete those results and the redirect will be gone. Your browser may have the redirect cached so make sure to clear cache or open a Chrome Incognito window to test it after you have deleted the postmeta. – WebElaine Apr 7 '17 at 18:54
  • 1
    @Sarah You did the right thing, but you did it back to front, you add your rule, then you flush out the old rules, not the other way around. Think of it as demolishing a building, rebuilding it, then telling the architect you want it to have a penthouse at the opening ceremony, having said that, flush_rewrite_rules is an expensive function, so use the permalinks page instead – Tom J Nowell Apr 8 '17 at 0:26
1

I installed Monkeyman Rewrite Analyzer https://wordpress.org/support/plugin/monkeyman-rewrite-analyzer/ which helped a great deal. I saw this referenced on Jan Fabry's detailed answer on this post which also helped me.

First thing that I found out with the plugin was that my rewrites weren't actually getting added; they didn't appear in the logic. It turns out the add_rewrite_rule() function is useless unless rewrites have just been flushed. I took out the flush_rewrite_rules(); line from my code but I flushed permalinks manually in the admin panel every time I tested a change.

Once I had renamed the custom post and page back to the same URL sectors/hotels-hospitality, I was able to resolve the issue. As @WebElaine explained in the comments, extra redirects are created if any _wp_old_slug fields are saved in the wp_postsmeta table, which helped me solve the related/secondary redirect issue after I edited the post slug.

This is my final function and it only works after flushing rewrites (clicking Save in Settings > Permalinks). I also used pagename instead of page_id in the query, but you can use either.

add_action( 'init', 'addMyRules' );
function addMyRules(){
    add_rewrite_rule('sector/hotels-hospitality','index.php?pagename=sector/hotels-hospitality','top');
}

The top parameter is important as it means this pattern to match will be checked before the system post-type check (check the order of rewrites when using the above mentioned plugin, screenshot below).

enter image description here

So, when I go to the matching URL, WordPress shows the page and not the post, because this is the first pattern match reached in the list.

|improve this answer|||||
0

The first thing I would try for the main issue is to delete the "sector" post called "Hotels & Hospitality." Then, go to your permalinks page (Settings > Permalinks) and save the rules as they are, which flushes your rewrite rules. In theory, if there is not a /sector/hotels-hospitality/ "sector" post, WordPress should check and find the Page you're looking for. You may want to use a Chrome Incognito window to make sure past redirects aren't making it seem like there's an issue where there actually isn't.

If that doesn't work, try using the CPT instead of a Page. Re-create the "sector" post called "Hotels & Hospitality". When you create the CPT "sector" add "supports => page-attributes" so that your CPT can use Page templates. That way, you can apply Page-like styling to the post, but you won't be confusing WordPress with what post type to display.

So change your CPT registration code to:

register_post_type( 'sector',
  array(
    'labels' => array(
      'name' => __( 'Sectors' ),
      'singular_name' => __( 'Sector' )
    ),
    'public' => true,
    'has_archive' => false,
    'rewrite' => array('slug' => 'sector'),
    'supports' => array('title', 'editor', 'thumbnail', 'revisions', 'page-attributes')
  )
);

Adjust title/editor/thumbnail/revisions as needed - it's "page-attributes" that enables you to choose a Page Template. Then just copy your Page content into the CPT, delete the Page, and you should be in business.

|improve this answer|||||
  • 1
    Thanks for your help. FYI the solution in your first para didn't work. Wordpress checks for a sector post named hotels-hospitality but if it doesn't find one, it shows a 404, it doesn't fallback to Pages. Your second solution seems like it would work (and is probably a more logical solution in this case, to be honest), but I found a solution that was more directly answering the question about add_rewrite_rule(). It is possible to sort the rewrites out, see my answer. – Sarah Apr 7 '17 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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