1

I wrote plugin which uses Custom Post Types to create a series of pages. I have the code which adds the CPT to the "Reading" dropdown menu and it works great.

Here it is...

add_filter( 'get_pages',  'add_wpwebinar_front' );
function add_wpwebinar_front( $pages ) {
     $my_wpwebinar_pages = new WP_Query( array( 'post_type' => 'wpwebinar' ) );
     if ( $my_wpwebinar_pages->post_count > 0 ) {
         $pages = array_merge( $pages, $my_wpwebinar_pages->posts );
     }
     return $pages;
}

The code works but if you select a Custom Post Type as the home page it redirects to the CPT actual page. Example... domain.com would redirect to domain.com/slug/pagename

In order to fix this, I found this code which I added...

function enable_front_page_stacks( $query ){
global $post, $wp_query;
   if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->set('post_type', 'wpwebinar');
}
add_action( 'pre_get_posts', 'enable_front_page_stacks' );

This keeps the Custom Post Type as the main page. But... I have a few issues.

  1. If you select the default of show latest posts IT'S OK.
  2. If you select a Custom Post Type page as the front page IT'S OK.

The problem is when you select a normal PAGE as the frontpage. It inherits the Custom Post Type template and does not show the page content of course, because there's not code there for it.

I'm sure the fix is simple, but I have no idea what to change.

Ideas anyone? It would be greatly appreciated.

2
  • In your CPT settings you'll probably see something similar to this: 'rewrite' => array( 'with_front' => true, 'pages' => true, 'feeds' => true, 'slug' => 'post_type', ), If you try changing 'with_front' to false and 'slug' as well are you getting the same issues?
    – David
    Apr 11, 2012 at 22:39
  • David, yes I still get the same result. Although, I'm not sure what you meant bby changing 'slug'
    – Armand
    Apr 11, 2012 at 23:31

1 Answer 1

2

The error is in the code you added:

function enable_front_page_stacks( $query ){
    global $post, $wp_query;
    if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->set('post_type', 'wpwebinar');
}

Specifically $query->set(). This call will specifically set the post type to "wpwebinar" if it's not explicitly set to anything else. As a result, just hitting a regular page will force it to assume "wpwebinar" and load the custom post type template.

Instead, change your function to this:

function enable_front_page_stacks( $query ){
    if(( ! isset($query->query_vars['post_type']) || '' == $query->query_vars['post_type']) && 0 != $query->query_vars['page_id'])
        $query->query_vars['post_type'] = array( 'page', 'wpwebinar' );
}

This was the original enable_front_page_stacks() function I wrote, but using "wpwebinar" instead of "stack" as the additional custom post type.


Referencing a Template File from a Plugin

Usually, the best guidelines I can give include registering a CPT with a plugin and leaving the CPT templates up to the theme. This typically works better with styling and allows the end user complete control over the site design. However, there are rare situations were it makes sense to specify the CPT template in the plugin itself.

To take care of this, you need to hook in to the get_single_template() function in core to tell it where to get the file. Here's the typical request pattern:

template-loader.php
--> if ( is_single() ) $template = get_single_template()

-- --> template.php -> get_single_template()
-- -- --> $templates[] = array( 'single.php', 'single-{post_type}.php' );
-- -- --> return get_query_template( 'single', $templates )

-- -- -- --> template.php -> get_query_template( $type, $templates )
-- -- -- -- --> if ( empty($templates) ) $templates = array( '{$type}.php' );
-- -- -- -- --> return apply_filters( "{$type}_template", locate_template( $templates ) )

In order to register your plugin-hosted CPT template, you need to hook on to this filter and specify its location.

function load_plugin_cpt_template( $path ) {
    $path = dirname(__FILE__) . '/single-wpwebinar.php';

    return $path;
}
add_filter( 'wpwebinar_template', 'load_plugin_cpt_template' );

I use dirname( __FILE__ ) above based on the assumption that your CPT template is at the same level as the file with this function. If not, adjust the include path accordingly. Note that this function will absolutely override any single-wpwebinar.php specified by the theme.

As a safeguard, you can check the passed-in value of $path to see if we're using single.php or a theme-specified override, but that's an exercise I leave to you.

There is also a more complete tutorial posted on my site: http://jumping-duck.com/tutorial/theme-ready-custom-post-types-in-wordpress/.

7
  • EAMann, I tried that but the problem would be the revers, meaning the CPT page now is using the standard page template and NOT the CPT template. So you end up with a page with basically the title. That's why I used a mofidified version of your orginal code using $query->set. By using $query->set, the page uses the CPT template, but the an actual page set in "Reading" takes on the CPT template. See my point?
    – Armand
    Apr 11, 2012 at 23:30
  • I'd need to see what your templates look like, because your CPT should use single-wpwebinar.php as a template if you're using the same code.
    – EAMann
    Apr 11, 2012 at 23:41
  • I'm using 'template_redirect' to change the location of the single-wpwebinar.php page. Maybe that has a bearing on this. So the problem is that the CPT page is not implementing the CPT template I created. I've tried moving the single-wp-webinar.php into the them root to test and removing the template-redirect, but I still get the same results. The CPT still inherits the normal page template.
    – Armand
    Apr 12, 2012 at 11:17
  • If your CPT is registered as wpwebinar you must use the single-wpwebinar.php template in the theme. single-wp-webinar.php won't work. And if you're overriding the theme with a plugin, I'd argue that you're doing something wrong ... but that's a longer discussion. An easier route here would be to build out your CPT, build a CPT template page, then register a shortcode that can be used on a standard page to display your CPT.
    – EAMann
    Apr 12, 2012 at 13:35
  • The single-wp-webinar.php was typo. I am using the single-wpwebinar.php. The whole point is the that the CPT IS A PLUGIN. So the single-wpwebinar.php is in the plugins folder, that's why I use template_redirect to get the correct location of the template.
    – Armand
    Apr 12, 2012 at 13:42

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.