1

In my plugin I think that I use pretty much standard and documented way to add my custom post type and two tax (cats and tags), but only thing that I do is set custom capability_type and perms.

Here is code:

// =============================
// custom taxonomies (cats and tags)
// =============================
function custom_taxonomy() {

    $labels = array(
        'name'                       => _x( 'ifcc Categories', 'Taxonomy General Name', 'text_domain' ),
        'singular_name'              => _x( 'ifcc Category', 'Taxonomy Singular Name', 'text_domain' ),
        'menu_name'                  => __( 'ifcc category', 'text_domain' ),
        'all_items'                  => __( 'All Items', 'text_domain' ),
        'parent_item'                => __( 'Parent Item', 'text_domain' ),
        'parent_item_colon'          => __( 'Parent Item:', 'text_domain' ),
        'new_item_name'              => __( 'New Item Name', 'text_domain' ),
        'add_new_item'               => __( 'Add New Item', 'text_domain' ),
        'edit_item'                  => __( 'Edit Item', 'text_domain' ),
        'update_item'                => __( 'Update Item', 'text_domain' ),
        'separate_items_with_commas' => __( 'Separate items with commas', 'text_domain' ),
        'search_items'               => __( 'Search Items', 'text_domain' ),
        'add_or_remove_items'        => __( 'Add or remove items', 'text_domain' ),
        'choose_from_most_used'      => __( 'Choose from the most used items', 'text_domain' ),
        'not_found'                  => __( 'Not Found', 'text_domain' ),
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'rewrite'                    => array( 'slug' => 'ifcc-categories' ),
        'query_var'                  => true
    );
    register_taxonomy( 'ifcc_cats', array( 'ifcc' ), $args );

    $labels = array(
        'name'                       => _x( 'Tags', 'Taxonomy General Name', 'text_domain' ),
        'singular_name'              => _x( 'Tag', 'Taxonomy Singular Name', 'text_domain' ),
        'menu_name'                  => __( 'Tag', 'text_domain' ),
        'all_items'                  => __( 'All Items', 'text_domain' ),
        'parent_item'                => __( 'Parent Item', 'text_domain' ),
        'parent_item_colon'          => __( 'Parent Item:', 'text_domain' ),
        'new_item_name'              => __( 'New Item Name', 'text_domain' ),
        'add_new_item'               => __( 'Add New Item', 'text_domain' ),
        'edit_item'                  => __( 'Edit Item', 'text_domain' ),
        'update_item'                => __( 'Update Item', 'text_domain' ),
        'separate_items_with_commas' => __( 'Separate items with commas', 'text_domain' ),
        'search_items'               => __( 'Search Items', 'text_domain' ),
        'add_or_remove_items'        => __( 'Add or remove items', 'text_domain' ),
        'choose_from_most_used'      => __( 'Choose from the most used items', 'text_domain' ),
        'not_found'                  => __( 'Not Found', 'text_domain' ),
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => false,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'query_var'                  => true
    );
    register_taxonomy( 'ifcc_tags', array( 'ifcc' ), $args );

}
add_action( 'init', 'custom_taxonomy', 20 );

// =============================
// register ifcc custom post type for new tax up
// =============================
function custom_post_type() {
    global $woo_contest;

    $labels = array(
        'name'                => _x( 'IFCC Submits', 'Post Type General Name', 'text_domain' ),
        'singular_name'       => _x( 'IFCC Submit', 'Post Type Singular Name', 'text_domain' ),
        'menu_name'           => __( 'IFCC Submit', 'text_domain' ),
        'parent_item_colon'   => __( 'Parent Item:', 'text_domain' ),
        'all_items'           => __( 'All Items', 'text_domain' ),
        'view_item'           => __( 'View Item', 'text_domain' ),
        'add_new_item'        => __( 'Add New Item', 'text_domain' ),
        'add_new'             => __( 'Add New', 'text_domain' ),
        'edit_item'           => __( 'Edit Item', 'text_domain' ),
        'update_item'         => __( 'Update Item', 'text_domain' ),
        'search_items'        => __( 'Search Item', 'text_domain' ),
        'not_found'           => __( 'Not found', 'text_domain' ),
        'not_found_in_trash'  => __( 'Not found in Trash', 'text_domain' ),
    );
    $args = array(
        'label'               => __( 'post_type', 'text_domain' ),
        'description'         => __( 'ifcc submit', 'text_domain' ),
        'labels'              => $labels,
        'supports'            => array( 'title', 'editor', 'revisions', 'custom-fields', 'post-formats', 'author', 'thumbnail' ),
        'taxonomies'          => array( 'ifcc_cats', 'ifcc_tags' ),
        'hierarchical'        => false,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'show_in_nav_menus'   => true,
        'show_in_admin_bar'   => true,
        'menu_position'       => 20,
        'can_export'          => true,
        'has_archive'         => true,
        'exclude_from_search' => true,
        'publicly_queryable'  => true,
        'capability_type'     => 'ifcc',
    'capabilities'        => array( 'read_ifcc', 'edit_ifcc', 'delete_ifcc' ),
    'map_meta_cap'        => true
    );
    register_post_type( 'ifcc', $args );

    register_taxonomy_for_object_type( 'ifcc_cats', 'ifcc' );
    register_taxonomy_for_object_type( 'ifcc_tags', 'ifcc' );
    // flush_rewrite_rules();

}

add_action( 'init', 'custom_post_type', 30 );

Then I add this to fix admin and customer ( real user for that cpt, but for frontend tasks only, to upload picture and submit forms to backend, save posts )

// =============================
// fix admin and woo user perms
// =============================
function ifccperms(){
    $role = get_role('administrator');
    $role->add_cap( 'edit_ifcc' );
    $role->add_cap( 'read_ifcc' );
    $role->add_cap( 'delete_ifcc' );
    $role->add_cap( 'delete_ifccs' );
    $role->add_cap( 'edit_ifccs' );
    $role->add_cap( 'edit_others_ifccs' );
    $role->add_cap( 'publish_ifccs' );
    $role->add_cap( 'read_private_ifccs' );
    $role->add_cap( 'delete_private_ifccs' );
    $role->add_cap( 'delete_published_ifccs' );
    $role->add_cap( 'delete_others_ifccs' );
    $role->add_cap( 'edit_private_ifccs' );
    $role->add_cap( 'edit_published_ifccs' );    

    if( null == add_role( 'customer', 'customer' ) ){
        $role = get_role('customer');
        $role->add_cap( 'edit_ifcc' );
        $role->add_cap( 'edit_ifccs' );
        $role->add_cap( 'delete_ifcc' );
        $role->add_cap( 'delete_ifccs' );
        $role->add_cap( 'edit_published_ifccs' );    
        $role->add_cap( 'publish_ifccs' );
        $role->add_cap( 'read_ifcc' );
        $role->add_cap( 'upload_files' );            
    }

}
add_action( 'init', 'ifccperms', 40 );



// =============================
// dirty hack to alter sql query == do not know why does the query works wrongly?
// here I just alter one
// =============================

function checkq($a){
    return str_replace('product', 'ifcc', $a );
}
add_filter( 'posts_request', 'checkq' );

All is great, in backend I can see cpt, and tax, and each user can only see it's own posts, upload from frontend works great, etc.

But here comes question part. When I try to access taxonomy page from frontend

root/ifcc-categories/

the page goes to 'Page not found', 404 error.

I did hook in to inspect sql that holds the page and it echoes me this:

SELECT wp_posts.* 
FROM wp_posts 
WHERE 1=1 
AND wp_posts.post_name = 'ifcc-categories' 
AND wp_posts.post_type = 'post' 
ORDER BY wp_posts.post_date DESC

I'm puzzled with two things here. Why did wordpress think that is post_name and post type is post ?

One more thing, if I go to term url, for ex:

root/ifcc-categories/design/

I get this sql string:

SELECT ...  WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (7) ) 
AND wp_posts.post_type 
IN ('post', 'page', 'attachment', 'product') 
AND (wp_posts.post_status = 'publish' 
OR wp_posts.post_author = 1 
AND wp_posts.post_status = 'private')

If there is anyone that have any clue about what's going on here I'd be glad to hear it, 'cause I'm in lost

3
  • You should post your code directly in your question. I know you say it is to long, but you need not post code that is not relevant. remove what is not needed. Even if the code is still long, paste your code still inside your question :-) Dec 22, 2014 at 4:20
  • root/ifcc-categories/ returning 404 is expected, taxonomy archives are for individual terms, there is no taxonomy-wide archive for all terms.
    – Milo
    Dec 22, 2014 at 5:03
  • This is note to myself and anyone who gets lost like me,, this case of 404 that I had is I guess expected, but I didn't know that this url structure: root/ifcc/?ifcc_cats=3d works perfectly ok! I adapted the links structure in sidebar to that format, rather than to run additional query with new WP_Query() after main query loop. I guess if we tend to optimize our apps, it is best to run only one query, right? :) Dec 30, 2014 at 10:16

1 Answer 1

1

The first section of this question have been answered before. Basically, there are no index pages for archives, and there never will be. For a complete explanation, feel free to check this post I have recently done on this subject.

Why did wordpress think that is post_name and post type is post?

You might or might not know this, but Wordpress uses WP_Query to run the main query, the only difference with a new instance of WP_Query is is that with a new instance the argument values are set by the user while the main query uses the URL to set this arguments and values

OK, so what really happens here? When any link is clicked or any URL is typed into the address bar, Wordpress executes the main query. The arguments and values passed to WP_Query is determined by the URL. Wordpress parses the URL, match rewrite rules and breaks the URL up into values that is passed as query arguments.

If you have /%postname%/ set as your permalink structure, the URL of a post looks like this

mysite.com/name-of-my-post/

So, if you directly enters the taxonomy name into the URL, it looks like this

mysite.com/ifcc-categories/

As you can see, these two URL's are exactly the same structure, and that is how Wordpress reads it. You have to remember, the main query uses rewrite rules to match the URL against, and in this example, it matches normal posts. This is why you see the SQL query in your question

The main query defaults to post post type on all pages accept on custom post type archive pages, normal pages (in which case the post type will be page) and taxonomy pages.

Because you don't have a post (or page for that matter) that has the name ifcc-categories, a 404 is returned. The main query is never stopped if something is not found, even if invalid values are set to start with to the arguments (which in any case the main query will not know), it simply carries on executing and finishes what it started of, even on 404 pages. It is like dropping a ball. That ball can't decide to stop mid-air because there is no one to catch it. It can only stop when its finished falling

TO CONCLUDE

If you need to have an index page for a specific term, category or taxonomy, you will need to create a page with the desired custom query and name your slug accordingly, so that if you visit

mysite.com/ifcc-categories

you will be served with the index page you've created

2
  • Firstly, thank you very much for this very long and thoroughly writen answer, I haven't had much hope to get that kind of replay here, this is most pleasing... I will need some time to process all this, but this last part you said to create a page with custom query, how hard that part is, can I do it from plugin or have to create templete file inside theme directly? thanks Dec 22, 2014 at 12:51
  • To be honest, I believe, either do a proper answer or rather just leave it, never give half written info :-). That should be quite easy. Have a look at the WP_Query docs, also get_terms. You always have an opportunity to post a new question if you get stuck on this part. As for where that page should go, my personal opinion, in a theme, preferably a child theme if you are not the author of the parent theme. You can add that page in a plugin, nothing wrong with that. I just believe that templates are theme territory, not plugin Dec 22, 2014 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.