single-{post_type}.php is not loaded despite flushing rules

I have the following code to define my producto custom type post:

add_action('init', 'custom_post_producto');
function custom_post_producto() {
  $args = array(
    "label"               => 'Productos',
    "labels"              => $labels,
    "description"         => "Artículos a la venta dentro del sitio web.",
    "public"              => true,
    "publicly_queryable"  => false,
    "show_ui"             => true,
    "show_in_rest"        => false,
    "has_archive"         => false,
    "show_in_menu"        => true,
    "exclude_from_search" => true,
    "capability_type"     => "page",
    "map_meta_cap"        => true,
    "hierarchical"        => false,
    // "rewrite"          => array( "slug" => "producto", "with_front" => true ),
    "rewrite"             => true,
    "query_var"           => true,
    "menu_icon"           => "dashicons-products",        
    "supports"            => array( "title", "thumbnail" )
  );

  register_post_type("producto", $args);
  // flush_rewrite_rules();
}

And, as the question title poses, single-{post_type}.php is not being loaded and redirects to the site index.

Now, I’ve been for hours trying to track down this problem. I’ve tried flushing rewrite rules with flush_rewrite_rules() right after register_post_type(), changing (and even deleting) the rewrite attribute in the $args array, resaving the Permalink Settings, and even installing the Rewrite Rules Inspector plugin to check if everything is right and flushing the rewrite rules again and again, to no avail. I even reinstalled the whole site and entered new info, but the problem persists.

For the record, I’m working on localhost using XAMPP 5.6.19 on Windows 10, and working with WordPress 4.5.2.

Thanks in advance for your help.

1 Answer
1

Flushing the rewrite rules – which you can do just by visiting the Settings -> Permalinks page – was a good step to take, because it’s usually the overlooked cause of these sorts of issues.

However as Milo said in the comments, in this case, it’s just that the publicly_queryable argument needs to be true if you want these posts to display on the frontend.

From the docs for register_post_type():

public
(boolean) (optional) Controls how the type is visible to authors (show_in_nav_menus, show_ui) and readers (exclude_from_search, publicly_queryable).
Default: false

publicly_queryable
(boolean) (optional) Whether queries can be performed on the front end as part of parse_request().
Default: value of public argument

As you can see – and again as Milo said – just avoiding setting publicly_queryable will make things a bit simpler for you in this case.

I would definitely recommend reading up on those docs to understand what each of the attributes do, but I realise it can be difficult to get your head around at first!

As for your second question in the comments:

Does public affect if the template is shown? And has_archive or rewrite?

  • public is a quick override to generally control all of the backend and frontend visibility of your post type in one go: unless you override it with any of the four more explicit options as seen above. For the frontend, these are publicly_queryable, as we have already addressed, and exclude_from_search. You’ve already set exclude_from_search to true, so no matter what you set for public, this post type won’t be found in searches (OR taxonomy term lists).

  • has_archive won’t affect whether your single post types can be viewed, but it will turn on and off the option to view the archive ‘loop’ of all of your posts – at http://example.com/your_rewrite_slug

  • rewrite doesn’t affect public visibility of your posts; just what the URL will be. The URL has to be something though, so if you don’t set the rewrite value, it’ll just default to your post_type name – in this case ‘producto’

Each of these are also covered in the docs, so I’ll mention again – definitely read up on it. The investment will be worth it! 🙂

Leave a Comment