I'm attempting to develop an is_blog() function which returns true if the current view is a single post, blog home, or post archive. I have successfully excluded pages and attachments. My current code is in my theme's functions.php, as follows:

function is_blog() {
    global $post;
    $post_type = get_post_type( $post );

    // is_archive() covers is_author(), is_category(), is_date(), is_tag(), and is_tax()
    return ( ('page' == $post_type ) && !is_attachment() && ( is_home() || is_archive() || is_single() ) );

So far, this works as expected per the above criteria - for this development I call the function from my footer.php and display the result.

My current difficulty is custom types. I have one custom type currently, and the function returns true, even though the custom type view is certainly not blog-related. I'm aware of checking for the post type, as evidenced by the code (oddly, a single post has a type of 'page'), but how can I exclude as yet-unknown custom types? Sure, I have just one now, but I'd like to be able to prevent ANY custom type from causing a true result.

Is there any way to catch ANY type that is not built-in to WordPress?

  • is_archive returns true for CPT archives, so I'd use the is_category, is_tag... instead. you could use is_singular('post') instead of is_single
    – paul
    Feb 18, 2013 at 20:19

2 Answers 2


This function could help you filter out non standard post types:

function is_non_standard_type($id = null) {
    if (!$id) {
        // rewind_posts();
        global $post;
        $id = $post->ID;
    $post_type = get_post_type( $id );

    return in_array($post_type, array('post', 'page', 'attachment', 'nav_menu, 'nav_menu_item', 'revision')); // You might want to handle revision differently

Keep in mind though that this is basically only true for single pages (i.e. is_single() === true), and even then you can't be entirely certain. This is due to the fact that the global $post might change during the course of loading the page, depending on what happens during any loops. For example, a loop in a sidebar might overwrite the value of $post. To account for this you could use rewind_posts() to revert to the state the global query/post was in when the page started loading.

But then there are also archive pages, for which the $post variable might not hold anything or might not reflect a single post type. Take taxonomy pages for example - as they taxonomies are not unique to a single post type you can't really be sure that just because you are querying taxonomy_x you will only get posts of type post_type_y. You might be able to work around this by using a function such as the below, but it will only work if the query being run has the post_type defined, which it might not always be.

function queried_post_type_object() {
    $var = get_query_var('post_type');

    if ($var) {
        return get_post_type_object($var);

    return null;

Even if you do manage to correctly determine which post type, taxonomies etc. are being displayed, the logic involved will not be trivial. Finding the right combination of is_single(), is_archive() in combination with exception for different post types will probably pose a challenge, but with a bit of work you should be able to solve it.


For archives that aren't post type archives:

// if is an archive but NOT a post type archive:
if( is_archive() && ! is_post_type_archive() )
    echo 'blog archive';

For single posts that are only of post type post, use instead of is_single():

if( is_singular( 'post' ) )
    echo 'blog post';

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.