I’ll build a strong template-parts/content/content.php for your RX Theme with many reusable WordPress features: post formats, thumbnails, meta, schema, excerpt/full content handling, pagination, tags, sharing hooks, ads/hooks, and accessibility-safe markup.
Below is a full advanced template-parts/content/content.php file for your RX Theme. It is built like a professional WordPress theme content template and includes many possible features while staying safe and extendable.
Create or replace this file:
<?php
/**
* Template part for displaying post/page/content cards.
*
* File: template-parts/content/content.php
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
$post_id = get_the_ID();
$post_type = get_post_type( $post_id );
if ( ! $post_id ) {
return;
}
/**
* Context checks.
*/
$is_singular = is_singular();
$is_page = is_page();
$is_post = 'post' === $post_type;
$is_sticky = is_sticky( $post_id ) && is_home() && ! is_paged();
/**
* Allow theme/plugin developers to customize CSS classes.
*/
$article_classes = array(
'rx-content',
'rx-content--' . sanitize_html_class( $post_type ),
'rx-content--format-' . sanitize_html_class( get_post_format() ?: 'standard' ),
);
if ( $is_singular ) {
$article_classes[] = 'rx-content--single';
} else {
$article_classes[] = 'rx-content--archive';
}
if ( $is_sticky ) {
$article_classes[] = 'rx-content--sticky';
}
if ( has_post_thumbnail() ) {
$article_classes[] = 'rx-content--has-thumbnail';
} else {
$article_classes[] = 'rx-content--no-thumbnail';
}
$article_classes = apply_filters( 'rx_theme_content_article_classes', $article_classes, $post_id );
/**
* Schema type.
*/
$schema_type = $is_page ? 'WebPage' : 'Article';
if ( $is_post ) {
$schema_type = 'BlogPosting';
}
/**
* Reading time fallback.
*/
if ( ! function_exists( 'rx_theme_get_reading_time' ) ) {
function rx_theme_get_reading_time( $post_id = null ) {
$post_id = $post_id ? absint( $post_id ) : get_the_ID();
$content = get_post_field( 'post_content', $post_id );
$content = wp_strip_all_tags( strip_shortcodes( $content ) );
$word_count = str_word_count( $content );
$minutes = max( 1, ceil( $word_count / 200 ) );
return sprintf(
/* translators: %s: reading time in minutes */
esc_html__( '%s min read', 'rx-theme' ),
number_format_i18n( $minutes )
);
}
}
/**
* Author avatar fallback renderer.
*/
if ( ! function_exists( 'rx_theme_content_author_avatar' ) ) {
function rx_theme_content_author_avatar( $size = 48 ) {
$author_id = get_the_author_meta( 'ID' );
if ( ! $author_id ) {
return;
}
echo '<span class="rx-content__author-avatar">';
echo get_avatar(
$author_id,
absint( $size ),
'',
esc_attr( get_the_author() ),
array(
'class' => 'rx-content__avatar-img',
)
);
echo '</span>';
}
}
/**
* Post views placeholder.
* You can connect this with your own post view counter later.
*/
$post_views = apply_filters( 'rx_theme_content_post_views', '', $post_id );
?>
<article
id="post-<?php the_ID(); ?>"
<?php post_class( $article_classes ); ?>
itemscope
itemtype="https://schema.org/<?php echo esc_attr( $schema_type ); ?>"
>
<?php
/**
* Before article hook.
*/
do_action( 'rx_theme_before_content_article', $post_id );
?>
<?php if ( $is_sticky ) : ?>
<div class="rx-content__badge rx-content__badge--sticky">
<?php esc_html_e( 'Featured', 'rx-theme' ); ?>
</div>
<?php endif; ?>
<?php if ( has_post_thumbnail() && apply_filters( 'rx_theme_content_show_thumbnail', true, $post_id ) ) : ?>
<figure class="rx-content__thumbnail" itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<?php
do_action( 'rx_theme_before_content_thumbnail', $post_id );
if ( $is_singular ) {
the_post_thumbnail(
'large',
array(
'class' => 'rx-content__thumbnail-img',
'loading' => 'eager',
'decoding' => 'async',
'itemprop' => 'url',
)
);
} else {
?>
<a class="rx-content__thumbnail-link" href="<?php the_permalink(); ?>" aria-label="<?php echo esc_attr( get_the_title() ); ?>">
<?php
the_post_thumbnail(
'large',
array(
'class' => 'rx-content__thumbnail-img',
'loading' => 'lazy',
'decoding' => 'async',
'itemprop' => 'url',
)
);
?>
</a>
<?php
}
$thumbnail_id = get_post_thumbnail_id( $post_id );
$image_meta = wp_get_attachment_metadata( $thumbnail_id );
if ( ! empty( $image_meta['width'] ) ) {
echo '<meta itemprop="width" content="' . esc_attr( $image_meta['width'] ) . '">';
}
if ( ! empty( $image_meta['height'] ) ) {
echo '<meta itemprop="height" content="' . esc_attr( $image_meta['height'] ) . '">';
}
do_action( 'rx_theme_after_content_thumbnail', $post_id );
?>
<?php if ( get_the_post_thumbnail_caption() ) : ?>
<figcaption class="rx-content__thumbnail-caption">
<?php echo wp_kses_post( get_the_post_thumbnail_caption() ); ?>
</figcaption>
<?php endif; ?>
</figure>
<?php endif; ?>
<header class="rx-content__header">
<?php
/**
* Before title hook.
*/
do_action( 'rx_theme_before_content_title', $post_id );
?>
<?php if ( $is_singular ) : ?>
<h1 class="rx-content__title entry-title" itemprop="headline">
<?php the_title(); ?>
</h1>
<?php else : ?>
<h2 class="rx-content__title entry-title" itemprop="headline">
<a class="rx-content__title-link" href="<?php the_permalink(); ?>" rel="bookmark">
<?php the_title(); ?>
</a>
</h2>
<?php endif; ?>
<?php
/**
* After title hook.
*/
do_action( 'rx_theme_after_content_title', $post_id );
?>
<?php if ( 'post' === $post_type && apply_filters( 'rx_theme_content_show_meta', true, $post_id ) ) : ?>
<div class="rx-content__meta entry-meta">
<span class="rx-content__meta-item rx-content__meta-author" itemprop="author" itemscope itemtype="https://schema.org/Person">
<?php rx_theme_content_author_avatar( 32 ); ?>
<span class="rx-content__meta-label">
<?php esc_html_e( 'By', 'rx-theme' ); ?>
</span>
<a class="rx-content__author-link" href="<?php echo esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ); ?>" itemprop="url">
<span itemprop="name"><?php echo esc_html( get_the_author() ); ?></span>
</a>
</span>
<span class="rx-content__meta-item rx-content__meta-date">
<span class="screen-reader-text">
<?php esc_html_e( 'Published on', 'rx-theme' ); ?>
</span>
<a href="<?php the_permalink(); ?>" rel="bookmark">
<time class="published" datetime="<?php echo esc_attr( get_the_date( DATE_W3C ) ); ?>" itemprop="datePublished">
<?php echo esc_html( get_the_date() ); ?>
</time>
</a>
</span>
<?php if ( get_the_modified_time( 'U' ) !== get_the_time( 'U' ) ) : ?>
<span class="rx-content__meta-item rx-content__meta-updated">
<span class="screen-reader-text">
<?php esc_html_e( 'Updated on', 'rx-theme' ); ?>
</span>
<time class="updated" datetime="<?php echo esc_attr( get_the_modified_date( DATE_W3C ) ); ?>" itemprop="dateModified">
<?php echo esc_html( get_the_modified_date() ); ?>
</time>
</span>
<?php endif; ?>
<span class="rx-content__meta-item rx-content__meta-reading-time">
<?php echo esc_html( rx_theme_get_reading_time( $post_id ) ); ?>
</span>
<?php if ( comments_open() || get_comments_number() ) : ?>
<span class="rx-content__meta-item rx-content__meta-comments">
<?php
comments_popup_link(
esc_html__( 'No Comments', 'rx-theme' ),
esc_html__( '1 Comment', 'rx-theme' ),
esc_html__( '% Comments', 'rx-theme' ),
'rx-content__comments-link'
);
?>
</span>
<?php endif; ?>
<?php if ( ! empty( $post_views ) ) : ?>
<span class="rx-content__meta-item rx-content__meta-views">
<?php echo esc_html( $post_views ); ?>
</span>
<?php endif; ?>
<?php edit_post_link(
esc_html__( 'Edit', 'rx-theme' ),
'<span class="rx-content__meta-item rx-content__meta-edit">',
'</span>'
); ?>
</div>
<?php endif; ?>
<?php if ( 'post' === $post_type && has_category() && apply_filters( 'rx_theme_content_show_categories', true, $post_id ) ) : ?>
<div class="rx-content__terms rx-content__categories">
<span class="rx-content__terms-label">
<?php esc_html_e( 'Categories:', 'rx-theme' ); ?>
</span>
<?php the_category( ' ' ); ?>
</div>
<?php endif; ?>
</header>
<?php
/**
* After header hook.
*/
do_action( 'rx_theme_after_content_header', $post_id );
?>
<?php if ( ! $is_singular && has_excerpt() && apply_filters( 'rx_theme_content_show_excerpt_above', false, $post_id ) ) : ?>
<div class="rx-content__summary" itemprop="description">
<?php the_excerpt(); ?>
</div>
<?php endif; ?>
<div class="rx-content__body entry-content" itemprop="articleBody">
<?php
/**
* Before content body hook.
* Useful for ads, notices, breadcrumbs, table of contents, or affiliate disclosure.
*/
do_action( 'rx_theme_before_content_body', $post_id );
?>
<?php
if ( $is_singular ) {
the_content(
sprintf(
wp_kses(
/* translators: %s: post title */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'rx-theme' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
)
);
wp_link_pages(
array(
'before' => '<nav class="rx-content__page-links page-links" aria-label="' . esc_attr__( 'Post pages', 'rx-theme' ) . '"><span class="rx-content__page-links-title">' . esc_html__( 'Pages:', 'rx-theme' ) . '</span>',
'after' => '</nav>',
'link_before' => '<span class="rx-content__page-link">',
'link_after' => '</span>',
)
);
} else {
if ( apply_filters( 'rx_theme_content_archive_show_excerpt', true, $post_id ) ) {
the_excerpt();
} else {
the_content(
sprintf(
wp_kses(
/* translators: %s: post title */
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'rx-theme' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
)
);
}
}
/**
* After content body hook.
* Useful for ads, CTA box, newsletter box, author box, or related posts.
*/
do_action( 'rx_theme_after_content_body', $post_id );
?>
</div>
<?php if ( ! $is_singular && apply_filters( 'rx_theme_content_show_read_more', true, $post_id ) ) : ?>
<div class="rx-content__read-more-wrap">
<a class="rx-content__read-more" href="<?php the_permalink(); ?>" aria-label="<?php echo esc_attr( sprintf( __( 'Read more about %s', 'rx-theme' ), get_the_title() ) ); ?>">
<?php esc_html_e( 'Read More', 'rx-theme' ); ?>
<span aria-hidden="true">→</span>
</a>
</div>
<?php endif; ?>
<?php if ( 'post' === $post_type && has_tag() && apply_filters( 'rx_theme_content_show_tags', true, $post_id ) ) : ?>
<footer class="rx-content__footer entry-footer">
<div class="rx-content__terms rx-content__tags">
<span class="rx-content__terms-label">
<?php esc_html_e( 'Tags:', 'rx-theme' ); ?>
</span>
<?php the_tags( '', ' ', '' ); ?>
</div>
</footer>
<?php endif; ?>
<?php if ( $is_singular && 'post' === $post_type && apply_filters( 'rx_theme_content_show_author_box', true, $post_id ) ) : ?>
<section class="rx-content__author-box" aria-label="<?php esc_attr_e( 'Author information', 'rx-theme' ); ?>">
<?php rx_theme_content_author_avatar( 80 ); ?>
<div class="rx-content__author-info">
<h2 class="rx-content__author-title">
<?php esc_html_e( 'Written by', 'rx-theme' ); ?>
<a href="<?php echo esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ); ?>">
<?php echo esc_html( get_the_author() ); ?>
</a>
</h2>
<?php if ( get_the_author_meta( 'description' ) ) : ?>
<p class="rx-content__author-description">
<?php echo esc_html( get_the_author_meta( 'description' ) ); ?>
</p>
<?php endif; ?>
</div>
</section>
<?php endif; ?>
<?php if ( $is_singular && apply_filters( 'rx_theme_content_show_share_links', true, $post_id ) ) : ?>
<nav class="rx-content__share" aria-label="<?php esc_attr_e( 'Share this article', 'rx-theme' ); ?>">
<span class="rx-content__share-title">
<?php esc_html_e( 'Share:', 'rx-theme' ); ?>
</span>
<a class="rx-content__share-link rx-content__share-link--facebook" href="<?php echo esc_url( 'https://www.facebook.com/sharer/sharer.php?u=' . rawurlencode( get_permalink() ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'Facebook', 'rx-theme' ); ?>
</a>
<a class="rx-content__share-link rx-content__share-link--x" href="<?php echo esc_url( 'https://twitter.com/intent/tweet?url=' . rawurlencode( get_permalink() ) . '&text=' . rawurlencode( get_the_title() ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'X', 'rx-theme' ); ?>
</a>
<a class="rx-content__share-link rx-content__share-link--linkedin" href="<?php echo esc_url( 'https://www.linkedin.com/shareArticle?mini=true&url=' . rawurlencode( get_permalink() ) . '&title=' . rawurlencode( get_the_title() ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'LinkedIn', 'rx-theme' ); ?>
</a>
<a class="rx-content__share-link rx-content__share-link--whatsapp" href="<?php echo esc_url( 'https://api.whatsapp.com/send?text=' . rawurlencode( get_the_title() . ' ' . get_permalink() ) ); ?>" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'WhatsApp', 'rx-theme' ); ?>
</a>
<a class="rx-content__share-link rx-content__share-link--email" href="<?php echo esc_url( 'mailto:?subject=' . rawurlencode( get_the_title() ) . '&body=' . rawurlencode( get_permalink() ) ); ?>">
<?php esc_html_e( 'Email', 'rx-theme' ); ?>
</a>
</nav>
<?php endif; ?>
<?php
/**
* Hidden schema/meta information.
*/
if ( $is_post ) :
$publisher_name = get_bloginfo( 'name' );
$logo_id = get_theme_mod( 'custom_logo' );
$logo_url = $logo_id ? wp_get_attachment_image_url( $logo_id, 'full' ) : '';
?>
<meta itemprop="mainEntityOfPage" content="<?php echo esc_url( get_permalink() ); ?>">
<meta itemprop="url" content="<?php echo esc_url( get_permalink() ); ?>">
<meta itemprop="wordCount" content="<?php echo esc_attr( str_word_count( wp_strip_all_tags( get_the_content() ) ) ); ?>">
<span class="rx-content__schema-publisher" itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
<meta itemprop="name" content="<?php echo esc_attr( $publisher_name ); ?>">
<?php if ( $logo_url ) : ?>
<span itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="url" content="<?php echo esc_url( $logo_url ); ?>">
</span>
<?php endif; ?>
</span>
<?php endif; ?>
<?php
/**
* After article hook.
*/
do_action( 'rx_theme_after_content_article', $post_id );
?>
</article>
You can use this file with:
<?php get_template_part( 'template-parts/content/content' ); ?>
Example in index.php, archive.php, search.php, or home.php:
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/content/content' );
endwhile;
the_posts_pagination(
array(
'mid_size' => 2,
'prev_text' => esc_html__( 'Previous', 'rx-theme' ),
'next_text' => esc_html__( 'Next', 'rx-theme' ),
)
);
else :
get_template_part( 'template-parts/content/content', 'none' );
endif;
?>
Important hooks included for future extension:
do_action( 'rx_theme_before_content_article', $post_id );
do_action( 'rx_theme_before_content_thumbnail', $post_id );
do_action( 'rx_theme_after_content_thumbnail', $post_id );
do_action( 'rx_theme_before_content_title', $post_id );
do_action( 'rx_theme_after_content_title', $post_id );
do_action( 'rx_theme_after_content_header', $post_id );
do_action( 'rx_theme_before_content_body', $post_id );
do_action( 'rx_theme_after_content_body', $post_id );
do_action( 'rx_theme_after_content_article', $post_id );
Useful filters included:
rx_theme_content_article_classes
rx_theme_content_show_thumbnail
rx_theme_content_show_meta
rx_theme_content_show_categories
rx_theme_content_show_excerpt_above
rx_theme_content_archive_show_excerpt
rx_theme_content_show_read_more
rx_theme_content_show_tags
rx_theme_content_show_author_box
rx_theme_content_show_share_links
rx_theme_content_post_views
For example, you can disable share links from functions.php:
add_filter( 'rx_theme_content_show_share_links', '__return_false' );
Or disable archive excerpts and show full content:
add_filter( 'rx_theme_content_archive_show_excerpt', '__return_false' );