How do you create an archive for a custom post type from a plugin?

Include your template files in your plugin. I stick mine in /plugin/templates.

You need to hook into template location for that template:

add_filter('archive_template', 'yourplugin_get_custom_archive_template');

function yourplugin_get_custom_archive_template($template) {
    global $wp_query;
    if (is_post_type_archive('yourCPT')) {
        $templates[] = 'archive-yourCPT.php';
        $template = yourplugin_locate_plugin_template($templates);
    }
    return $template;
}

Rinse and repeat with the appropriate checks for each template you want to implement (single, taxonomy etc).

function yourplugin_locate_plugin_template($template_names, $load = false, $require_once = true ) {
    if (!is_array($template_names)) {
        return '';
    }
    $located = '';  
    $this_plugin_dir = WP_PLUGIN_DIR . "https://wordpress.stackexchange.com/" . str_replace( basename(__FILE__), "", plugin_basename(__FILE__));
    foreach ( $template_names as $template_name ) {
        if ( !$template_name )
            continue;
        if ( file_exists(STYLESHEETPATH . "https://wordpress.stackexchange.com/" . $template_name)) {
            $located = STYLESHEETPATH . "https://wordpress.stackexchange.com/" . $template_name;
            break;
        } elseif ( file_exists(TEMPLATEPATH . "https://wordpress.stackexchange.com/" . $template_name) ) {
            $located = TEMPLATEPATH . "https://wordpress.stackexchange.com/" . $template_name;
            break;
        } elseif ( file_exists( $this_plugin_dir . '/templates/' . $template_name) ) {
            $located =  $this_plugin_dir . '/templates/' . $template_name;
            break;
        }
    }
    if ( $load && $located != '' ) {
        load_template( $located, $require_once );
    }
    return $located;
}

Doing it this way means that WP will look in the theme first for your templates, but will fall back to the plugin’s templates folder if not found in your theme. If users want to modify the templates to fit their theme, they can simply copy them to their theme’s folder.

If you want to be really clever about it, you can force a check for the templates in their theme folder and load some default styles if they’re using the plugin’s copy of the templates:

add_action('switch_theme', 'yourplugin_theme_check');
add_action('wp_enqueue_scripts', 'yourplugin_css');


function yourplugin_css() {
    if(get_option('yourplugin-own-theme') != true && !is_admin()) {
    wp_enqueue_style('yourplugin-styles', plugins_url('/css/yourplugin.css', __FILE__));
    }
}

function yourplugin_theme_check() {
    if(locate_template('archive-yourCPT.php') != '' && locate_template('single-yourCPT.php') != '' && locate_template('taxonomy-yourTaxonomy.php') != '' && locate_template('taxonomy-anotherTaxonomy.php') != '') {
    update_option('yourplugin-own-theme', true);
     }   
     else {
     update_option('yourplugin-own-theme', false);
     }
}

Leave a Comment