Slug for custom post type archive

I created a new custom post type ‘Projects’ and want the archive of all posts of this type to be available at mysite.com/projects. At the moment all project single posts are shown with a slug as follows mysite.com/projects/project-title, but when I go to mysite.com/projects I get a 404.

Here is how I built the custom post type:

   /* Create the Project Custom Post Type ------------------------------------------*/
 function create_post_type_project() 
 {
$labels = array(
    'name' => __( 'Projects' ),
    'singular_name' => __( 'Project' ),
    'add_new' => __('Add New'),
    'add_new_item' => __('Add New Project'),
    'edit_item' => __('Edit Project'),
    'new_item' => __('New Project'),
    'view_item' => __('View Project'),
    'search_items' => __('Search Project'),
    'not_found' =>  __('No project found'),
    'not_found_in_trash' => __('No project found in Trash'), 
    'parent_item_colon' => ''
  );

  $args = array(
    'labels' => $labels,
    'public' => true,
    'exclude_from_search' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'query_var' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => null,
    // Uncomment the following line to change the slug; 
    // You must also save your permalink structure to prevent 404 errors
    'rewrite' => array( 'slug' => 'projects' ),
    'has_archive' => true,
    'supports' => array('title','editor','thumbnail'),

  ); 

  register_post_type(__( 'project' ),$args);
    }

Related posts

Leave a Reply

2 comments

  1. Nothing appears to be incorrect – (and I assumed you’ve gone to saved your permalink structure to flush the rewrite rules as the comments suggest? 🙂 ).

    I would recommend using this plug-in to determine problems with your url-redirection: http://wordpress.org/extend/plugins/monkeyman-rewrite-analyzer/ – update your question with your findings and someone may be able to offer a solution

    However (but this probably isn’t the cause of your issue)., you should not translate the post type’s name, have:

    register_post_type('project',$args);
    

    instead of

    register_post_type(__( 'project' ),$args);
    

    Translations are for the benefit of the user – and so should be on labels only – the WordPress internal names shouldn’t depend on translation.

  2. The code you have pasted does not apear to be incorrect, however what you are asking for will also work using 'rewrite' => true

    http://codex.wordpress.org states:

    has_archive
    (boolean or string) (optional) Enables post type archives. Will use $post_type as archive slug by default.

    Default: false

    Note: Will generate the proper rewrite rules if rewrite is enabled. Also use rewrite to > change the slug used.

    A solution to your problem may be that the template for the custom post type isn’t working or has not been created, you can either try adding the following code to your functions.php or plugins function:

    function _post_type_template_smart(){
    
        global $post;
    
        $single_template_name = 'single-projects.php';
        $archive_template_name = 'archive-projects.php';
    
        if ( is_single() && 'projects' == get_post_type() ){
    
            $template = locate_template(array($single_template_name), true);
    
            if(empty($template)) {
    
              include(PLUGIN_DIR . 'template/' . $single_template_name);
    
              exit();
            }
    
        }else if( is_archive() && 'projects' == get_post_type() ){
    
            $template = locate_template(array($archive_template_name), true);
    
            if(empty($template)) {
    
              include(PLUGIN_DIR . 'template/' . $archive_template_name);
    
              exit();
            }
    
        }
    
    }
    add_filter('template_redirect', '_post_type_template_smart');
    

    and in your ‘single-projects.php’/’archive-projects.php’ pages, create a loop/query/get_pages (whichever you prefer) to bring in and display the content:

        $args = array(
            //'child_of' => 0,
            'sort_order' => 'ASC',
            'sort_column' => 'post_modified',
            'hierarchical' => 1,
            'parent' => 0,
            'post_type' => 'projects',
            'post_status' => 'publish'
        );
        $pages = get_pages( $args );
        foreach ( $pages as $project ){
            $project_id = $project->ID;
            $project_link = get_page_link($project->ID);
            $project_title = $project->post_title;
            $content = $project->post_content;
            $author = $project->post_author;
            $posted_on = $project->post_date;
    
            if(empty($content)){
                $content = 'There is no description for this package';
            }
            echo '<div class="content">';
            echo $content;
            echo '</div>';      
    
        }
    

    Hope this helps!