Support » Fixing WordPress » Create fake paged author pages when there are no posts

  • Resolved Beee

    (@beee)


    I have created a profile page for all users in our database with author.php, see an example on https://internationaldownhillfederation.org/member/berry-plasman/

    I am now developing a new website where I’m using query vars to create ‘fake’ sub-pages, such as

    • https://internationaldownhillfederation.org/member/berry-plasman/race-attendance/ (which races he/she attended)
    • https://internationaldownhillfederation.org/member/berry-plasman/written/ which posts he/she wrote (what’s normally shown on an author page)
    • https://internationaldownhillfederation.org/member/berry-plasman/mentioned/ to show in which posts he/she got mentioned

    Note: links are not working on live site (except first one).

    The last one is the one which is giving me issues. I used ACF to be able to tag users in a normal post. On /mentioned/ I query the posts in which he/she got mentioned. That is not a problem.

    The problem lies in the fact that I need to paginate these ‘mentioned’ posts BUT since 99% of the users have not written any posts, a paged author page returns a 404 because there are no posts for that user and thus no page 2.

Viewing 11 replies - 16 through 26 (of 26 total)
  • Moderator keesiemeijer

    (@keesiemeijer)

    The query for all of these pages is a query for the author’s posts because the author_name query var is set. You need to reset the author_name in the pre_get_posts action if you want to display other posts not necessarily from the author (with correct pagination).

    
    $query->set( 'author_name', '' );
    

    With this it will search for posts regardless of the author.

    You then also don’t need to add the author IDs when you use post__in:

    
    $query->set( 'author__in', $authors );
    $query->set( 'post__in', $post_ids );
    

    (from the pre_get_posts action)

    I can’t really test your setup because it depends on theme functions and meta keys (I don’t have).

    Why is it you need to fake paged pages, and what is it you want to display there?

    • This reply was modified 1 year, 3 months ago by  keesiemeijer.

    I understand (you can’t test it).

    I have tried setting post author to false/empty and then querying the posts, but it didn’t seem to work.

    If I have some time I might revisit this to test it, because it does intrigue me.

    Moderator keesiemeijer

    (@keesiemeijer)

    Ah, no problem. Good luck with the launch 🙂

    Couldn’t let it go 🙂

    When I set author_name to false, the entire query collapses because the queried object returns as false. I remember now why I immediately abandoned it after testing 🙂

    So I think author_name needs to be set and therein lies the crux of the issue.

    Moderator keesiemeijer

    (@keesiemeijer)

    Yes, that’s a downside.

    You can add the author_name back after the query. In the next example I’ve stored the author_name variable in fake_author_name and added it back in the_posts filter (after the posts are retrieved from the database). This doesn’t break the queried object.

    
    function change_author_permalinks() {
    	global $wp_rewrite;
    	$wp_rewrite->author_base = 'member';
    	$wp_rewrite->flush_rules();
    }
    add_action( 'init', 'change_author_permalinks' );
    
    function idf_rewrite_profile_pages() {
    	add_rewrite_rule( 'member/([a-z-]+)/([a-z-]+)/?$', 'index.php?author_name=$matches[1]&subpage=$matches[2]', 'top' );
    	add_rewrite_rule( 'member/([a-z-]+)/mentioned/page/([0-9]+)/?$', 'index.php?paged=$matches[2]&author_name=$matches[1]&subpage=mentioned', 'top' );
    	add_rewrite_rule( 'member/([a-z-]+)/written/page/([0-9]+)/?$', 'index.php?paged=$matches[2]&author_name=$matches[1]&subpage=written', 'top' );
    }
    add_filter( 'init', 'idf_rewrite_profile_pages', 1, 3 );
    
    function idf_add_query_vars( $query_vars ) {
    	$query_vars[] = 'subpage';
    	$query_vars[] = 'fake_author_name';
    	return $query_vars;
    }
    add_filter( 'query_vars', 'idf_add_query_vars' );
    
    function alter_query_for_author_mentioned_subpages( $query ) {
    	if ( ! is_admin() && $query->is_main_query() && is_author() ) {
    		$subpage = get_query_var( 'subpage' );
    
    		if ( ( 'mentioned' === $subpage ) && $query->is_paged() ) {
    			$author_name = get_query_var( 'author_name' );
    			// Reset paged
    			$query->set( 'paged', '' );
    
    			// Reset author name
    			$query->set( 'author_name', '' );
    
    			// Store author name in fake_author_name query var
    			$query->set( 'fake_author_name', $author_name );
    
    			add_filter( 'the_posts', 'idf_undo_reset_author_name', 99, 2 );
    		}
    	}
    
    }
    add_action( 'pre_get_posts', 'alter_query_for_author_mentioned_subpages' );
    
    function idf_undo_reset_author_name( $posts, $query ) {
    	$author_name = get_query_var( 'fake_author_name' );
    	if ( ! $author_name ) {
    		return $posts;
    	}
    
    	// Set author name back after the query
    	$query->set( 'author_name', $author_name );
    
    	$author = get_user_by( 'slug', $author_name );
    	if ( $author ) {
    		// Set author after query (needed for get_queried_object() )
    		$query->set( 'author', $author->ID );
    	}
    
    	// Remove filter
    	remove_filter( 'the_posts', 'idf_undo_reset_author_name', 99, 2 );
    
    	return $posts;
    }

    It does feel a little bit hacky. I will let you know if I come up with something more elegant.

    • This reply was modified 1 year, 3 months ago by  keesiemeijer.

    Not sure where I need to ‘insert’ my post ids. Below add_filter ?

    Moderator keesiemeijer

    (@keesiemeijer)

    It shouldn’t matter, as the the_posts filter is fired after the pre_get_posts action.

    
    $query->set( 'post__in', $post_ids );
    add_filter( 'the_posts', 'idf_undo_reset_author_name', 99, 2 );
    

    And maybe for troubleshooting you should remove the paged conditional
    && $query->is_paged(). (or in your code && false != get_query_var( 'paged' )).

    Now this is getting somewhere…. Page 2 is now does not result in a 404 anymore, so I feel I only need to polish up the query to make it work…

    Will update, once I get there…

    WOOPTIE F***ING DOO !!! It works !!!

    As I suspected it was indeed the author name which was too ‘limited’ to include all in the query.

    This is the final result in pre-get-posts. It might look a bit different than you supplied it but tweaked/DRY-ed it a bit as well to eliminate other queries.

    function alter_query_for_author_mentioned_subpages( $query ) {
        if ( ! is_admin() && $query->is_main_query() && is_author() ) {
    
            $subpage     = get_query_var( 'subpage' );
            $author_name = get_query_var( 'author_name' );
    
            if ( ( 'mentioned' === $subpage ) ) {
                $ppp     = 18; // @TODO: get from setting
                $user_id = get_user_by( 'slug', $author_name )->ID;
                $mentioned_posts = idf_get_user_mentions( $user_id );
    
                $query->set( 'posts_per_page', $ppp );
    
                if ( $mentioned_posts ) {
        
                    $authors   = get_all_authors_ids();
                    $authors[] = $user_id;
        
                    $query->set( 'post__in', $mentioned_posts );
        
                    // Reset author name
                    $query->set( 'author_name', '' );
        
                    // Store author name in fake_author_name query var
                    $query->set( 'fake_author_name', $author_name );
        
                }
    
                add_filter( 'the_posts', 'idf_undo_reset_author_name', 99, 2 );
            }   
        }
    }
    add_action( 'pre_get_posts', 'alter_query_for_author_mentioned_subpages' );

    Thanks @keesiemeijer couldn’t have fixed it without you I think.

    Moderator keesiemeijer

    (@keesiemeijer)

    You’re welcome. I’m glad you have your issue solved 🙂

    Happy new year!

    My new year starts of nicely… This was a long standing issue for me…

    Happy new year to you too.

Viewing 11 replies - 16 through 26 (of 26 total)
  • The topic ‘Create fake paged author pages when there are no posts’ is closed to new replies.