template-left-sidebar.php

I’ll build this as a real WordPress page template file for templates/template-left-sidebar.php, with safe escaping, hooks, schema support, accessibility, breadcrumbs area, featured media, pagination, comments, and flexible sidebar fallback.

Friend, create this file here:

rx-theme/templates/template-left-sidebar.php

Then paste this full code:

<?php
/**
 * Template Name: RX Left Sidebar
 * Template Post Type: page, post
 *
 * Advanced left-sidebar layout template for RX Theme.
 *
 * @package RX_Theme
 * @since 1.0.0
 */

defined( 'ABSPATH' ) || exit;

get_header();

/**
 * ------------------------------------------------------------
 * Template variables
 * ------------------------------------------------------------
 */

$rx_post_id          = get_queried_object_id();
$rx_post_type        = get_post_type( $rx_post_id );
$rx_sidebar_id       = 'rx-left-sidebar';
$rx_has_sidebar      = is_active_sidebar( $rx_sidebar_id );
$rx_show_breadcrumbs = true;
$rx_show_featured    = true;
$rx_show_author_box  = true;
$rx_show_comments    = true;
$rx_show_related     = true;
$rx_show_toc         = true;

/**
 * Allow child theme or plugins to modify template options.
 */
$rx_template_options = apply_filters(
	'rx_theme_left_sidebar_template_options',
	array(
		'post_id'          => $rx_post_id,
		'post_type'        => $rx_post_type,
		'sidebar_id'       => $rx_sidebar_id,
		'has_sidebar'      => $rx_has_sidebar,
		'show_breadcrumbs' => $rx_show_breadcrumbs,
		'show_featured'    => $rx_show_featured,
		'show_author_box'  => $rx_show_author_box,
		'show_comments'    => $rx_show_comments,
		'show_related'     => $rx_show_related,
		'show_toc'         => $rx_show_toc,
	)
);

$rx_sidebar_id       = ! empty( $rx_template_options['sidebar_id'] ) ? sanitize_key( $rx_template_options['sidebar_id'] ) : 'rx-left-sidebar';
$rx_has_sidebar      = ! empty( $rx_template_options['has_sidebar'] );
$rx_show_breadcrumbs = ! empty( $rx_template_options['show_breadcrumbs'] );
$rx_show_featured    = ! empty( $rx_template_options['show_featured'] );
$rx_show_author_box  = ! empty( $rx_template_options['show_author_box'] );
$rx_show_comments    = ! empty( $rx_template_options['show_comments'] );
$rx_show_related     = ! empty( $rx_template_options['show_related'] );
$rx_show_toc         = ! empty( $rx_template_options['show_toc'] );

/**
 * ------------------------------------------------------------
 * Helper fallback functions
 * These are inside function_exists checks, so later you can move
 * them to inc/helpers/template-functions.php safely.
 * ------------------------------------------------------------
 */

if ( ! function_exists( 'rx_theme_get_primary_category' ) ) {
	/**
	 * Get primary category fallback.
	 *
	 * @param int $post_id Post ID.
	 * @return WP_Term|null
	 */
	function rx_theme_get_primary_category( $post_id ) {
		$categories = get_the_category( $post_id );

		if ( empty( $categories ) || is_wp_error( $categories ) ) {
			return null;
		}

		return $categories[0];
	}
}

if ( ! function_exists( 'rx_theme_estimated_reading_time' ) ) {
	/**
	 * Estimate reading time.
	 *
	 * @param int $post_id Post ID.
	 * @return string
	 */
	function rx_theme_estimated_reading_time( $post_id ) {
		$content    = get_post_field( 'post_content', $post_id );
		$word_count = str_word_count( wp_strip_all_tags( strip_shortcodes( $content ) ) );
		$minutes    = max( 1, (int) ceil( $word_count / 200 ) );

		return sprintf(
			/* translators: %d: minutes */
			_n( '%d min read', '%d min read', $minutes, 'rx-theme' ),
			$minutes
		);
	}
}

if ( ! function_exists( 'rx_theme_get_post_excerpt' ) ) {
	/**
	 * Safe custom excerpt.
	 *
	 * @param int $post_id Post ID.
	 * @param int $length  Excerpt length.
	 * @return string
	 */
	function rx_theme_get_post_excerpt( $post_id, $length = 28 ) {
		$excerpt = get_the_excerpt( $post_id );

		if ( empty( $excerpt ) ) {
			$excerpt = wp_strip_all_tags( strip_shortcodes( get_post_field( 'post_content', $post_id ) ) );
		}

		return wp_trim_words( $excerpt, absint( $length ), '...' );
	}
}

if ( ! function_exists( 'rx_theme_render_breadcrumbs' ) ) {
	/**
	 * Simple breadcrumb fallback.
	 *
	 * @return void
	 */
	function rx_theme_render_breadcrumbs() {
		if ( is_front_page() ) {
			return;
		}

		echo '<nav class="rx-breadcrumbs" aria-label="' . esc_attr__( 'Breadcrumb', 'rx-theme' ) . '">';
		echo '<ol class="rx-breadcrumbs__list" itemscope itemtype="https://schema.org/BreadcrumbList">';

		echo '<li class="rx-breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
		echo '<a class="rx-breadcrumbs__link" href="' . esc_url( home_url( '/' ) ) . '" itemprop="item">';
		echo '<span itemprop="name">' . esc_html__( 'Home', 'rx-theme' ) . '</span>';
		echo '</a>';
		echo '<meta itemprop="position" content="1">';
		echo '</li>';

		$position = 2;

		if ( is_singular( 'post' ) ) {
			$category = rx_theme_get_primary_category( get_the_ID() );

			if ( $category ) {
				echo '<li class="rx-breadcrumbs__item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
				echo '<a class="rx-breadcrumbs__link" href="' . esc_url( get_category_link( $category ) ) . '" itemprop="item">';
				echo '<span itemprop="name">' . esc_html( $category->name ) . '</span>';
				echo '</a>';
				echo '<meta itemprop="position" content="' . esc_attr( $position ) . '">';
				echo '</li>';

				$position++;
			}
		}

		echo '<li class="rx-breadcrumbs__item rx-breadcrumbs__item--current" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
		echo '<span itemprop="name">' . esc_html( wp_strip_all_tags( get_the_title() ) ) . '</span>';
		echo '<meta itemprop="position" content="' . esc_attr( $position ) . '">';
		echo '</li>';

		echo '</ol>';
		echo '</nav>';
	}
}

if ( ! function_exists( 'rx_theme_render_post_toc' ) ) {
	/**
	 * Render lightweight table of contents from H2/H3 headings.
	 *
	 * @param string $content Post content.
	 * @return void
	 */
	function rx_theme_render_post_toc( $content ) {
		if ( empty( $content ) ) {
			return;
		}

		preg_match_all( '/<h([2-3])[^>]*>(.*?)<\/h[2-3]>/', $content, $matches, PREG_SET_ORDER );

		if ( empty( $matches ) || count( $matches ) < 2 ) {
			return;
		}

		echo '<aside class="rx-toc" aria-labelledby="rx-toc-title">';
		echo '<h2 id="rx-toc-title" class="rx-toc__title">' . esc_html__( 'On this page', 'rx-theme' ) . '</h2>';
		echo '<ol class="rx-toc__list">';

		foreach ( $matches as $index => $heading ) {
			$level      = absint( $heading[1] );
			$text       = wp_strip_all_tags( $heading[2] );
			$anchor     = sanitize_title( $text );
			$anchor     = $anchor ? $anchor : 'rx-heading-' . ( $index + 1 );
			$item_class = 3 === $level ? ' rx-toc__item--sub' : '';

			echo '<li class="rx-toc__item' . esc_attr( $item_class ) . '">';
			echo '<a class="rx-toc__link" href="#' . esc_attr( $anchor ) . '">' . esc_html( $text ) . '</a>';
			echo '</li>';
		}

		echo '</ol>';
		echo '</aside>';
	}
}

if ( ! function_exists( 'rx_theme_add_heading_ids_to_content' ) ) {
	/**
	 * Add IDs to H2/H3 headings for TOC anchor links.
	 *
	 * @param string $content Post content.
	 * @return string
	 */
	function rx_theme_add_heading_ids_to_content( $content ) {
		if ( empty( $content ) ) {
			return $content;
		}

		return preg_replace_callback(
			'/<h([2-3])([^>]*)>(.*?)<\/h[2-3]>/',
			static function ( $matches ) {
				$level      = $matches[1];
				$attributes = $matches[2];
				$inner_html  = $matches[3];
				$text        = wp_strip_all_tags( $inner_html );
				$id          = sanitize_title( $text );

				if ( false !== strpos( $attributes, ' id=' ) || empty( $id ) ) {
					return $matches[0];
				}

				return '<h' . esc_attr( $level ) . $attributes . ' id="' . esc_attr( $id ) . '">' . $inner_html . '</h' . esc_attr( $level ) . '>';
			},
			$content
		);
	}
}

if ( ! function_exists( 'rx_theme_render_author_box' ) ) {
	/**
	 * Render author box.
	 *
	 * @param int $post_id Post ID.
	 * @return void
	 */
	function rx_theme_render_author_box( $post_id ) {
		$author_id   = (int) get_post_field( 'post_author', $post_id );
		$author_name = get_the_author_meta( 'display_name', $author_id );
		$author_bio  = get_the_author_meta( 'description', $author_id );
		$author_url  = get_author_posts_url( $author_id );

		if ( empty( $author_name ) ) {
			return;
		}

		echo '<section class="rx-author-box" aria-labelledby="rx-author-box-title">';
		echo '<div class="rx-author-box__avatar">';
		echo get_avatar( $author_id, 96, '', esc_attr( $author_name ), array( 'class' => 'rx-author-box__image' ) );
		echo '</div>';

		echo '<div class="rx-author-box__content">';
		echo '<h2 id="rx-author-box-title" class="rx-author-box__title">' . esc_html__( 'Written by', 'rx-theme' ) . ' ';
		echo '<a class="rx-author-box__link" href="' . esc_url( $author_url ) . '">' . esc_html( $author_name ) . '</a>';
		echo '</h2>';

		if ( ! empty( $author_bio ) ) {
			echo '<p class="rx-author-box__bio">' . esc_html( $author_bio ) . '</p>';
		}

		echo '</div>';
		echo '</section>';
	}
}

if ( ! function_exists( 'rx_theme_render_related_posts' ) ) {
	/**
	 * Render related posts by category.
	 *
	 * @param int $post_id Post ID.
	 * @return void
	 */
	function rx_theme_render_related_posts( $post_id ) {
		if ( 'post' !== get_post_type( $post_id ) ) {
			return;
		}

		$category_ids = wp_get_post_categories( $post_id );

		if ( empty( $category_ids ) ) {
			return;
		}

		$related_query = new WP_Query(
			array(
				'post_type'           => 'post',
				'post_status'         => 'publish',
				'posts_per_page'      => 3,
				'post__not_in'        => array( $post_id ),
				'category__in'        => $category_ids,
				'ignore_sticky_posts' => true,
				'no_found_rows'       => true,
			)
		);

		if ( ! $related_query->have_posts() ) {
			wp_reset_postdata();
			return;
		}

		echo '<section class="rx-related-posts" aria-labelledby="rx-related-posts-title">';
		echo '<h2 id="rx-related-posts-title" class="rx-related-posts__title">' . esc_html__( 'Related Articles', 'rx-theme' ) . '</h2>';
		echo '<div class="rx-related-posts__grid">';

		while ( $related_query->have_posts() ) {
			$related_query->the_post();

			echo '<article class="rx-related-card">';
			echo '<a class="rx-related-card__link" href="' . esc_url( get_permalink() ) . '">';

			if ( has_post_thumbnail() ) {
				echo '<span class="rx-related-card__thumb">';
				the_post_thumbnail(
					'medium',
					array(
						'class'   => 'rx-related-card__image',
						'loading' => 'lazy',
					)
				);
				echo '</span>';
			}

			echo '<span class="rx-related-card__content">';
			echo '<span class="rx-related-card__title">' . esc_html( get_the_title() ) . '</span>';
			echo '<span class="rx-related-card__meta">' . esc_html( get_the_date() ) . '</span>';
			echo '</span>';

			echo '</a>';
			echo '</article>';
		}

		echo '</div>';
		echo '</section>';

		wp_reset_postdata();
	}
}

?>

<main id="primary" class="rx-site-main rx-template rx-template--left-sidebar" role="main">

	<?php
	/**
	 * Before left sidebar template.
	 */
	do_action( 'rx_theme_before_left_sidebar_template' );
	?>

	<?php if ( $rx_show_breadcrumbs ) : ?>
		<div class="rx-template__breadcrumbs">
			<?php
			if ( function_exists( 'rank_math_the_breadcrumbs' ) ) {
				rank_math_the_breadcrumbs();
			} elseif ( function_exists( 'yoast_breadcrumb' ) ) {
				yoast_breadcrumb( '<nav class="rx-breadcrumbs" aria-label="' . esc_attr__( 'Breadcrumb', 'rx-theme' ) . '">', '</nav>' );
			} else {
				rx_theme_render_breadcrumbs();
			}
			?>
		</div>
	<?php endif; ?>

	<div class="rx-container rx-container--wide">
		<div class="rx-layout rx-layout--left-sidebar <?php echo $rx_has_sidebar ? 'rx-layout--has-sidebar' : 'rx-layout--no-sidebar'; ?>">

			<?php if ( $rx_has_sidebar ) : ?>
				<aside id="secondary" class="rx-sidebar rx-sidebar--left" role="complementary" aria-label="<?php esc_attr_e( 'Left Sidebar', 'rx-theme' ); ?>">
					<div class="rx-sidebar__inner">
						<?php
						/**
						 * Before left sidebar widgets.
						 */
						do_action( 'rx_theme_before_left_sidebar_widgets' );

						dynamic_sidebar( $rx_sidebar_id );

						/**
						 * After left sidebar widgets.
						 */
						do_action( 'rx_theme_after_left_sidebar_widgets' );
						?>
					</div>
				</aside>
			<?php endif; ?>

			<section class="rx-content-area rx-content-area--left-sidebar">

				<?php
				while ( have_posts() ) :
					the_post();

					$rx_current_post_id   = get_the_ID();
					$rx_content_raw       = get_post_field( 'post_content', $rx_current_post_id );
					$rx_modified_time     = get_the_modified_time( 'c', $rx_current_post_id );
					$rx_published_time    = get_the_date( 'c', $rx_current_post_id );
					$rx_primary_category  = rx_theme_get_primary_category( $rx_current_post_id );
					$rx_reading_time      = rx_theme_estimated_reading_time( $rx_current_post_id );
					$rx_comment_count     = get_comments_number( $rx_current_post_id );
					$rx_is_password_post  = post_password_required( $rx_current_post_id );
					?>

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

						<meta itemprop="mainEntityOfPage" content="<?php echo esc_url( get_permalink() ); ?>">
						<meta itemprop="datePublished" content="<?php echo esc_attr( $rx_published_time ); ?>">
						<meta itemprop="dateModified" content="<?php echo esc_attr( $rx_modified_time ); ?>">

						<header class="rx-entry__header">

							<?php if ( $rx_primary_category ) : ?>
								<div class="rx-entry__category">
									<a class="rx-entry__category-link" href="<?php echo esc_url( get_category_link( $rx_primary_category ) ); ?>">
										<?php echo esc_html( $rx_primary_category->name ); ?>
									</a>
								</div>
							<?php endif; ?>

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

							<?php if ( has_excerpt() ) : ?>
								<p class="rx-entry__summary" itemprop="description">
									<?php echo esc_html( rx_theme_get_post_excerpt( $rx_current_post_id, 34 ) ); ?>
								</p>
							<?php endif; ?>

							<div class="rx-entry__meta" aria-label="<?php esc_attr_e( 'Article information', 'rx-theme' ); ?>">

								<span class="rx-entry__meta-item rx-entry__meta-item--author" itemprop="author" itemscope itemtype="https://schema.org/Person">
									<span class="screen-reader-text"><?php esc_html_e( 'Author:', 'rx-theme' ); ?></span>
									<a class="rx-entry__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-entry__meta-separator" aria-hidden="true"></span>

								<span class="rx-entry__meta-item rx-entry__meta-item--date">
									<span class="screen-reader-text"><?php esc_html_e( 'Published:', 'rx-theme' ); ?></span>
									<time datetime="<?php echo esc_attr( $rx_published_time ); ?>">
										<?php echo esc_html( get_the_date() ); ?>
									</time>
								</span>

								<?php if ( get_the_modified_time( 'U' ) > get_the_time( 'U' ) ) : ?>
									<span class="rx-entry__meta-separator" aria-hidden="true"></span>

									<span class="rx-entry__meta-item rx-entry__meta-item--updated">
										<span class="screen-reader-text"><?php esc_html_e( 'Updated:', 'rx-theme' ); ?></span>
										<time datetime="<?php echo esc_attr( $rx_modified_time ); ?>">
											<?php
											printf(
												/* translators: %s: modified date */
												esc_html__( 'Updated %s', 'rx-theme' ),
												esc_html( get_the_modified_date() )
											);
											?>
										</time>
									</span>
								<?php endif; ?>

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

								<span class="rx-entry__meta-item rx-entry__meta-item--reading-time">
									<?php echo esc_html( $rx_reading_time ); ?>
								</span>

								<?php if ( comments_open() || $rx_comment_count ) : ?>
									<span class="rx-entry__meta-separator" aria-hidden="true"></span>

									<a class="rx-entry__meta-item rx-entry__meta-item--comments" href="<?php echo esc_url( get_comments_link( $rx_current_post_id ) ); ?>">
										<?php
										printf(
											/* translators: %s: comment count */
											esc_html( _n( '%s Comment', '%s Comments', $rx_comment_count, 'rx-theme' ) ),
											esc_html( number_format_i18n( $rx_comment_count ) )
										);
										?>
									</a>
								<?php endif; ?>

							</div>
						</header>

						<?php if ( $rx_show_featured && has_post_thumbnail() && ! $rx_is_password_post ) : ?>
							<figure class="rx-entry__featured-media" itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
								<?php
								the_post_thumbnail(
									'large',
									array(
										'class'    => 'rx-entry__featured-image',
										'loading'  => 'eager',
										'decoding' => 'async',
										'itemprop' => 'url',
									)
								);

								$rx_thumbnail_id  = get_post_thumbnail_id();
								$rx_thumbnail_alt = get_post_meta( $rx_thumbnail_id, '_wp_attachment_image_alt', true );
								$rx_caption       = wp_get_attachment_caption( $rx_thumbnail_id );
								$rx_image_src     = wp_get_attachment_image_src( $rx_thumbnail_id, 'large' );

								if ( ! empty( $rx_image_src[0] ) ) {
									echo '<meta itemprop="url" content="' . esc_url( $rx_image_src[0] ) . '">';
								}

								if ( ! empty( $rx_image_src[1] ) ) {
									echo '<meta itemprop="width" content="' . esc_attr( $rx_image_src[1] ) . '">';
								}

								if ( ! empty( $rx_image_src[2] ) ) {
									echo '<meta itemprop="height" content="' . esc_attr( $rx_image_src[2] ) . '">';
								}

								if ( $rx_caption ) :
									?>
									<figcaption class="rx-entry__featured-caption">
										<?php echo esc_html( $rx_caption ); ?>
									</figcaption>
								<?php elseif ( $rx_thumbnail_alt ) : ?>
									<figcaption class="rx-entry__featured-caption screen-reader-text">
										<?php echo esc_html( $rx_thumbnail_alt ); ?>
									</figcaption>
								<?php endif; ?>
							</figure>
						<?php endif; ?>

						<?php
						/**
						 * Before entry content.
						 */
						do_action( 'rx_theme_before_entry_content', $rx_current_post_id );
						?>

						<?php if ( $rx_show_toc && ! $rx_is_password_post ) : ?>
							<?php rx_theme_render_post_toc( apply_filters( 'the_content', $rx_content_raw ) ); ?>
						<?php endif; ?>

						<div class="rx-entry__content entry-content" itemprop="articleBody">
							<?php
							$rx_filtered_content = apply_filters( 'the_content', get_the_content() );
							$rx_filtered_content = str_replace( ']]>', ']]&gt;', $rx_filtered_content );
							$rx_filtered_content = rx_theme_add_heading_ids_to_content( $rx_filtered_content );

							echo $rx_filtered_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

							wp_link_pages(
								array(
									'before'      => '<nav class="rx-page-links" aria-label="' . esc_attr__( 'Page links', 'rx-theme' ) . '"><span class="rx-page-links__label">' . esc_html__( 'Pages:', 'rx-theme' ) . '</span>',
									'after'       => '</nav>',
									'link_before' => '<span class="rx-page-links__number">',
									'link_after'  => '</span>',
								)
							);
							?>
						</div>

						<?php
						/**
						 * After entry content.
						 */
						do_action( 'rx_theme_after_entry_content', $rx_current_post_id );
						?>

						<footer class="rx-entry__footer">

							<?php if ( has_tag() ) : ?>
								<div class="rx-entry__tags">
									<span class="rx-entry__tags-label"><?php esc_html_e( 'Tags:', 'rx-theme' ); ?></span>
									<?php the_tags( '<ul class="rx-entry__tag-list"><li class="rx-entry__tag-item">', '</li><li class="rx-entry__tag-item">', '</li></ul>' ); ?>
								</div>
							<?php endif; ?>

							<?php if ( is_singular( 'post' ) ) : ?>
								<nav class="rx-post-navigation" aria-label="<?php esc_attr_e( 'Post navigation', 'rx-theme' ); ?>">
									<div class="rx-post-navigation__previous">
										<?php
										previous_post_link(
											'%link',
											'<span class="rx-post-navigation__label">' . esc_html__( 'Previous Article', 'rx-theme' ) . '</span><span class="rx-post-navigation__title">%title</span>'
										);
										?>
									</div>

									<div class="rx-post-navigation__next">
										<?php
										next_post_link(
											'%link',
											'<span class="rx-post-navigation__label">' . esc_html__( 'Next Article', 'rx-theme' ) . '</span><span class="rx-post-navigation__title">%title</span>'
										);
										?>
									</div>
								</nav>
							<?php endif; ?>

						</footer>

					</article>

					<?php if ( $rx_show_author_box && is_singular( 'post' ) && ! $rx_is_password_post ) : ?>
						<?php rx_theme_render_author_box( $rx_current_post_id ); ?>
					<?php endif; ?>

					<?php if ( $rx_show_related && is_singular( 'post' ) && ! $rx_is_password_post ) : ?>
						<?php rx_theme_render_related_posts( $rx_current_post_id ); ?>
					<?php endif; ?>

					<?php if ( $rx_show_comments && ( comments_open() || get_comments_number() ) ) : ?>
						<section class="rx-comments-area">
							<?php comments_template(); ?>
						</section>
					<?php endif; ?>

				<?php endwhile; ?>

			</section>
		</div>
	</div>

	<?php
	/**
	 * After left sidebar template.
	 */
	do_action( 'rx_theme_after_left_sidebar_template' );
	?>

</main>

<?php
get_footer();

Now add this sidebar registration in:

rx-theme/inc/core/sidebars.php
<?php
/**
 * Register RX Theme sidebars.
 *
 * @package RX_Theme
 */

defined( 'ABSPATH' ) || exit;

if ( ! function_exists( 'rx_theme_register_sidebars' ) ) {
	/**
	 * Register all theme widget areas.
	 *
	 * @return void
	 */
	function rx_theme_register_sidebars() {
		register_sidebar(
			array(
				'name'          => esc_html__( 'RX Left Sidebar', 'rx-theme' ),
				'id'            => 'rx-left-sidebar',
				'description'   => esc_html__( 'Widgets added here will appear in the left sidebar template.', 'rx-theme' ),
				'before_widget' => '<section id="%1$s" class="widget rx-widget %2$s">',
				'after_widget'  => '</section>',
				'before_title'  => '<h2 class="widget-title rx-widget__title">',
				'after_title'   => '</h2>',
			)
		);
	}
}
add_action( 'widgets_init', 'rx_theme_register_sidebars' );

Make sure sidebars.php is loaded from functions.php:

require_once get_template_directory() . '/inc/core/sidebars.php';

Add this CSS in your main theme CSS, for example:

assets/css/layouts/left-sidebar.css
.rx-template--left-sidebar {
	width: 100%;
}

.rx-container {
	width: min(100% - 32px, 1200px);
	margin-inline: auto;
}

.rx-container--wide {
	width: min(100% - 32px, 1320px);
}

.rx-layout--left-sidebar {
	display: grid;
	grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
	gap: var(--rx-space-8, 2rem);
	align-items: start;
}

.rx-layout--no-sidebar {
	grid-template-columns: minmax(0, 1fr);
}

.rx-sidebar--left {
	position: relative;
}

.rx-sidebar__inner {
	position: sticky;
	top: var(--rx-sticky-offset, 96px);
	display: grid;
	gap: var(--rx-space-5, 1.25rem);
}

.rx-content-area--left-sidebar {
	min-width: 0;
}

.rx-entry {
	background: var(--rx-surface, #ffffff);
	border-radius: var(--rx-radius-lg, 18px);
	padding: clamp(1.25rem, 3vw, 2.5rem);
	box-shadow: var(--rx-shadow-soft, 0 10px 35px rgba(15, 23, 42, 0.06));
}

.rx-entry__category {
	margin-bottom: 0.75rem;
}

.rx-entry__category-link {
	display: inline-flex;
	align-items: center;
	border-radius: 999px;
	padding: 0.35rem 0.75rem;
	background: var(--rx-primary-soft, #eef6ff);
	color: var(--rx-primary, #0b63ce);
	font-size: 0.875rem;
	font-weight: 700;
	text-decoration: none;
}

.rx-entry__title {
	margin: 0;
	font-size: clamp(2rem, 5vw, 3.75rem);
	line-height: 1.08;
	letter-spacing: -0.04em;
	color: var(--rx-heading, #111827);
}

.rx-entry__summary {
	margin-top: 1rem;
	font-size: clamp(1.05rem, 2vw, 1.25rem);
	line-height: 1.7;
	color: var(--rx-muted, #4b5563);
}

.rx-entry__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	align-items: center;
	margin-top: 1rem;
	font-size: 0.925rem;
	color: var(--rx-muted, #6b7280);
}

.rx-entry__meta a {
	color: inherit;
	text-decoration: none;
}

.rx-entry__meta a:hover {
	color: var(--rx-primary, #0b63ce);
}

.rx-entry__featured-media {
	margin: 2rem 0;
}

.rx-entry__featured-image {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--rx-radius-lg, 18px);
}

.rx-entry__featured-caption {
	margin-top: 0.75rem;
	font-size: 0.875rem;
	color: var(--rx-muted, #6b7280);
	text-align: center;
}

.rx-toc {
	margin: 2rem 0;
	padding: 1.25rem;
	border: 1px solid var(--rx-border, #e5e7eb);
	border-radius: var(--rx-radius-md, 14px);
	background: var(--rx-surface-soft, #f9fafb);
}

.rx-toc__title {
	margin: 0 0 0.75rem;
	font-size: 1.1rem;
}

.rx-toc__list {
	margin: 0;
	padding-left: 1.25rem;
}

.rx-toc__item {
	margin-top: 0.45rem;
}

.rx-toc__item--sub {
	margin-left: 1rem;
	font-size: 0.95rem;
}

.rx-toc__link {
	color: var(--rx-text, #1f2937);
	text-decoration: none;
}

.rx-toc__link:hover {
	color: var(--rx-primary, #0b63ce);
}

.rx-entry__content {
	font-size: 1.0625rem;
	line-height: 1.85;
	color: var(--rx-text, #1f2937);
}

.rx-entry__content h2,
.rx-entry__content h3,
.rx-entry__content h4 {
	scroll-margin-top: 120px;
	color: var(--rx-heading, #111827);
}

.rx-entry__content img {
	max-width: 100%;
	height: auto;
	border-radius: var(--rx-radius-md, 14px);
}

.rx-entry__content table {
	width: 100%;
	border-collapse: collapse;
	overflow-x: auto;
}

.rx-entry__content th,
.rx-entry__content td {
	padding: 0.75rem;
	border: 1px solid var(--rx-border, #e5e7eb);
}

.rx-entry__footer {
	margin-top: 2.5rem;
	padding-top: 1.5rem;
	border-top: 1px solid var(--rx-border, #e5e7eb);
}

.rx-entry__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	align-items: center;
}

.rx-entry__tag-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.rx-entry__tag-item a {
	display: inline-flex;
	border-radius: 999px;
	padding: 0.35rem 0.75rem;
	background: var(--rx-surface-soft, #f3f4f6);
	color: var(--rx-text, #1f2937);
	text-decoration: none;
}

.rx-post-navigation {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1rem;
	margin-top: 2rem;
}

.rx-post-navigation a {
	display: block;
	height: 100%;
	padding: 1rem;
	border: 1px solid var(--rx-border, #e5e7eb);
	border-radius: var(--rx-radius-md, 14px);
	text-decoration: none;
	color: var(--rx-text, #1f2937);
}

.rx-post-navigation__label {
	display: block;
	margin-bottom: 0.25rem;
	font-size: 0.8rem;
	color: var(--rx-muted, #6b7280);
}

.rx-post-navigation__title {
	display: block;
	font-weight: 700;
}

.rx-author-box,
.rx-related-posts,
.rx-comments-area {
	margin-top: 2rem;
	padding: clamp(1.25rem, 3vw, 2rem);
	border-radius: var(--rx-radius-lg, 18px);
	background: var(--rx-surface, #ffffff);
	box-shadow: var(--rx-shadow-soft, 0 10px 35px rgba(15, 23, 42, 0.06));
}

.rx-author-box {
	display: flex;
	gap: 1rem;
	align-items: flex-start;
}

.rx-author-box__image {
	border-radius: 999px;
}

.rx-author-box__title {
	margin: 0 0 0.5rem;
	font-size: 1.15rem;
}

.rx-author-box__bio {
	margin: 0;
	color: var(--rx-muted, #4b5563);
	line-height: 1.7;
}

.rx-related-posts__title {
	margin-top: 0;
}

.rx-related-posts__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1rem;
}

.rx-related-card__link {
	display: block;
	height: 100%;
	overflow: hidden;
	border: 1px solid var(--rx-border, #e5e7eb);
	border-radius: var(--rx-radius-md, 14px);
	color: var(--rx-text, #1f2937);
	text-decoration: none;
}

.rx-related-card__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

.rx-related-card__content {
	display: block;
	padding: 1rem;
}

.rx-related-card__title {
	display: block;
	font-weight: 700;
	line-height: 1.4;
}

.rx-related-card__meta {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.85rem;
	color: var(--rx-muted, #6b7280);
}

.rx-breadcrumbs {
	margin: 1rem 0 1.5rem;
	font-size: 0.925rem;
}

.rx-breadcrumbs__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.rx-breadcrumbs__item::after {
	content: "/";
	margin-left: 0.35rem;
	color: var(--rx-muted, #9ca3af);
}

.rx-breadcrumbs__item:last-child::after {
	content: "";
}

.rx-breadcrumbs__link {
	color: var(--rx-primary, #0b63ce);
	text-decoration: none;
}

.rx-breadcrumbs__item--current {
	color: var(--rx-muted, #6b7280);
}

@media (max-width: 991px) {
	.rx-layout--left-sidebar {
		grid-template-columns: 1fr;
	}

	.rx-sidebar--left {
		order: 2;
	}

	.rx-content-area--left-sidebar {
		order: 1;
	}

	.rx-sidebar__inner {
		position: static;
	}

	.rx-related-posts__grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 640px) {
	.rx-post-navigation {
		grid-template-columns: 1fr;
	}

	.rx-author-box {
		display: block;
	}

	.rx-author-box__avatar {
		margin-bottom: 1rem;
	}
}

To enqueue this CSS, add in your enqueue file:

wp_enqueue_style(
	'rx-left-sidebar',
	get_template_directory_uri() . '/assets/css/layouts/left-sidebar.css',
	array(),
	wp_get_theme()->get( 'Version' )
);

Best folder placement:

rx-theme/
├── templates/
│   └── template-left-sidebar.php
│
├── inc/
│   └── core/
│       └── sidebars.php
│
└── assets/
    └── css/
        └── layouts/
            └── left-sidebar.css

This template is now advanced enough for RX Theme: left sidebar, dynamic widgets, schema-ready article markup, breadcrumbs fallback, SEO meta structure, featured image, reading time, table of contents, author box, related posts, comments, pagination, previous/next post links, hooks, filters, responsive CSS, and safe WordPress escaping.

Leave a Reply

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