inc/template-parts/content.php template for your RX theme, including post formats, accessibility, schema-ready markup, thumbnails, meta, sharing hooks, pagination, related extension hooks, ads/widget hooks, and safe fallback handling.Below is an advanced, big, feature-rich inc/template-parts/content.php file for your RX theme. It is made for WordPress posts, pages, search results, archives, sticky posts, post formats, schema markup, thumbnails, meta, categories, tags, reading time, share hooks, edit links, pagination, accessibility, and future extension hooks.
Create or replace this file:
<?php
/**
* Template part for displaying post/page content.
*
* File: inc/template-parts/content.php
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
/**
* --------------------------------------------------------------------------
* Safety helper fallbacks
* --------------------------------------------------------------------------
* These fallback functions prevent fatal errors if your theme helper files
* are not loaded yet. Later, you can move these helpers to:
*
* inc/template-functions.php
* inc/helpers/template-tags.php
* inc/helpers/content.php
* --------------------------------------------------------------------------
*/
if ( ! function_exists( 'rx_theme_get_post_reading_time' ) ) {
/**
* Get estimated reading time.
*
* @param int|null $post_id Post ID.
* @return string
*/
function rx_theme_get_post_reading_time( $post_id = null ) {
$post_id = $post_id ? absint( $post_id ) : get_the_ID();
$content = get_post_field( 'post_content', $post_id );
$word_count = str_word_count( wp_strip_all_tags( $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 )
);
}
}
if ( ! function_exists( 'rx_theme_get_primary_category' ) ) {
/**
* Get first category as primary category fallback.
*
* @param int|null $post_id Post ID.
* @return WP_Term|null
*/
function rx_theme_get_primary_category( $post_id = null ) {
$post_id = $post_id ? absint( $post_id ) : get_the_ID();
$categories = get_the_category( $post_id );
if ( ! empty( $categories ) && ! is_wp_error( $categories ) ) {
return $categories[0];
}
return null;
}
}
if ( ! function_exists( 'rx_theme_get_post_thumbnail_alt' ) ) {
/**
* Get post thumbnail alt text.
*
* @param int|null $post_id Post ID.
* @return string
*/
function rx_theme_get_post_thumbnail_alt( $post_id = null ) {
$post_id = $post_id ? absint( $post_id ) : get_the_ID();
$thumbnail_id = get_post_thumbnail_id( $post_id );
if ( ! $thumbnail_id ) {
return '';
}
$alt = get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true );
if ( empty( $alt ) ) {
$alt = get_the_title( $post_id );
}
return esc_attr( $alt );
}
}
if ( ! function_exists( 'rx_theme_post_classes' ) ) {
/**
* Custom article classes.
*
* @return string
*/
function rx_theme_post_classes() {
$classes = array();
if ( is_singular() ) {
$classes[] = 'rx-content-single';
} else {
$classes[] = 'rx-content-card';
}
if ( is_sticky() && is_home() && ! is_paged() ) {
$classes[] = 'rx-content-sticky';
}
if ( has_post_thumbnail() ) {
$classes[] = 'rx-has-thumbnail';
} else {
$classes[] = 'rx-no-thumbnail';
}
$post_format = get_post_format();
if ( $post_format ) {
$classes[] = 'rx-format-' . sanitize_html_class( $post_format );
}
return implode( ' ', array_map( 'sanitize_html_class', $classes ) );
}
}
if ( ! function_exists( 'rx_theme_entry_meta' ) ) {
/**
* Display post meta.
*
* @return void
*/
function rx_theme_entry_meta() {
?>
<div class="rx-entry-meta" aria-label="<?php esc_attr_e( 'Post information', 'rx-theme' ); ?>">
<span class="rx-meta-item rx-meta-author">
<span class="rx-meta-label"><?php esc_html_e( 'By', 'rx-theme' ); ?></span>
<a href="<?php echo esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ); ?>" class="rx-author-link" rel="author">
<?php echo esc_html( get_the_author() ); ?>
</a>
</span>
<span class="rx-meta-separator" aria-hidden="true">•</span>
<span class="rx-meta-item rx-meta-date">
<a href="<?php echo esc_url( get_permalink() ); ?>" rel="bookmark">
<time class="entry-date published" datetime="<?php echo esc_attr( get_the_date( DATE_W3C ) ); ?>">
<?php echo esc_html( get_the_date() ); ?>
</time>
<?php if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) : ?>
<time class="updated rx-screen-reader-text" datetime="<?php echo esc_attr( get_the_modified_date( DATE_W3C ) ); ?>">
<?php echo esc_html( get_the_modified_date() ); ?>
</time>
<?php endif; ?>
</a>
</span>
<?php if ( comments_open() || get_comments_number() ) : ?>
<span class="rx-meta-separator" aria-hidden="true">•</span>
<span class="rx-meta-item rx-meta-comments">
<?php
comments_popup_link(
esc_html__( 'No comments', 'rx-theme' ),
esc_html__( '1 comment', 'rx-theme' ),
esc_html__( '% comments', 'rx-theme' ),
'rx-comments-link'
);
?>
</span>
<?php endif; ?>
<span class="rx-meta-separator" aria-hidden="true">•</span>
<span class="rx-meta-item rx-meta-reading-time">
<?php echo esc_html( rx_theme_get_post_reading_time() ); ?>
</span>
</div>
<?php
}
}
if ( ! function_exists( 'rx_theme_entry_taxonomies' ) ) {
/**
* Display categories and tags.
*
* @return void
*/
function rx_theme_entry_taxonomies() {
if ( 'post' !== get_post_type() ) {
return;
}
$categories = get_the_category_list( esc_html__( ', ', 'rx-theme' ) );
$tags = get_the_tag_list( '', esc_html__( ', ', 'rx-theme' ) );
if ( ! $categories && ! $tags ) {
return;
}
?>
<footer class="rx-entry-taxonomies" aria-label="<?php esc_attr_e( 'Post taxonomies', 'rx-theme' ); ?>">
<?php if ( $categories ) : ?>
<div class="rx-entry-categories">
<span class="rx-taxonomy-label"><?php esc_html_e( 'Categories:', 'rx-theme' ); ?></span>
<span class="rx-taxonomy-links"><?php echo wp_kses_post( $categories ); ?></span>
</div>
<?php endif; ?>
<?php if ( $tags ) : ?>
<div class="rx-entry-tags">
<span class="rx-taxonomy-label"><?php esc_html_e( 'Tags:', 'rx-theme' ); ?></span>
<span class="rx-taxonomy-links"><?php echo wp_kses_post( $tags ); ?></span>
</div>
<?php endif; ?>
</footer>
<?php
}
}
if ( ! function_exists( 'rx_theme_share_links' ) ) {
/**
* Display simple share links.
*
* @return void
*/
function rx_theme_share_links() {
if ( ! is_singular() ) {
return;
}
$post_url = rawurlencode( get_permalink() );
$post_title = rawurlencode( get_the_title() );
?>
<div class="rx-share-box" aria-label="<?php esc_attr_e( 'Share this post', 'rx-theme' ); ?>">
<span class="rx-share-title"><?php esc_html_e( 'Share:', 'rx-theme' ); ?></span>
<a class="rx-share-link rx-share-facebook" href="<?php echo esc_url( 'https://www.facebook.com/sharer/sharer.php?u=' . $post_url ); ?>" target="_blank" rel="nofollow noopener noreferrer">
<?php esc_html_e( 'Facebook', 'rx-theme' ); ?>
</a>
<a class="rx-share-link rx-share-x" href="<?php echo esc_url( 'https://twitter.com/intent/tweet?url=' . $post_url . '&text=' . $post_title ); ?>" target="_blank" rel="nofollow noopener noreferrer">
<?php esc_html_e( 'X', 'rx-theme' ); ?>
</a>
<a class="rx-share-link rx-share-linkedin" href="<?php echo esc_url( 'https://www.linkedin.com/sharing/share-offsite/?url=' . $post_url ); ?>" target="_blank" rel="nofollow noopener noreferrer">
<?php esc_html_e( 'LinkedIn', 'rx-theme' ); ?>
</a>
<a class="rx-share-link rx-share-whatsapp" href="<?php echo esc_url( 'https://api.whatsapp.com/send?text=' . $post_title . '%20' . $post_url ); ?>" target="_blank" rel="nofollow noopener noreferrer">
<?php esc_html_e( 'WhatsApp', 'rx-theme' ); ?>
</a>
</div>
<?php
}
}
if ( ! function_exists( 'rx_theme_post_schema_attrs' ) ) {
/**
* Article schema attributes.
*
* @return string
*/
function rx_theme_post_schema_attrs() {
if ( 'post' === get_post_type() ) {
return 'itemscope itemtype="https://schema.org/Article"';
}
if ( 'page' === get_post_type() ) {
return 'itemscope itemtype="https://schema.org/WebPage"';
}
return 'itemscope itemtype="https://schema.org/CreativeWork"';
}
}
if ( ! function_exists( 'rx_theme_post_format_label' ) ) {
/**
* Post format visible label.
*
* @return void
*/
function rx_theme_post_format_label() {
$format = get_post_format();
if ( ! $format ) {
return;
}
$labels = array(
'aside' => esc_html__( 'Aside', 'rx-theme' ),
'gallery' => esc_html__( 'Gallery', 'rx-theme' ),
'link' => esc_html__( 'Link', 'rx-theme' ),
'image' => esc_html__( 'Image', 'rx-theme' ),
'quote' => esc_html__( 'Quote', 'rx-theme' ),
'status' => esc_html__( 'Status', 'rx-theme' ),
'video' => esc_html__( 'Video', 'rx-theme' ),
'audio' => esc_html__( 'Audio', 'rx-theme' ),
'chat' => esc_html__( 'Chat', 'rx-theme' ),
);
if ( isset( $labels[ $format ] ) ) :
?>
<span class="rx-post-format-label rx-format-label-<?php echo esc_attr( $format ); ?>">
<?php echo esc_html( $labels[ $format ] ); ?>
</span>
<?php
endif;
}
}
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( rx_theme_post_classes() ); ?> <?php echo rx_theme_post_schema_attrs(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<?php
/**
* Hook: rx_theme_before_article
*
* Useful for ads, badges, breadcrumbs, analytics markers,
* custom notices, membership labels, or future modules.
*/
do_action( 'rx_theme_before_article', get_the_ID() );
?>
<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
<div class="rx-sticky-badge" aria-label="<?php esc_attr_e( 'Featured post', 'rx-theme' ); ?>">
<?php esc_html_e( 'Featured', 'rx-theme' ); ?>
</div>
<?php endif; ?>
<header class="rx-entry-header entry-header">
<?php
/**
* Hook: rx_theme_before_entry_header
*/
do_action( 'rx_theme_before_entry_header', get_the_ID() );
?>
<?php if ( 'post' === get_post_type() ) : ?>
<?php $primary_category = rx_theme_get_primary_category(); ?>
<?php if ( $primary_category ) : ?>
<div class="rx-primary-category">
<a href="<?php echo esc_url( get_category_link( $primary_category->term_id ) ); ?>">
<?php echo esc_html( $primary_category->name ); ?>
</a>
</div>
<?php endif; ?>
<?php endif; ?>
<?php rx_theme_post_format_label(); ?>
<?php
if ( is_singular() ) :
the_title(
'<h1 class="rx-entry-title entry-title" itemprop="headline">',
'</h1>'
);
else :
the_title(
'<h2 class="rx-entry-title entry-title" itemprop="headline"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">',
'</a></h2>'
);
endif;
?>
<?php if ( 'post' === get_post_type() ) : ?>
<?php rx_theme_entry_meta(); ?>
<?php endif; ?>
<?php
/**
* Hook: rx_theme_after_entry_header
*/
do_action( 'rx_theme_after_entry_header', get_the_ID() );
?>
</header>
<?php
/**
* Hook: rx_theme_before_thumbnail
*/
do_action( 'rx_theme_before_thumbnail', get_the_ID() );
?>
<?php if ( has_post_thumbnail() ) : ?>
<figure class="rx-entry-thumbnail post-thumbnail" itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<?php if ( is_singular() ) : ?>
<?php
the_post_thumbnail(
'full',
array(
'class' => 'rx-featured-image',
'alt' => rx_theme_get_post_thumbnail_alt(),
'loading' => 'eager',
'decoding' => 'async',
)
);
?>
<?php else : ?>
<a href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php
the_post_thumbnail(
'large',
array(
'class' => 'rx-card-image',
'alt' => rx_theme_get_post_thumbnail_alt(),
'loading' => 'lazy',
'decoding' => 'async',
)
);
?>
</a>
<?php endif; ?>
<?php
$thumbnail_id = get_post_thumbnail_id();
$caption = wp_get_attachment_caption( $thumbnail_id );
$image_src = wp_get_attachment_image_src( $thumbnail_id, 'full' );
if ( $image_src ) :
?>
<meta itemprop="url" content="<?php echo esc_url( $image_src[0] ); ?>">
<meta itemprop="width" content="<?php echo esc_attr( $image_src[1] ); ?>">
<meta itemprop="height" content="<?php echo esc_attr( $image_src[2] ); ?>">
<?php endif; ?>
<?php if ( is_singular() && $caption ) : ?>
<figcaption class="rx-thumbnail-caption">
<?php echo wp_kses_post( $caption ); ?>
</figcaption>
<?php endif; ?>
</figure>
<?php endif; ?>
<?php
/**
* Hook: rx_theme_after_thumbnail
*/
do_action( 'rx_theme_after_thumbnail', get_the_ID() );
?>
<?php if ( is_singular() ) : ?>
<div class="rx-entry-content entry-content" itemprop="articleBody">
<?php
/**
* Hook: rx_theme_before_entry_content
*/
do_action( 'rx_theme_before_entry_content', get_the_ID() );
?>
<?php
the_content(
sprintf(
wp_kses(
/* translators: %s: post title */
__( 'Continue reading<span class="rx-screen-reader-text"> "%s"</span>', 'rx-theme' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
)
);
?>
<?php
wp_link_pages(
array(
'before' => '<nav class="rx-page-links page-links" aria-label="' . esc_attr__( 'Post pages', 'rx-theme' ) . '"><span class="rx-page-links-title">' . esc_html__( 'Pages:', 'rx-theme' ) . '</span>',
'after' => '</nav>',
'link_before' => '<span class="rx-page-number">',
'link_after' => '</span>',
)
);
?>
<?php
/**
* Hook: rx_theme_after_entry_content
*/
do_action( 'rx_theme_after_entry_content', get_the_ID() );
?>
</div>
<?php else : ?>
<div class="rx-entry-summary entry-summary">
<?php
/**
* Hook: rx_theme_before_entry_summary
*/
do_action( 'rx_theme_before_entry_summary', get_the_ID() );
?>
<?php if ( has_excerpt() ) : ?>
<?php the_excerpt(); ?>
<?php else : ?>
<p>
<?php
echo esc_html(
wp_trim_words(
wp_strip_all_tags( get_the_content() ),
35,
'...'
)
);
?>
</p>
<?php endif; ?>
<a class="rx-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>
<?php
/**
* Hook: rx_theme_after_entry_summary
*/
do_action( 'rx_theme_after_entry_summary', get_the_ID() );
?>
</div>
<?php endif; ?>
<footer class="rx-entry-footer entry-footer">
<?php
/**
* Hook: rx_theme_before_entry_footer
*/
do_action( 'rx_theme_before_entry_footer', get_the_ID() );
?>
<?php rx_theme_entry_taxonomies(); ?>
<?php rx_theme_share_links(); ?>
<?php if ( is_singular() && get_the_author_meta( 'description' ) ) : ?>
<section class="rx-author-box" aria-label="<?php esc_attr_e( 'Author information', 'rx-theme' ); ?>">
<div class="rx-author-avatar">
<?php echo get_avatar( get_the_author_meta( 'ID' ), 96, '', get_the_author(), array( 'class' => 'rx-avatar' ) ); ?>
</div>
<div class="rx-author-content">
<h2 class="rx-author-title">
<?php esc_html_e( 'About the author', 'rx-theme' ); ?>
</h2>
<h3 class="rx-author-name">
<a href="<?php echo esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ); ?>">
<?php echo esc_html( get_the_author() ); ?>
</a>
</h3>
<p class="rx-author-description">
<?php echo wp_kses_post( get_the_author_meta( 'description' ) ); ?>
</p>
</div>
</section>
<?php endif; ?>
<?php if ( is_singular() ) : ?>
<nav class="rx-post-navigation" aria-label="<?php esc_attr_e( 'Post navigation', 'rx-theme' ); ?>">
<?php
the_post_navigation(
array(
'prev_text' => '<span class="rx-nav-subtitle">' . esc_html__( 'Previous:', 'rx-theme' ) . '</span> <span class="rx-nav-title">%title</span>',
'next_text' => '<span class="rx-nav-subtitle">' . esc_html__( 'Next:', 'rx-theme' ) . '</span> <span class="rx-nav-title">%title</span>',
)
);
?>
</nav>
<?php endif; ?>
<?php
edit_post_link(
sprintf(
wp_kses(
/* translators: %s: post title */
__( 'Edit <span class="rx-screen-reader-text">%s</span>', 'rx-theme' ),
array(
'span' => array(
'class' => array(),
),
)
),
wp_kses_post( get_the_title() )
),
'<div class="rx-edit-link">',
'</div>'
);
?>
<?php
/**
* Hook: rx_theme_after_entry_footer
*/
do_action( 'rx_theme_after_entry_footer', get_the_ID() );
?>
</footer>
<?php
/**
* Hook: rx_theme_after_article
*
* You can use this for:
* - Related posts
* - Newsletter box
* - AdSense block
* - Author social links
* - Medical disclaimer
* - Affiliate disclaimer
* - Dynamic table of contents
*/
do_action( 'rx_theme_after_article', get_the_ID() );
?>
<?php if ( is_singular() ) : ?>
<meta itemprop="mainEntityOfPage" content="<?php echo esc_url( get_permalink() ); ?>">
<meta itemprop="datePublished" content="<?php echo esc_attr( get_the_date( DATE_W3C ) ); ?>">
<meta itemprop="dateModified" content="<?php echo esc_attr( get_the_modified_date( DATE_W3C ) ); ?>">
<meta itemprop="author" content="<?php echo esc_attr( get_the_author() ); ?>">
<meta itemprop="publisher" content="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>">
<?php endif; ?>
</article>
Also add this small CSS to your theme stylesheet for screen-reader text and better structure:
.rx-screen-reader-text {
position: absolute !important;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.rx-content-card,
.rx-content-single {
position: relative;
margin-bottom: 2rem;
}
.rx-entry-thumbnail img {
width: 100%;
height: auto;
display: block;
}
.rx-entry-meta,
.rx-entry-taxonomies,
.rx-share-box {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.rx-sticky-badge,
.rx-post-format-label,
.rx-primary-category {
display: inline-block;
margin-bottom: 0.5rem;
font-size: 0.875rem;
font-weight: 600;
}
.rx-read-more {
display: inline-flex;
align-items: center;
gap: 0.25rem;
margin-top: 1rem;
font-weight: 600;
}
.rx-author-box {
display: flex;
gap: 1rem;
margin-top: 2rem;
padding-top: 2rem;
border-top: 1px solid currentColor;
}
.rx-author-avatar img {
border-radius: 50%;
}
To load this template inside your main theme files, use:
<?php get_template_part( 'inc/template-parts/content' ); ?>
Example inside index.php, archive.php, or search.php:
<?php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
get_template_part( 'inc/template-parts/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( 'inc/template-parts/content', 'none' );
endif;
?>
This file is intentionally powerful but still safe. Later you can connect more advanced RX theme modules through these hooks:
do_action( 'rx_theme_before_article', get_the_ID() );
do_action( 'rx_theme_after_article', get_the_ID() );
do_action( 'rx_theme_before_entry_content', get_the_ID() );
do_action( 'rx_theme_after_entry_content', get_the_ID() );
do_action( 'rx_theme_after_entry_footer', get_the_ID() );
These hooks will help you add ads, related posts, medical disclaimers, affiliate notices, newsletter boxes, schema modules, or custom RX widgets without editing content.php again.