the_author_posts_link() for authors of custom post types

All we need is an easy explanation of the problem, so here it is.

I have both regular blog posts and a custom post type in a blog. The page template shows the author posts link. If you click on that link for an author that has authored some posts, that page (blog/authors/mr-author) shows the expected bio information and a list of the author’s posts.

However, if you create a user that is an author, but who has only authored the custom post type, and no regular posts, the link generated by the_author_posts_link() (which is still the correct link: blog/authors/mr-author) shows an unpopulated page (ie: the fields are all empty, and the posts listing is the full list of all posts for all authors).

Clearly, we’re not getting the right data inside the $authordata global. But why? author.php is using standard template tags like get_the_author_meta('display_name') to display author information, but this is all showing blank results for an author that has no posts.

I’m currently digging through core to figure out where and when $authordata gets populated to see if it’s linked to a specific post type being present, but so far have yielded nothing useful. Anyone run into this before?

EDIT: SOLUTION BASED ON CHIP’S ANSWER

add_action('pre_get_posts', 'hdb_add_custom_type_to_query');

function hdb_add_custom_type_to_query( $notused ){
     if (! is_admin() ){
        global $wp_query;
        if ( is_author() || is_home() ){
            $wp_query->set( 'post_type',  array( 'post', CUSTOM_TYPE ) );
        }
     }
}

Assumes you’ve defined CUSTOM_TYPE constant at some point, probably when you declare the custom post type.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I believe the issue is that the default query only queries for post post-type. (See related WPSE question here.)

So, you probably need to modify the query in your author.php template file, so that all relevant post-types are included in the query.

Method 2

This workaround solved the problem for me, but I feel a little dirty. I think Chip’s on the money with the fact that when we populate the post globals with the_post(), it’s only taking into consideration actual ‘posts’, hence the $authordata global is not getting populated (heck, NOTHING is getting populated).

Strangely (or not, I suppose if you truly grock the deep internals, which I do not yet) get_queried_object() returns the exact same structure as $authordata. So the following snippet, inserted in authors.php accomplishes what I hoped for. Obviously this only works as expected on an authors archive template page, otherwise get_queried_object() will return some other structure.

<?php 
  the_post(); // Attempt to populate post globals (works if this author has regular posts)

  global $authordata;
  if ( !is_object( $authordata ) ) $authordata = get_queried_object(); 
?>

As I think about this more, it seems that the default method for populating the author data is actually flawed. It gets a list of the authors’ posts and based on the first post in the list, (re)populates the author data. I’m not going to say that my approach is better, or even good, but I like the idea of treating the author object as the primary queried object on this page, rather than just an adjunct to a post that happens to surface on this page because of a circular relationship with the queried term.

Method 3

Easier way to do that is simply adding support of author to your custom post type
while registering the new post

'supports' => array(
                        'title',
                        'editor',
                        'thumbnail',
                        'post-formats',
                        'author', 
                        ),

Method 4

If any user has not any post, it shows 404 by default. You can get the user_id of that user from $author variable. Then you can populate the users post and other type of things as you wanted.

Method 5

I had to do this recently on a site without “posts”, that still needed author pages.

Basically you catch author pages at the template_redirect hook, make sure to unset the 404 flag, and include the author template. You can extend the logic within the template redirect test as necessary. What you then do in the author.php template is up to you.

/* Force author views to use author.php, rather than default to 404 pages 
    if there are no posts to show. */
add_action( 'template_redirect', 'author_page_template' );

function author_page_template() {

    // Note: you probably also want to check if the author exists...
    if ( is_author() ) {
        global $wp_query;
        $wp_query->set( 'is_404', false );
        include( get_stylesheet_directory().'/author.php' );
        exit;
    }

}

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply