I'm trying to show aditional posts in the author's page. This page must have posts containing a specific meta_key and meta_value, where the displayed author it is not really the WP post's author.

This is the function I have:

function my_pre_get_posts( $query ) {

    if ( is_admin() )

    if ( $query->is_main_query() ) :

        if ( is_author() ):
            $query->set( 'meta_query', array(
                'relation'      => 'OR',
                    'key'       => 'writer',
                    'value'     => 'the same author name'
                    'key' => '',
                    'value' => ''
            ) );

add_action( 'pre_get_posts', 'my_pre_get_posts' );

But at a glance, it won't work.

Sorry if my english is bad.

  • Just to clarify: Do you want this to return posts where key = 'the same author name' OR key = NULL, but not return posts where key = 'other author name'? – Andy Adams Dec 5 '12 at 19:02
  • Yes, it's something like co-authors. If the author template is displayed, the user will see your posts. In addition, because of your user_login (or ID, display_name...) could be in the meta values of other posts, those posts should be displayed too. – alekstrust Dec 6 '12 at 6:14

The WP_Query class will automatically AND any filters that are set. In your case, using $query->set( 'meta_query', ... ) means that WordPress will be looking for posts from the current author (because this is the author template) AND that have your custom meta key. From my understanding of your problem, this intentionally will never happen, so the query can't be modified this way.

Instead, you'll need the posts_where filter to add an OR condition to the WHERE clause:

function wp_75068_filter_where( $where ) {
    if ( is_author() ) {
        global $wpdb;

        $co_author_posts = get_posts( array( 
            'numberposts' => 99,
            'meta_key' => 'writer',
            'meta_value' => 'the same author name',
            'fields' => 'ids' // fetch only the IDs
        ) );

        if ( ! empty( $co_author_posts ) ) {
            $where .= " OR $wpdb->posts.ID IN (" . implode( ", ", array_map( 'intval', $co_author_posts ) ) . ") "; 

    return $where;

add_filter( 'posts_where', 'wp_75068_filter_where' );

Code hasn't been tested, so let me know if there are any hiccups!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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