4

I'm trying to create a plugin which adds a new custom post type and it should be shown at the same locations as a normal post (front page, archives etc.).

Is there any functions for me to retrieve the post types which are currently being called in the query so that I can modify and add my CPT to the current query? (example stated in 2nd comment if my question sounds confusing)

I can't use the code below (i.e. list the post types) because I can't predict what post types would the user have :

add_filter( 'pre_get_posts', 'my_get_posts' );

function my_get_posts( $query ) {

if ( is_home() && $query->is_main_query() )
    $query->set( 'post_type', array( 'post', 'page', 'album', 'movie', 'quote' ) );

return $query;
}

Similarly, I can't use the code below because that would return all post types, including those which might not be intended to be shown at the front page :

if ( !is_admin() && empty( $query->query_vars['suppress_filters'] ) && $query->is_main_query() ) {
    $post_type = get_query_var('post_type');
    $post_types = get_post_types( array( 'public' => true ) );

    if ($post_type) {
        $post_type = $post_type;
    } else {
        $post_type = $post_types;
    }

    $query->set('post_type',$post_type);
    return $query;
    }
}

So, is there any ideas how I can add my CPT to the query without affecting other post types? Thanks for helping!

4
  • I think you are misunderstanding the situation or I'm not understanding you. You have said: " ... to retrieve the post types which are currently being called in the query so that I can add this CPT to the query ...". If they are currently called in the query .... why you want to include them again??? Please, explain better the situation and the problem.
    – cybmeta
    Dec 24, 2014 at 9:42
  • For example, that query might be retrieving content from 'post' and 'page'. I would like those to remain but add my CPT to it, such that it's now getting content from 'post', 'page' and 'my-CPT'. Both the approaches above can't seem to work this way, with the second approach also including other post types. Does this make things clearer?
    – Billy
    Dec 24, 2014 at 10:08
  • No, it is not clear. You said "retrieve the post types which are currently being called in the query" but it seems that they are not included and you want to include them. I don't understand why the code in your answer doesn't work. It seems that you want to include custom post types but you don't know what custom post types to include. Am I right? If you don't know what custom post types want to include, how do you expect we can know it? You will have to describe the situation more deeply. Fore example, where the CPT come from, how they are selected to be included and so on.
    – cybmeta
    Dec 24, 2014 at 10:48
  • Well, it's a plugin which will be used by others who might have other CPTs being used concurrently, so I can't hard-code the post types to be retrieved (i.e. first approach won't work in this case). The code above will only work if I know all the post types required. I thought maybe there's a way to get all the post types in the current query and add my CPT to the array. Hence, in situations like this, what would be the best way to make my CPT show along with contents from other post types? @David's understanding of my question is correct.
    – Billy
    Dec 24, 2014 at 11:25

1 Answer 1

5

You are actually not that far away with pre_get_posts, you just need to first grab the current post types that are in the query before adding your own.

Also, I'd recommend using a $priority of 99 so that the action is hooked after any other pre_get_posts hooks, meaning that if users add there own CPT's (or built in post types) they are detected and included by the function below (but you can change that as required).

add_action('pre_get_posts', 'djg_includ_my_cpt_in_query', 99);
function djg_includ_my_cpt_in_query($query){

    if(is_home() && $query->is_main_query()) :              // Ensure you only alter your desired query

        $post_types = $query->get('post_type');             // Get the currnet post types in the query

        if(!is_array($post_types) && !empty($post_types))   // Check that the current posts types are stored as an array
            $post_types = explode(',', $post_types);

        if(empty($post_types))                              // If there are no post types defined, be sure to include posts so that they are not ignored
            $post_types[] = 'post';         
        $post_types[] = 'document';                         // Add your custom post type

        $post_types = array_map('trim', $post_types);       // Trim every element, just in case
        $post_types = array_filter($post_types);            // Remove any empty elements, just in case

        $query->set('post_type', $post_types);              // Add the updated list of post types to your query

    endif; 

    return $query;

}

EDIT

When constructing the final query, WordPress checks to see if 'post_type' is empty, and if so the following code is executed -

$where .= " AND $wpdb->posts.post_type = 'post'";
$post_type_object = get_post_type_object ( 'post' );

So what happens when we add a CPT is that WordPress assuems we want to ignore posts as it is not explicitly declared. That is were my scenario differed - I had explicitly declared other post types previously so they were included in the call $post_types = $query->get('post_type');.

So, in your case we can resonably summise that if $post_types is empty, the user does not wish to amend that portion of the query so 'post' can be manually added to the $post_types array. This should (hopefully!) do the trick.

13
  • Note that the OP doesn't know what custom post types should added to $post_types[]. That is the question asked.
    – cybmeta
    Dec 24, 2014 at 11:05
  • Note that the OP said "I can't predict what post types would the user have"
    – cybmeta
    Dec 24, 2014 at 11:07
  • @cybmeta - The OP wants to amend the query my keeping the post types that would be queried, but by also adding the CPT as generated by his plugin. Therefore you must get the post types currently in the query ($post_types = $query->get('post_type');), add the new CPT ($post_types[] = 'document';), and then update the query ($query->set('post_type', $post_types);).
    – David Gard
    Dec 24, 2014 at 11:08
  • @cybmeta - Exactly, the user said "I can't predict what post types would the user have", therefore before adding the CPT you need to work out what post types are currently in $query. The users question of how I can add my CPT to the query without affecting other post types? also seems pretty clear in this regard.
    – David Gard
    Dec 24, 2014 at 11:11
  • I understood that the OP can not have a list of CPT to add to current query, so filling $post_types[] with hardcoded custom post types as you suggested is not possible. Maybe I didn't understood the question???.
    – cybmeta
    Dec 24, 2014 at 11:20

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.