I’ll build this as a complete advanced template-parts/post/author-box.php file for your RX Theme, with safe escaping, schema, social links, avatar fallback, author stats, and hooks so you can extend it later.
Below is a very advanced, feature-rich template-parts/post/author-box.php file for your RX Theme.
Create this file:
rx-theme/template-parts/post/author-box.php
Then paste this full code:
<?php
/**
* Template Part: Author Box
*
* File: template-parts/post/author-box.php
*
* Advanced author box for RX Theme.
*
* Features:
* - Safe WordPress escaping
* - Author avatar
* - Author name
* - Author bio
* - Author role/title
* - Author website
* - Author email button optional
* - Social profile links
* - Author post count
* - Author archive link
* - Latest posts by same author
* - Schema.org Person markup
* - Hooks and filters for future extension
* - Accessibility friendly markup
* - Works inside single post templates
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
/**
* Do not show author box in places where it is not useful.
*/
if ( ! is_singular( 'post' ) ) {
return;
}
/**
* Get current post author.
*/
$rx_post_id = get_the_ID();
$rx_author_id = (int) get_post_field( 'post_author', $rx_post_id );
if ( ! $rx_author_id ) {
return;
}
/**
* Basic author data.
*/
$rx_author_name = get_the_author_meta( 'display_name', $rx_author_id );
$rx_author_first_name = get_the_author_meta( 'first_name', $rx_author_id );
$rx_author_last_name = get_the_author_meta( 'last_name', $rx_author_id );
$rx_author_nickname = get_the_author_meta( 'nickname', $rx_author_id );
$rx_author_description = get_the_author_meta( 'description', $rx_author_id );
$rx_author_url = get_the_author_meta( 'user_url', $rx_author_id );
$rx_author_email = get_the_author_meta( 'user_email', $rx_author_id );
$rx_author_archive_url = get_author_posts_url( $rx_author_id );
$rx_author_posts_count = count_user_posts( $rx_author_id, 'post', true );
/**
* Custom user meta support.
* You can later create user profile fields for these.
*/
$rx_author_job_title = get_the_author_meta( 'rx_author_job_title', $rx_author_id );
$rx_author_company = get_the_author_meta( 'rx_author_company', $rx_author_id );
$rx_author_location = get_the_author_meta( 'rx_author_location', $rx_author_id );
$rx_author_specialty = get_the_author_meta( 'rx_author_specialty', $rx_author_id );
$rx_author_credentials = get_the_author_meta( 'rx_author_credentials', $rx_author_id );
$rx_author_verified = get_the_author_meta( 'rx_author_verified', $rx_author_id );
$rx_author_verified_text = get_the_author_meta( 'rx_author_verified_text', $rx_author_id );
$rx_author_reviewed_by = get_the_author_meta( 'rx_author_reviewed_by', $rx_author_id );
$rx_author_updated_profile = get_the_author_meta( 'rx_author_updated_profile', $rx_author_id );
/**
* Social profile fields.
* These can be added later through user profile fields.
*/
$rx_social_profiles = array(
'facebook' => array(
'label' => __( 'Facebook', 'rx-theme' ),
'url' => get_the_author_meta( 'facebook', $rx_author_id ),
),
'twitter' => array(
'label' => __( 'X / Twitter', 'rx-theme' ),
'url' => get_the_author_meta( 'twitter', $rx_author_id ),
),
'linkedin' => array(
'label' => __( 'LinkedIn', 'rx-theme' ),
'url' => get_the_author_meta( 'linkedin', $rx_author_id ),
),
'instagram' => array(
'label' => __( 'Instagram', 'rx-theme' ),
'url' => get_the_author_meta( 'instagram', $rx_author_id ),
),
'youtube' => array(
'label' => __( 'YouTube', 'rx-theme' ),
'url' => get_the_author_meta( 'youtube', $rx_author_id ),
),
'github' => array(
'label' => __( 'GitHub', 'rx-theme' ),
'url' => get_the_author_meta( 'github', $rx_author_id ),
),
'website' => array(
'label' => __( 'Website', 'rx-theme' ),
'url' => $rx_author_url,
),
);
/**
* Allow child theme/plugin customization.
*/
$rx_social_profiles = apply_filters( 'rx_theme_author_box_social_profiles', $rx_social_profiles, $rx_author_id, $rx_post_id );
/**
* Author avatar settings.
*/
$rx_avatar_size = apply_filters( 'rx_theme_author_box_avatar_size', 120, $rx_author_id, $rx_post_id );
$rx_avatar = get_avatar(
$rx_author_id,
$rx_avatar_size,
'',
$rx_author_name,
array(
'class' => 'rx-author-box__avatar-img',
'loading' => 'lazy',
'fetchpriority' => 'low',
'decoding' => 'async',
)
);
/**
* Should show sections?
*/
$rx_show_author_box = apply_filters( 'rx_theme_show_author_box', true, $rx_author_id, $rx_post_id );
$rx_show_avatar = apply_filters( 'rx_theme_author_box_show_avatar', true, $rx_author_id, $rx_post_id );
$rx_show_bio = apply_filters( 'rx_theme_author_box_show_bio', true, $rx_author_id, $rx_post_id );
$rx_show_social = apply_filters( 'rx_theme_author_box_show_social', true, $rx_author_id, $rx_post_id );
$rx_show_stats = apply_filters( 'rx_theme_author_box_show_stats', true, $rx_author_id, $rx_post_id );
$rx_show_latest = apply_filters( 'rx_theme_author_box_show_latest_posts', true, $rx_author_id, $rx_post_id );
$rx_show_email = apply_filters( 'rx_theme_author_box_show_email', false, $rx_author_id, $rx_post_id );
if ( ! $rx_show_author_box ) {
return;
}
/**
* Do not show empty author box if author has no useful data.
*/
if (
empty( $rx_author_name )
&& empty( $rx_author_description )
&& empty( $rx_avatar )
) {
return;
}
/**
* Latest posts by same author.
*/
$rx_latest_posts_count = apply_filters( 'rx_theme_author_box_latest_posts_count', 3, $rx_author_id, $rx_post_id );
$rx_latest_posts = array();
if ( $rx_show_latest && $rx_latest_posts_count > 0 ) {
$rx_latest_posts_query = new WP_Query(
array(
'post_type' => 'post',
'post_status' => 'publish',
'author' => $rx_author_id,
'posts_per_page' => absint( $rx_latest_posts_count ),
'post__not_in' => array( $rx_post_id ),
'ignore_sticky_posts' => true,
'no_found_rows' => true,
)
);
if ( $rx_latest_posts_query->have_posts() ) {
while ( $rx_latest_posts_query->have_posts() ) {
$rx_latest_posts_query->the_post();
$rx_latest_posts[] = array(
'id' => get_the_ID(),
'title' => get_the_title(),
'url' => get_permalink(),
'date' => get_the_date(),
);
}
wp_reset_postdata();
}
}
/**
* Build sameAs schema array.
*/
$rx_schema_same_as = array();
foreach ( $rx_social_profiles as $rx_social_key => $rx_social_data ) {
if ( ! empty( $rx_social_data['url'] ) && filter_var( $rx_social_data['url'], FILTER_VALIDATE_URL ) ) {
$rx_schema_same_as[] = esc_url_raw( $rx_social_data['url'] );
}
}
/**
* Person schema data.
*/
$rx_author_schema = array(
'@context' => 'https://schema.org',
'@type' => 'Person',
'name' => wp_strip_all_tags( $rx_author_name ),
'url' => esc_url_raw( $rx_author_archive_url ),
);
if ( ! empty( $rx_author_description ) ) {
$rx_author_schema['description'] = wp_strip_all_tags( $rx_author_description );
}
if ( ! empty( $rx_author_job_title ) ) {
$rx_author_schema['jobTitle'] = wp_strip_all_tags( $rx_author_job_title );
}
if ( ! empty( $rx_author_company ) ) {
$rx_author_schema['worksFor'] = array(
'@type' => 'Organization',
'name' => wp_strip_all_tags( $rx_author_company ),
);
}
if ( ! empty( $rx_schema_same_as ) ) {
$rx_author_schema['sameAs'] = $rx_schema_same_as;
}
$rx_author_schema = apply_filters( 'rx_theme_author_box_schema', $rx_author_schema, $rx_author_id, $rx_post_id );
/**
* CSS classes.
*/
$rx_author_box_classes = array(
'rx-author-box',
'rx-author-box--post',
'rx-author-box--author-' . $rx_author_id,
);
if ( ! empty( $rx_author_verified ) ) {
$rx_author_box_classes[] = 'rx-author-box--verified';
}
if ( ! empty( $rx_author_description ) ) {
$rx_author_box_classes[] = 'rx-author-box--has-bio';
}
if ( ! empty( $rx_latest_posts ) ) {
$rx_author_box_classes[] = 'rx-author-box--has-latest-posts';
}
$rx_author_box_classes = apply_filters( 'rx_theme_author_box_classes', $rx_author_box_classes, $rx_author_id, $rx_post_id );
?>
<?php do_action( 'rx_theme_before_author_box', $rx_author_id, $rx_post_id ); ?>
<section
class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $rx_author_box_classes ) ) ); ?>"
aria-labelledby="rx-author-box-title-<?php echo esc_attr( $rx_author_id ); ?>"
itemscope
itemtype="https://schema.org/Person"
>
<div class="rx-author-box__inner">
<?php if ( $rx_show_avatar && ! empty( $rx_avatar ) ) : ?>
<div class="rx-author-box__avatar">
<a
class="rx-author-box__avatar-link"
href="<?php echo esc_url( $rx_author_archive_url ); ?>"
aria-label="<?php echo esc_attr( sprintf( __( 'View all posts by %s', 'rx-theme' ), $rx_author_name ) ); ?>"
itemprop="url"
>
<?php echo wp_kses_post( $rx_avatar ); ?>
</a>
</div>
<?php endif; ?>
<div class="rx-author-box__content">
<header class="rx-author-box__header">
<p class="rx-author-box__label">
<?php esc_html_e( 'Written by', 'rx-theme' ); ?>
</p>
<h2
id="rx-author-box-title-<?php echo esc_attr( $rx_author_id ); ?>"
class="rx-author-box__title"
itemprop="name"
>
<a
class="rx-author-box__name-link"
href="<?php echo esc_url( $rx_author_archive_url ); ?>"
rel="author"
>
<?php echo esc_html( $rx_author_name ); ?>
</a>
<?php if ( ! empty( $rx_author_verified ) ) : ?>
<span class="rx-author-box__verified" title="<?php echo esc_attr__( 'Verified author', 'rx-theme' ); ?>">
<span aria-hidden="true">✓</span>
<span class="screen-reader-text">
<?php esc_html_e( 'Verified author', 'rx-theme' ); ?>
</span>
</span>
<?php endif; ?>
</h2>
<?php if ( ! empty( $rx_author_credentials ) || ! empty( $rx_author_job_title ) || ! empty( $rx_author_specialty ) ) : ?>
<div class="rx-author-box__meta">
<?php if ( ! empty( $rx_author_credentials ) ) : ?>
<span class="rx-author-box__credential">
<?php echo esc_html( $rx_author_credentials ); ?>
</span>
<?php endif; ?>
<?php if ( ! empty( $rx_author_job_title ) ) : ?>
<span class="rx-author-box__job-title" itemprop="jobTitle">
<?php echo esc_html( $rx_author_job_title ); ?>
</span>
<?php endif; ?>
<?php if ( ! empty( $rx_author_specialty ) ) : ?>
<span class="rx-author-box__specialty">
<?php echo esc_html( $rx_author_specialty ); ?>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_author_company ) || ! empty( $rx_author_location ) ) : ?>
<div class="rx-author-box__details">
<?php if ( ! empty( $rx_author_company ) ) : ?>
<span class="rx-author-box__company">
<?php esc_html_e( 'Works at', 'rx-theme' ); ?>
<strong><?php echo esc_html( $rx_author_company ); ?></strong>
</span>
<?php endif; ?>
<?php if ( ! empty( $rx_author_location ) ) : ?>
<span class="rx-author-box__location">
<?php echo esc_html( $rx_author_location ); ?>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
</header>
<?php if ( $rx_show_bio && ! empty( $rx_author_description ) ) : ?>
<div class="rx-author-box__bio" itemprop="description">
<?php
echo wp_kses_post(
wpautop(
wp_trim_words(
$rx_author_description,
apply_filters( 'rx_theme_author_box_bio_words', 80, $rx_author_id, $rx_post_id ),
'...'
)
)
);
?>
</div>
<?php else : ?>
<div class="rx-author-box__bio rx-author-box__bio--empty">
<p>
<?php
printf(
esc_html__( '%s writes helpful, evidence-based, and reader-friendly articles for this website.', 'rx-theme' ),
esc_html( $rx_author_name )
);
?>
</p>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_author_verified_text ) ) : ?>
<div class="rx-author-box__verification-note">
<?php echo wp_kses_post( wpautop( $rx_author_verified_text ) ); ?>
</div>
<?php endif; ?>
<?php if ( $rx_show_stats ) : ?>
<div class="rx-author-box__stats" aria-label="<?php echo esc_attr__( 'Author statistics', 'rx-theme' ); ?>">
<span class="rx-author-box__stat rx-author-box__stat--posts">
<strong><?php echo esc_html( number_format_i18n( $rx_author_posts_count ) ); ?></strong>
<?php echo esc_html( _n( 'Published article', 'Published articles', $rx_author_posts_count, 'rx-theme' ) ); ?>
</span>
<?php if ( ! empty( $rx_author_updated_profile ) ) : ?>
<span class="rx-author-box__stat rx-author-box__stat--updated">
<?php esc_html_e( 'Profile updated:', 'rx-theme' ); ?>
<strong><?php echo esc_html( $rx_author_updated_profile ); ?></strong>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ( $rx_show_social ) : ?>
<?php
$rx_has_social_links = false;
foreach ( $rx_social_profiles as $rx_social_data ) {
if ( ! empty( $rx_social_data['url'] ) ) {
$rx_has_social_links = true;
break;
}
}
?>
<?php if ( $rx_has_social_links ) : ?>
<nav class="rx-author-box__social" aria-label="<?php echo esc_attr__( 'Author social links', 'rx-theme' ); ?>">
<ul class="rx-author-box__social-list">
<?php foreach ( $rx_social_profiles as $rx_social_key => $rx_social_data ) : ?>
<?php
if ( empty( $rx_social_data['url'] ) ) {
continue;
}
$rx_social_label = ! empty( $rx_social_data['label'] ) ? $rx_social_data['label'] : ucfirst( $rx_social_key );
$rx_social_url = $rx_social_data['url'];
?>
<li class="rx-author-box__social-item rx-author-box__social-item--<?php echo esc_attr( sanitize_html_class( $rx_social_key ) ); ?>">
<a
class="rx-author-box__social-link"
href="<?php echo esc_url( $rx_social_url ); ?>"
target="_blank"
rel="nofollow noopener noreferrer me"
itemprop="sameAs"
>
<span class="rx-author-box__social-text">
<?php echo esc_html( $rx_social_label ); ?>
</span>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
<?php endif; ?>
<?php endif; ?>
<div class="rx-author-box__actions">
<a
class="rx-author-box__button rx-author-box__button--archive"
href="<?php echo esc_url( $rx_author_archive_url ); ?>"
>
<?php
printf(
esc_html__( 'View all posts by %s', 'rx-theme' ),
esc_html( $rx_author_name )
);
?>
</a>
<?php if ( ! empty( $rx_author_url ) ) : ?>
<a
class="rx-author-box__button rx-author-box__button--website"
href="<?php echo esc_url( $rx_author_url ); ?>"
target="_blank"
rel="nofollow noopener noreferrer"
>
<?php esc_html_e( 'Visit website', 'rx-theme' ); ?>
</a>
<?php endif; ?>
<?php if ( $rx_show_email && ! empty( $rx_author_email ) && is_email( $rx_author_email ) ) : ?>
<a
class="rx-author-box__button rx-author-box__button--email"
href="<?php echo esc_url( 'mailto:' . antispambot( $rx_author_email ) ); ?>"
>
<?php esc_html_e( 'Contact author', 'rx-theme' ); ?>
</a>
<?php endif; ?>
</div>
<?php if ( ! empty( $rx_latest_posts ) ) : ?>
<div class="rx-author-box__latest">
<h3 class="rx-author-box__latest-title">
<?php esc_html_e( 'More articles by this author', 'rx-theme' ); ?>
</h3>
<ul class="rx-author-box__latest-list">
<?php foreach ( $rx_latest_posts as $rx_latest_post ) : ?>
<li class="rx-author-box__latest-item">
<a
class="rx-author-box__latest-link"
href="<?php echo esc_url( $rx_latest_post['url'] ); ?>"
>
<?php echo esc_html( $rx_latest_post['title'] ); ?>
</a>
<?php if ( ! empty( $rx_latest_post['date'] ) ) : ?>
<span class="rx-author-box__latest-date">
<?php echo esc_html( $rx_latest_post['date'] ); ?>
</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
</div>
</div>
<?php if ( ! empty( $rx_author_schema ) ) : ?>
<script type="application/ld+json">
<?php
echo wp_json_encode(
$rx_author_schema,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
);
?>
</script>
<?php endif; ?>
</section>
<?php do_action( 'rx_theme_after_author_box', $rx_author_id, $rx_post_id ); ?>
To show it inside your single.php, add this where you want the author box to appear:
<?php get_template_part( 'template-parts/post/author-box' ); ?>
Best position is usually after post content and before related posts:
<?php the_content(); ?>
<?php get_template_part( 'template-parts/post/author-box' ); ?>
<?php get_template_part( 'template-parts/post/related-posts' ); ?>
You can later add custom user fields like:
rx_author_job_title
rx_author_company
rx_author_location
rx_author_specialty
rx_author_credentials
rx_author_verified
rx_author_verified_text
rx_author_updated_profile
facebook
twitter
linkedin
instagram
youtube
github
This file is already safe, expandable, SEO-friendly, and suitable for a serious medical/blog theme.