content-single.php

I’ll build this as a full advanced content-single.php template for your RX Theme, including SEO-friendly article markup, author box, breadcrumbs hooks, sharing, related areas, post meta, schema-ready structure, pagination, comments, ads/hooks, and safe WordPress escaping.

Yes friend — this file can be very powerful. Below is an advanced RX Theme single post template for:

template-parts/content/content-single.php

It uses safe WordPress escaping, semantic <article> markup, featured image, categories, tags, author box, reading time fallback, share buttons, post pagination, previous/next navigation, comments, edit link, hooks for ads/plugins, and schema-friendly structure. WordPress supports dynamic template tags such as the_content(), wp_link_pages(), comments_template(), and author meta functions for templates. get_the_author_meta() returns author data for use in PHP, especially inside the Loop.

<?php
/**
 * Template part for displaying single posts
 *
 * Path: template-parts/content/content-single.php
 *
 * @package RX_Theme
 */

defined( 'ABSPATH' ) || exit;

$post_id        = get_the_ID();
$author_id      = (int) get_post_field( 'post_author', $post_id );
$permalink      = get_permalink( $post_id );
$title          = get_the_title( $post_id );
$excerpt        = has_excerpt( $post_id ) ? get_the_excerpt( $post_id ) : wp_trim_words( wp_strip_all_tags( get_the_content() ), 32 );
$published_time = get_the_date( DATE_W3C, $post_id );
$modified_time  = get_the_modified_date( DATE_W3C, $post_id );
$author_name    = get_the_author_meta( 'display_name', $author_id );
$author_url     = get_author_posts_url( $author_id );
$author_bio     = get_the_author_meta( 'description', $author_id );
$comment_count  = get_comments_number( $post_id );

/**
 * Reading time fallback.
 * If you already have rx_reading_time(), it will use your function.
 */
if ( function_exists( 'rx_reading_time' ) ) {
	$reading_time = rx_reading_time( $post_id );
} else {
	$content_plain = wp_strip_all_tags( get_post_field( 'post_content', $post_id ) );
	$word_count    = str_word_count( $content_plain );
	$minutes       = max( 1, ceil( $word_count / 200 ) );
	$reading_time  = sprintf(
		/* translators: %d: reading minutes */
		_n( '%d min read', '%d min read', $minutes, 'rx-theme' ),
		$minutes
	);
}

$categories_list = get_the_category_list( esc_html__( ', ', 'rx-theme' ) );
$tags_list       = get_the_tag_list( '', esc_html__( ', ', 'rx-theme' ) );
?>

<article id="post-<?php the_ID(); ?>" <?php post_class( 'rx-single-post rx-article hentry' ); ?> itemscope itemtype="https://schema.org/Article">

	<?php
	/**
	 * Hook before full single article.
	 * Useful for ads, notices, breadcrumbs, custom banners.
	 */
	do_action( 'rx_before_single_article', $post_id );
	?>

	<header class="rx-single-header entry-header">

		<?php
		/**
		 * Breadcrumbs support.
		 * Use your helper function if available.
		 */
		if ( function_exists( 'rx_breadcrumbs' ) ) :
			?>
			<nav class="rx-breadcrumbs-wrap" aria-label="<?php esc_attr_e( 'Breadcrumbs', 'rx-theme' ); ?>">
				<?php rx_breadcrumbs(); ?>
			</nav>
		<?php endif; ?>

		<?php if ( $categories_list ) : ?>
			<div class="rx-single-categories entry-categories">
				<span class="screen-reader-text"><?php esc_html_e( 'Categories:', 'rx-theme' ); ?></span>
				<?php echo wp_kses_post( $categories_list ); ?>
			</div>
		<?php endif; ?>

		<?php the_title( '<h1 class="rx-single-title entry-title" itemprop="headline">', '</h1>' ); ?>

		<?php if ( ! empty( $excerpt ) ) : ?>
			<p class="rx-single-excerpt" itemprop="description">
				<?php echo esc_html( $excerpt ); ?>
			</p>
		<?php endif; ?>

		<div class="rx-single-meta entry-meta">

			<span class="rx-meta-item rx-meta-author" itemprop="author" itemscope itemtype="https://schema.org/Person">
				<?php echo get_avatar( $author_id, 36, '', esc_attr( $author_name ), array( 'class' => 'rx-author-avatar' ) ); ?>
				<span><?php esc_html_e( 'By', 'rx-theme' ); ?></span>
				<a href="<?php echo esc_url( $author_url ); ?>" rel="author" itemprop="url">
					<span itemprop="name"><?php echo esc_html( $author_name ); ?></span>
				</a>
			</span>

			<span class="rx-meta-separator" aria-hidden="true"></span>

			<span class="rx-meta-item rx-meta-date">
				<time class="published" datetime="<?php echo esc_attr( $published_time ); ?>" itemprop="datePublished">
					<?php echo esc_html( get_the_date( '', $post_id ) ); ?>
				</time>
			</span>

			<?php if ( get_the_modified_time( 'U', $post_id ) > get_the_time( 'U', $post_id ) ) : ?>
				<span class="rx-meta-separator" aria-hidden="true"></span>
				<span class="rx-meta-item rx-meta-updated">
					<?php esc_html_e( 'Updated:', 'rx-theme' ); ?>
					<time class="updated" datetime="<?php echo esc_attr( $modified_time ); ?>" itemprop="dateModified">
						<?php echo esc_html( get_the_modified_date( '', $post_id ) ); ?>
					</time>
				</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( $reading_time ); ?>
			</span>

			<?php if ( comments_open() || $comment_count ) : ?>
				<span class="rx-meta-separator" aria-hidden="true"></span>
				<a class="rx-meta-item rx-meta-comments" href="<?php echo esc_url( get_comments_link( $post_id ) ); ?>">
					<?php
					printf(
						esc_html(
							_n(
								'%s Comment',
								'%s Comments',
								$comment_count,
								'rx-theme'
							)
						),
						esc_html( number_format_i18n( $comment_count ) )
					);
					?>
				</a>
			<?php endif; ?>

		</div>

		<?php
		/**
		 * Hook after title/meta.
		 */
		do_action( 'rx_after_single_header', $post_id );
		?>

	</header>

	<?php if ( has_post_thumbnail() ) : ?>
		<figure class="rx-single-featured-image post-thumbnail" itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
			<?php
			the_post_thumbnail(
				'full',
				array(
					'class'    => 'rx-featured-img',
					'loading'  => 'eager',
					'decoding' => 'async',
					'alt'      => the_title_attribute(
						array(
							'echo' => false,
						)
					),
					'itemprop' => 'url',
				)
			);
			?>

			<?php
			$thumbnail_id      = get_post_thumbnail_id( $post_id );
			$thumbnail_caption = wp_get_attachment_caption( $thumbnail_id );
			?>

			<?php if ( $thumbnail_caption ) : ?>
				<figcaption class="rx-featured-caption">
					<?php echo wp_kses_post( $thumbnail_caption ); ?>
				</figcaption>
			<?php endif; ?>
		</figure>
	<?php endif; ?>

	<?php
	/**
	 * Hook before content.
	 * Good place for top ad, affiliate disclosure, medical disclaimer, table of contents.
	 */
	do_action( 'rx_before_single_content', $post_id );
	?>

	<div class="rx-single-layout">

		<main class="rx-single-main" id="primary-single-content">

			<?php
			/**
			 * Optional table of contents template.
			 * Create: template-parts/components/table-of-contents.php
			 */
			if ( locate_template( 'template-parts/components/table-of-contents.php' ) ) :
				get_template_part( 'template-parts/components/table-of-contents' );
			endif;
			?>

			<div class="rx-single-content entry-content" itemprop="articleBody">

				<?php
				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(),
								),
							)
						),
						esc_html( $title )
					)
				);

				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>',
					)
				);
				?>

			</div>

			<?php
			/**
			 * Hook after content.
			 * Good place for bottom ad, newsletter form, CTA, medical disclaimer.
			 */
			do_action( 'rx_after_single_content', $post_id );
			?>

			<footer class="rx-single-footer entry-footer">

				<?php if ( $tags_list ) : ?>
					<div class="rx-single-tags">
						<span class="rx-tags-title"><?php esc_html_e( 'Tags:', 'rx-theme' ); ?></span>
						<?php echo wp_kses_post( $tags_list ); ?>
					</div>
				<?php endif; ?>

				<div class="rx-single-share" aria-label="<?php esc_attr_e( 'Share this article', '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=' . rawurlencode( $permalink ) ); ?>"
					   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=' . rawurlencode( $permalink ) . '&text=' . rawurlencode( $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/shareArticle?mini=true&url=' . rawurlencode( $permalink ) . '&title=' . rawurlencode( $title ) ); ?>"
					   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=' . rawurlencode( $title . ' ' . $permalink ) ); ?>"
					   target="_blank"
					   rel="nofollow noopener noreferrer">
						<?php esc_html_e( 'WhatsApp', 'rx-theme' ); ?>
					</a>

					<a class="rx-share-link rx-share-email"
					   href="<?php echo esc_url( 'mailto:?subject=' . rawurlencode( $title ) . '&body=' . rawurlencode( $permalink ) ); ?>">
						<?php esc_html_e( 'Email', 'rx-theme' ); ?>
					</a>
				</div>

				<?php
				edit_post_link(
					esc_html__( 'Edit this post', 'rx-theme' ),
					'<div class="rx-edit-link">',
					'</div>'
				);
				?>

			</footer>

			<?php
			/**
			 * Author box.
			 */
			if ( $author_bio ) :
				?>
				<section class="rx-author-box" itemprop="author" itemscope itemtype="https://schema.org/Person">
					<div class="rx-author-box-avatar">
						<?php echo get_avatar( $author_id, 96, '', esc_attr( $author_name ) ); ?>
					</div>

					<div class="rx-author-box-content">
						<h2 class="rx-author-box-title">
							<?php esc_html_e( 'About the Author', 'rx-theme' ); ?>
						</h2>

						<h3 class="rx-author-name" itemprop="name">
							<a href="<?php echo esc_url( $author_url ); ?>" itemprop="url">
								<?php echo esc_html( $author_name ); ?>
							</a>
						</h3>

						<p class="rx-author-description" itemprop="description">
							<?php echo esc_html( $author_bio ); ?>
						</p>

						<a class="rx-author-posts-link" href="<?php echo esc_url( $author_url ); ?>">
							<?php esc_html_e( 'View all posts', 'rx-theme' ); ?>
						</a>
					</div>
				</section>
			<?php endif; ?>

			<?php
			/**
			 * Previous / next post navigation.
			 */
			the_post_navigation(
				array(
					'prev_text' => '<span class="nav-subtitle">' . esc_html__( 'Previous Article', 'rx-theme' ) . '</span><span class="nav-title">%title</span>',
					'next_text' => '<span class="nav-subtitle">' . esc_html__( 'Next Article', 'rx-theme' ) . '</span><span class="nav-title">%title</span>',
					'class'     => 'rx-post-navigation',
				)
			);
			?>

			<?php
			/**
			 * Related posts support.
			 * Recommended file:
			 * template-parts/content/related-posts.php
			 */
			if ( locate_template( 'template-parts/content/related-posts.php' ) ) :
				get_template_part( 'template-parts/content/related-posts' );
			elseif ( function_exists( 'rx_related_posts' ) ) :
				rx_related_posts( $post_id );
			endif;
			?>

			<?php
			/**
			 * Comments.
			 * Usually comments_template() can be placed in single.php,
			 * but it is also okay here when this template is only used for single posts.
			 */
			if ( comments_open() || get_comments_number() ) :
				comments_template();
			endif;
			?>

		</main>

		<?php
		/**
		 * Optional single sidebar template.
		 * Create: template-parts/sidebar/sidebar-single.php
		 */
		if ( locate_template( 'template-parts/sidebar/sidebar-single.php' ) ) :
			?>
			<aside class="rx-single-sidebar" aria-label="<?php esc_attr_e( 'Single post sidebar', 'rx-theme' ); ?>">
				<?php get_template_part( 'template-parts/sidebar/sidebar-single' ); ?>
			</aside>
		<?php endif; ?>

	</div>

	<?php
	/**
	 * Hook after full single article.
	 */
	do_action( 'rx_after_single_article', $post_id );
	?>

	<meta itemprop="mainEntityOfPage" content="<?php echo esc_url( $permalink ); ?>">
	<meta itemprop="url" content="<?php echo esc_url( $permalink ); ?>">
	<meta itemprop="datePublished" content="<?php echo esc_attr( $published_time ); ?>">
	<meta itemprop="dateModified" content="<?php echo esc_attr( $modified_time ); ?>">

	<?php if ( has_post_thumbnail() ) : ?>
		<meta itemprop="thumbnailUrl" content="<?php echo esc_url( get_the_post_thumbnail_url( $post_id, 'full' ) ); ?>">
	<?php endif; ?>

	<span class="screen-reader-text" itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
		<span itemprop="name"><?php echo esc_html( get_bloginfo( 'name' ) ); ?></span>
	</span>

</article>

Extra CSS classes this template gives you

You can style these in style.css:

.rx-single-post {}
.rx-single-header {}
.rx-single-title {}
.rx-single-excerpt {}
.rx-single-meta {}
.rx-single-featured-image {}
.rx-single-content {}
.rx-single-footer {}
.rx-single-tags {}
.rx-single-share {}
.rx-author-box {}
.rx-post-navigation {}
.rx-single-layout {}
.rx-single-main {}
.rx-single-sidebar {}

Best related files to create next

For this template to become even more powerful, create these optional files:

template-parts/components/table-of-contents.php
template-parts/content/related-posts.php
template-parts/sidebar/sidebar-single.php

Then this content-single.php will automatically load them when they exist.

Leave a Reply

Your email address will not be published. Required fields are marked *