Freddy
Freddy

Reputation: 867

How to disable page create for custom post type, but allow a page with the post types slug to be created?

I have a custom post type called integrations, which I have registered like this:

register_post_type(
  'Integrations',
  theme_build_post_args(
    // $slug, $singular, $plural
    'integrations', 'Integration', 'Integrations',
    array(
      'menu_position' => 20,
      'has_archive'     => true,
      'public'          => false,
      'publicly_queryable'  => false,
      'rewrite'   => array( 'slug' => false, 'with_front' => false ),
      'supports'            => array('title', 'revisions'),
      'taxonomies'      => array('categories'),
    )
  )
);

I don't want a page to be created upon registered the above post type, as I'm looking to create a page that sits on /integrations which will be much more customised. Also, I have subpages which sit under this page, so I'm looking for it to become a page so I can assign it as the parent to child pages. As such, I have added 'publicly_queryable' => false to the above.

Now, I have created a page called Integrations which sits on /integrations, but upon accessing it, it redirects to the homepage.

I'm certain this is because of 'publicly_queryable' => false, but, removing it would not solve my issue as the slug will exist as the post type is registered.

Is there a way around this?

Edit:

  1. Created template_redirect in functions.php:

function custom_integrations_template() {
  if (is_page('integrations')) {
    get_template_part('page', 'integrations');
    exit();
  }
}

add_action('template_redirect', 'custom_integrations_template');

  1. Created page-integrations.php and added a template name:

<?php

/*
* The template for displaying search results pages
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/#search-result
* Template Name: Integrations
*/

get_header(); ?>

<?php while ( have_posts() ) : the_post(); ?>
  <?php the_content(); ?>
<?php endwhile; ?>

<?php get_footer(); ?>

  1. Removed 'publicly_queryable' => false from my post type

  2. Assigned the Integrations template to my Integrations page.

  3. Added content to the Integrations page and updated

  4. Flushed permalinks

  5. Viewed /integrations and it doesn't show the content added in step 4?

It seems like it is still showing the page created when registering a post type, as my content on the page isn't showing?

Upvotes: 1

Views: 607

Answers (1)

zanderwar
zanderwar

Reputation: 3730

Remove 'publicly_queryable' => false. This tells wordpress to not let anyone access the page.

Try with a template_include action, and detect if the page slug is integrations:

function custom_integrations_template($template) 
{
    if (is_page('integrations')) {
        $newTemplate = locate_template(['page-integrations.php']);

        if (! $newTemplate) {
           return new WP_Error('broken', 'Integrations template not found');
        }

        return $newTemplate;
    }

    return $template;
}

add_filter('template_include', 'custom_integrations_template', 99);

This will look for a page-integrations.php file in your theme directory when someone access /integrations.

You don't have to use locate_template, you can include the full path to your template: __DIR__.'/path/to/your/template.php'

Upvotes: 1

Related Questions