sidebar-builder.php

I’ll build this as a reusable advanced WordPress theme sidebar builder file for inc/builders/sidebar-builder.php, with registration, dynamic sidebars, layout helpers, widget rendering, fallback content, schema-friendly markup, and theme hooks.

Below is an advanced, complete inc/builders/sidebar-builder.php file for your rx theme. It includes dynamic sidebar registration, multiple sidebar areas, layout helpers, sticky sidebar support, WooCommerce sidebars, BuddyPress/bbPress support, fallback widgets, conditional sidebar logic, schema markup, sanitization, hooks, filters, CSS class builders, and helper functions.

Create this file:

mkdir -p inc/builders
touch inc/builders/sidebar-builder.php

Then paste this full code inside:

<?php
/**
 * RX Theme Sidebar Builder
 *
 * File: inc/builders/sidebar-builder.php
 *
 * This file controls all sidebar-related functionality for the RX Theme.
 * It registers sidebar/widget areas, renders sidebars, builds sidebar layouts,
 * supports conditional sidebars, sticky sidebars, WooCommerce sidebars,
 * footer widget columns, fallback content, schema-ready markup, and developer hooks.
 *
 * @package RX_Theme
 */

defined( 'ABSPATH' ) || exit;

if ( ! class_exists( 'RX_Sidebar_Builder' ) ) :

	/**
	 * Main RX Sidebar Builder Class.
	 */
	final class RX_Sidebar_Builder {

		/**
		 * Class instance.
		 *
		 * @var RX_Sidebar_Builder|null
		 */
		private static $instance = null;

		/**
		 * Theme prefix.
		 *
		 * @var string
		 */
		private $prefix = 'rx';

		/**
		 * Default sidebar layout.
		 *
		 * Available values:
		 * - right-sidebar
		 * - left-sidebar
		 * - no-sidebar
		 * - full-width
		 *
		 * @var string
		 */
		private $default_layout = 'right-sidebar';

		/**
		 * Registered sidebar definitions.
		 *
		 * @var array
		 */
		private $sidebars = array();

		/**
		 * Get instance.
		 *
		 * @return RX_Sidebar_Builder
		 */
		public static function instance() {
			if ( null === self::$instance ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor.
		 */
		private function __construct() {
			$this->sidebars = $this->get_default_sidebars();

			add_action( 'widgets_init', array( $this, 'register_sidebars' ) );

			add_filter( 'body_class', array( $this, 'body_classes' ) );
			add_filter( 'rx_theme_layout', array( $this, 'filter_theme_layout' ) );

			add_action( 'rx_before_sidebar', array( $this, 'before_sidebar_hook' ), 10, 1 );
			add_action( 'rx_after_sidebar', array( $this, 'after_sidebar_hook' ), 10, 1 );
		}

		/**
		 * Get default sidebars.
		 *
		 * @return array
		 */
		private function get_default_sidebars() {
			$sidebars = array(
				'primary-sidebar' => array(
					'name'          => esc_html__( 'Primary Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Main sidebar used on posts, pages, archive pages, and blog layouts.', '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>',
				),

				'blog-sidebar' => array(
					'name'          => esc_html__( 'Blog Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar for blog index, category, tag, author, date, and search archive pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-blog-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'single-post-sidebar' => array(
					'name'          => esc_html__( 'Single Post Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on single blog posts.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-single-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'page-sidebar' => array(
					'name'          => esc_html__( 'Page Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on static pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-page-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'home-sidebar' => array(
					'name'          => esc_html__( 'Home Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on the homepage or front page.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-home-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'search-sidebar' => array(
					'name'          => esc_html__( 'Search Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on search result pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-search-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'404-sidebar' => array(
					'name'          => esc_html__( '404 Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on 404 error pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-404-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'header-widget-area' => array(
					'name'          => esc_html__( 'Header Widget Area', 'rx-theme' ),
					'description'   => esc_html__( 'Widget area displayed inside or near the header.', 'rx-theme' ),
					'before_widget' => '<div id="%1$s" class="widget rx-widget rx-header-widget %2$s">',
					'after_widget'  => '</div>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'above-content' => array(
					'name'          => esc_html__( 'Above Content Widget Area', 'rx-theme' ),
					'description'   => esc_html__( 'Widget area displayed above the main content.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-above-content-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'below-content' => array(
					'name'          => esc_html__( 'Below Content Widget Area', 'rx-theme' ),
					'description'   => esc_html__( 'Widget area displayed below the main content.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-below-content-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'after-post-content' => array(
					'name'          => esc_html__( 'After Post Content', 'rx-theme' ),
					'description'   => esc_html__( 'Widget area displayed after single post content.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-after-post-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'mobile-sidebar' => array(
					'name'          => esc_html__( 'Mobile Sidebar / Off Canvas', 'rx-theme' ),
					'description'   => esc_html__( 'Widget area for mobile menu, off-canvas panel, or mobile-only sidebar.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-mobile-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'footer-1' => array(
					'name'          => esc_html__( 'Footer Column 1', 'rx-theme' ),
					'description'   => esc_html__( 'First footer widget column.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-footer-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'footer-2' => array(
					'name'          => esc_html__( 'Footer Column 2', 'rx-theme' ),
					'description'   => esc_html__( 'Second footer widget column.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-footer-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'footer-3' => array(
					'name'          => esc_html__( 'Footer Column 3', 'rx-theme' ),
					'description'   => esc_html__( 'Third footer widget column.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-footer-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),

				'footer-4' => array(
					'name'          => esc_html__( 'Footer Column 4', 'rx-theme' ),
					'description'   => esc_html__( 'Fourth footer widget column.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-footer-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				),
			);

			if ( class_exists( 'WooCommerce' ) ) {
				$sidebars['shop-sidebar'] = array(
					'name'          => esc_html__( 'WooCommerce Shop Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on WooCommerce shop, product category, product tag, and product archive pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-shop-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				);

				$sidebars['single-product-sidebar'] = array(
					'name'          => esc_html__( 'Single Product Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on single WooCommerce product pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-product-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				);
			}

			if ( function_exists( 'bp_is_active' ) ) {
				$sidebars['buddypress-sidebar'] = array(
					'name'          => esc_html__( 'BuddyPress Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on BuddyPress pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-buddypress-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				);
			}

			if ( class_exists( 'bbPress' ) ) {
				$sidebars['bbpress-sidebar'] = array(
					'name'          => esc_html__( 'bbPress Sidebar', 'rx-theme' ),
					'description'   => esc_html__( 'Sidebar displayed on bbPress forum pages.', 'rx-theme' ),
					'before_widget' => '<section id="%1$s" class="widget rx-widget rx-bbpress-widget %2$s">',
					'after_widget'  => '</section>',
					'before_title'  => '<h2 class="widget-title rx-widget-title">',
					'after_title'   => '</h2>',
				);
			}

			/**
			 * Filter sidebar definitions.
			 *
			 * Example:
			 * add_filter( 'rx_sidebar_definitions', function( $sidebars ) {
			 *     $sidebars['custom-sidebar'] = array(
			 *         'name' => 'Custom Sidebar',
			 *         'description' => 'My custom sidebar',
			 *     );
			 *     return $sidebars;
			 * } );
			 */
			return apply_filters( 'rx_sidebar_definitions', $sidebars );
		}

		/**
		 * Register all sidebars.
		 *
		 * @return void
		 */
		public function register_sidebars() {
			foreach ( $this->sidebars as $id => $args ) {
				$defaults = array(
					'id'            => sanitize_key( $id ),
					'name'          => ucwords( str_replace( '-', ' ', $id ) ),
					'description'   => '',
					'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>',
				);

				$args       = wp_parse_args( $args, $defaults );
				$args['id'] = sanitize_key( $id );

				register_sidebar( $args );
			}
		}

		/**
		 * Get all registered RX sidebar IDs.
		 *
		 * @return array
		 */
		public function get_sidebar_ids() {
			return array_keys( $this->sidebars );
		}

		/**
		 * Check if a sidebar exists in RX sidebar list.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @return bool
		 */
		public function sidebar_exists( $sidebar_id ) {
			$sidebar_id = sanitize_key( $sidebar_id );

			return isset( $this->sidebars[ $sidebar_id ] );
		}

		/**
		 * Get the best sidebar ID for the current request.
		 *
		 * @return string
		 */
		public function get_current_sidebar_id() {
			$sidebar_id = 'primary-sidebar';

			if ( is_front_page() || is_home() ) {
				$sidebar_id = is_home() ? 'blog-sidebar' : 'home-sidebar';
			}

			if ( is_single() && 'post' === get_post_type() ) {
				$sidebar_id = 'single-post-sidebar';
			}

			if ( is_page() ) {
				$sidebar_id = 'page-sidebar';
			}

			if ( is_archive() ) {
				$sidebar_id = 'blog-sidebar';
			}

			if ( is_search() ) {
				$sidebar_id = 'search-sidebar';
			}

			if ( is_404() ) {
				$sidebar_id = '404-sidebar';
			}

			if ( class_exists( 'WooCommerce' ) ) {
				if ( function_exists( 'is_shop' ) && ( is_shop() || is_product_taxonomy() ) ) {
					$sidebar_id = 'shop-sidebar';
				}

				if ( function_exists( 'is_product' ) && is_product() ) {
					$sidebar_id = 'single-product-sidebar';
				}
			}

			if ( function_exists( 'bp_is_active' ) && function_exists( 'is_buddypress' ) && is_buddypress() ) {
				$sidebar_id = 'buddypress-sidebar';
			}

			if ( class_exists( 'bbPress' ) && function_exists( 'is_bbpress' ) && is_bbpress() ) {
				$sidebar_id = 'bbpress-sidebar';
			}

			/**
			 * Filter current sidebar ID.
			 */
			return sanitize_key( apply_filters( 'rx_current_sidebar_id', $sidebar_id ) );
		}

		/**
		 * Get sidebar layout.
		 *
		 * @return string
		 */
		public function get_layout() {
			$layout = get_theme_mod( 'rx_sidebar_layout', $this->default_layout );

			if ( is_singular() ) {
				$post_id = get_queried_object_id();

				if ( $post_id ) {
					$post_layout = get_post_meta( $post_id, '_rx_sidebar_layout', true );

					if ( ! empty( $post_layout ) ) {
						$layout = $post_layout;
					}
				}
			}

			if ( is_page_template( 'templates/full-width.php' ) ) {
				$layout = 'full-width';
			}

			if ( is_page_template( 'templates/no-sidebar.php' ) ) {
				$layout = 'no-sidebar';
			}

			if ( is_attachment() ) {
				$layout = 'no-sidebar';
			}

			if ( is_404() ) {
				$layout = get_theme_mod( 'rx_404_sidebar_layout', 'no-sidebar' );
			}

			if ( is_search() ) {
				$layout = get_theme_mod( 'rx_search_sidebar_layout', $layout );
			}

			if ( class_exists( 'WooCommerce' ) ) {
				if ( function_exists( 'is_cart' ) && ( is_cart() || is_checkout() || is_account_page() ) ) {
					$layout = 'no-sidebar';
				}
			}

			$allowed = array(
				'right-sidebar',
				'left-sidebar',
				'no-sidebar',
				'full-width',
			);

			if ( ! in_array( $layout, $allowed, true ) ) {
				$layout = $this->default_layout;
			}

			return apply_filters( 'rx_sidebar_layout', $layout );
		}

		/**
		 * Filter theme layout.
		 *
		 * @param string $layout Existing layout.
		 * @return string
		 */
		public function filter_theme_layout( $layout ) {
			$current = $this->get_layout();

			return ! empty( $current ) ? $current : $layout;
		}

		/**
		 * Whether current page should show sidebar.
		 *
		 * @return bool
		 */
		public function should_show_sidebar() {
			$layout = $this->get_layout();

			if ( in_array( $layout, array( 'no-sidebar', 'full-width' ), true ) ) {
				return false;
			}

			$sidebar_id = $this->get_current_sidebar_id();

			if ( ! is_active_sidebar( $sidebar_id ) && ! $this->fallback_enabled() ) {
				return false;
			}

			return (bool) apply_filters( 'rx_should_show_sidebar', true, $layout, $sidebar_id );
		}

		/**
		 * Is fallback sidebar enabled?
		 *
		 * @return bool
		 */
		public function fallback_enabled() {
			return (bool) apply_filters(
				'rx_sidebar_fallback_enabled',
				get_theme_mod( 'rx_sidebar_fallback_enabled', true )
			);
		}

		/**
		 * Render current sidebar.
		 *
		 * @param string $sidebar_id Optional sidebar ID.
		 * @param array  $args Optional args.
		 * @return void
		 */
		public function render_sidebar( $sidebar_id = '', $args = array() ) {
			if ( empty( $sidebar_id ) ) {
				$sidebar_id = $this->get_current_sidebar_id();
			}

			$sidebar_id = sanitize_key( $sidebar_id );

			$defaults = array(
				'echo'          => true,
				'wrapper'       => true,
				'fallback'      => true,
				'sticky'        => get_theme_mod( 'rx_sticky_sidebar', true ),
				'aria_label'    => esc_html__( 'Sidebar', 'rx-theme' ),
				'schema'        => true,
				'custom_class'  => '',
				'inner_class'   => '',
				'container_tag' => 'aside',
				'inner_tag'     => 'div',
			);

			$args = wp_parse_args( $args, $defaults );

			if ( ! $this->should_render_sidebar_id( $sidebar_id, $args ) ) {
				return;
			}

			$output = '';

			if ( $args['wrapper'] ) {
				$output .= $this->get_sidebar_open_markup( $sidebar_id, $args );
			}

			if ( is_active_sidebar( $sidebar_id ) ) {
				ob_start();
				dynamic_sidebar( $sidebar_id );
				$output .= ob_get_clean();
			} elseif ( true === $args['fallback'] && $this->fallback_enabled() ) {
				$output .= $this->get_fallback_sidebar_content( $sidebar_id );
			}

			if ( $args['wrapper'] ) {
				$output .= $this->get_sidebar_close_markup( $args );
			}

			$output = apply_filters( 'rx_render_sidebar_output', $output, $sidebar_id, $args );

			if ( $args['echo'] ) {
				echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				return;
			}

			return $output;
		}

		/**
		 * Check whether a specific sidebar should render.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @param array  $args Render args.
		 * @return bool
		 */
		private function should_render_sidebar_id( $sidebar_id, $args ) {
			if ( empty( $sidebar_id ) ) {
				return false;
			}

			if ( ! is_active_sidebar( $sidebar_id ) && empty( $args['fallback'] ) ) {
				return false;
			}

			if ( ! is_active_sidebar( $sidebar_id ) && ! $this->fallback_enabled() ) {
				return false;
			}

			return (bool) apply_filters( 'rx_should_render_sidebar_id', true, $sidebar_id, $args );
		}

		/**
		 * Get sidebar open markup.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @param array  $args Args.
		 * @return string
		 */
		private function get_sidebar_open_markup( $sidebar_id, $args ) {
			$tag = tag_escape( $args['container_tag'] );

			$classes = $this->get_sidebar_classes(
				$sidebar_id,
				array(
					'sticky'       => $args['sticky'],
					'custom_class' => $args['custom_class'],
				)
			);

			$attributes = array(
				'id'         => 'secondary',
				'class'      => implode( ' ', array_map( 'sanitize_html_class', $classes ) ),
				'aria-label' => $args['aria_label'],
			);

			if ( $args['schema'] ) {
				$attributes['itemscope'] = 'itemscope';
				$attributes['itemtype']  = 'https://schema.org/WPSideBar';
			}

			$attributes = apply_filters( 'rx_sidebar_wrapper_attributes', $attributes, $sidebar_id, $args );

			$output  = '';
			$output .= sprintf( '<%1$s %2$s>', $tag, $this->build_attributes( $attributes ) );
			$output .= "\n";

			do_action( 'rx_before_sidebar', $sidebar_id );

			$inner_tag     = tag_escape( $args['inner_tag'] );
			$inner_classes = array(
				'rx-sidebar-inner',
			);

			if ( ! empty( $args['inner_class'] ) ) {
				$inner_classes[] = sanitize_html_class( $args['inner_class'] );
			}

			$output .= sprintf(
				'<%1$s class="%2$s">',
				$inner_tag,
				esc_attr( implode( ' ', $inner_classes ) )
			);

			return $output;
		}

		/**
		 * Get sidebar close markup.
		 *
		 * @param array $args Args.
		 * @return string
		 */
		private function get_sidebar_close_markup( $args ) {
			$tag       = tag_escape( $args['container_tag'] );
			$inner_tag = tag_escape( $args['inner_tag'] );

			$output  = sprintf( '</%s>', $inner_tag );
			$output .= "\n";

			do_action( 'rx_after_sidebar', $this->get_current_sidebar_id() );

			$output .= sprintf( '</%s>', $tag );
			$output .= "\n";

			return $output;
		}

		/**
		 * Build sidebar CSS classes.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @param array  $args Args.
		 * @return array
		 */
		public function get_sidebar_classes( $sidebar_id = '', $args = array() ) {
			if ( empty( $sidebar_id ) ) {
				$sidebar_id = $this->get_current_sidebar_id();
			}

			$layout = $this->get_layout();

			$classes = array(
				'widget-area',
				'rx-sidebar',
				'rx-sidebar-' . sanitize_html_class( $sidebar_id ),
				'rx-layout-' . sanitize_html_class( $layout ),
			);

			if ( ! empty( $args['sticky'] ) ) {
				$classes[] = 'rx-sidebar-sticky';
			}

			if ( is_active_sidebar( $sidebar_id ) ) {
				$classes[] = 'rx-sidebar-has-widgets';
			} else {
				$classes[] = 'rx-sidebar-empty';
			}

			if ( is_rtl() ) {
				$classes[] = 'rx-sidebar-rtl';
			}

			if ( ! empty( $args['custom_class'] ) ) {
				$custom_classes = explode( ' ', $args['custom_class'] );

				foreach ( $custom_classes as $custom_class ) {
					if ( ! empty( $custom_class ) ) {
						$classes[] = sanitize_html_class( $custom_class );
					}
				}
			}

			return apply_filters( 'rx_sidebar_classes', array_unique( $classes ), $sidebar_id, $args );
		}

		/**
		 * Render above content widget area.
		 *
		 * @return void
		 */
		public function render_above_content() {
			$this->render_widget_area(
				'above-content',
				array(
					'wrapper_class' => 'rx-above-content-area',
					'aria_label'    => esc_html__( 'Above content widgets', 'rx-theme' ),
				)
			);
		}

		/**
		 * Render below content widget area.
		 *
		 * @return void
		 */
		public function render_below_content() {
			$this->render_widget_area(
				'below-content',
				array(
					'wrapper_class' => 'rx-below-content-area',
					'aria_label'    => esc_html__( 'Below content widgets', 'rx-theme' ),
				)
			);
		}

		/**
		 * Render after post content widget area.
		 *
		 * @return void
		 */
		public function render_after_post_content() {
			if ( ! is_single() ) {
				return;
			}

			$this->render_widget_area(
				'after-post-content',
				array(
					'wrapper_class' => 'rx-after-post-content-area',
					'aria_label'    => esc_html__( 'After post content widgets', 'rx-theme' ),
				)
			);
		}

		/**
		 * Render header widget area.
		 *
		 * @return void
		 */
		public function render_header_widget_area() {
			$this->render_widget_area(
				'header-widget-area',
				array(
					'wrapper_class' => 'rx-header-widget-area',
					'aria_label'    => esc_html__( 'Header widgets', 'rx-theme' ),
					'tag'           => 'div',
				)
			);
		}

		/**
		 * Render mobile sidebar area.
		 *
		 * @return void
		 */
		public function render_mobile_sidebar() {
			$this->render_widget_area(
				'mobile-sidebar',
				array(
					'wrapper_class' => 'rx-mobile-sidebar-area',
					'aria_label'    => esc_html__( 'Mobile sidebar widgets', 'rx-theme' ),
					'tag'           => 'aside',
				)
			);
		}

		/**
		 * Render a generic widget area.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @param array  $args Args.
		 * @return void
		 */
		public function render_widget_area( $sidebar_id, $args = array() ) {
			$sidebar_id = sanitize_key( $sidebar_id );

			if ( ! is_active_sidebar( $sidebar_id ) ) {
				return;
			}

			$defaults = array(
				'tag'           => 'section',
				'wrapper_class' => 'rx-widget-area',
				'aria_label'    => esc_html__( 'Widget area', 'rx-theme' ),
				'inner_class'   => 'rx-widget-area-inner',
			);

			$args = wp_parse_args( $args, $defaults );

			$tag = tag_escape( $args['tag'] );

			printf(
				'<%1$s class="%2$s" aria-label="%3$s">',
				$tag,
				esc_attr( $args['wrapper_class'] ),
				esc_attr( $args['aria_label'] )
			);

			printf(
				'<div class="%s">',
				esc_attr( $args['inner_class'] )
			);

			dynamic_sidebar( $sidebar_id );

			echo '</div>';

			printf(
				'</%s>',
				$tag
			);
		}

		/**
		 * Render footer widgets.
		 *
		 * @param int $columns Number of columns.
		 * @return void
		 */
		public function render_footer_widgets( $columns = 4 ) {
			$columns = absint( $columns );

			if ( $columns < 1 ) {
				$columns = 1;
			}

			if ( $columns > 4 ) {
				$columns = 4;
			}

			$active = false;

			for ( $i = 1; $i <= $columns; $i++ ) {
				if ( is_active_sidebar( 'footer-' . $i ) ) {
					$active = true;
					break;
				}
			}

			if ( ! $active ) {
				return;
			}

			$classes = array(
				'rx-footer-widgets',
				'rx-footer-widgets-columns-' . $columns,
			);

			$classes = apply_filters( 'rx_footer_widgets_classes', $classes, $columns );

			echo '<section class="' . esc_attr( implode( ' ', $classes ) ) . '" aria-label="' . esc_attr__( 'Footer widgets', 'rx-theme' ) . '">';
			echo '<div class="rx-container rx-footer-widgets-container">';

			for ( $i = 1; $i <= $columns; $i++ ) {
				$sidebar_id = 'footer-' . $i;

				if ( ! is_active_sidebar( $sidebar_id ) ) {
					continue;
				}

				echo '<div class="rx-footer-widget-column rx-footer-widget-column-' . esc_attr( $i ) . '">';
				dynamic_sidebar( $sidebar_id );
				echo '</div>';
			}

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

		/**
		 * Fallback sidebar content.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @return string
		 */
		private function get_fallback_sidebar_content( $sidebar_id ) {
			ob_start();

			/**
			 * Before fallback sidebar content.
			 */
			do_action( 'rx_before_fallback_sidebar_content', $sidebar_id );

			?>
			<section class="widget rx-widget rx-fallback-widget rx-fallback-search">
				<h2 class="widget-title rx-widget-title">
					<?php esc_html_e( 'Search', 'rx-theme' ); ?>
				</h2>
				<?php get_search_form(); ?>
			</section>

			<?php if ( ! is_404() ) : ?>
				<section class="widget rx-widget rx-fallback-widget rx-fallback-recent-posts">
					<h2 class="widget-title rx-widget-title">
						<?php esc_html_e( 'Recent Posts', 'rx-theme' ); ?>
					</h2>
					<ul>
						<?php
						$recent_posts = wp_get_recent_posts(
							array(
								'numberposts'      => 5,
								'post_status'      => 'publish',
								'suppress_filters' => false,
							)
						);

						if ( ! empty( $recent_posts ) ) :
							foreach ( $recent_posts as $recent_post ) :
								?>
								<li>
									<a href="<?php echo esc_url( get_permalink( $recent_post['ID'] ) ); ?>">
										<?php echo esc_html( get_the_title( $recent_post['ID'] ) ); ?>
									</a>
								</li>
								<?php
							endforeach;
						else :
							?>
							<li><?php esc_html_e( 'No recent posts found.', 'rx-theme' ); ?></li>
							<?php
						endif;
						?>
					</ul>
				</section>
			<?php endif; ?>

			<?php if ( ! is_page() ) : ?>
				<section class="widget rx-widget rx-fallback-widget rx-fallback-categories">
					<h2 class="widget-title rx-widget-title">
						<?php esc_html_e( 'Categories', 'rx-theme' ); ?>
					</h2>
					<ul>
						<?php
						wp_list_categories(
							array(
								'title_li'    => '',
								'number'      => 10,
								'hide_empty'  => true,
								'show_count'  => true,
								'orderby'     => 'count',
								'order'       => 'DESC',
							)
						);
						?>
					</ul>
				</section>
			<?php endif; ?>

			<?php
			/**
			 * After fallback sidebar content.
			 */
			do_action( 'rx_after_fallback_sidebar_content', $sidebar_id );

			$content = ob_get_clean();

			return apply_filters( 'rx_fallback_sidebar_content', $content, $sidebar_id );
		}

		/**
		 * Add body classes.
		 *
		 * @param array $classes Body classes.
		 * @return array
		 */
		public function body_classes( $classes ) {
			$layout     = $this->get_layout();
			$sidebar_id = $this->get_current_sidebar_id();

			$classes[] = 'rx-sidebar-layout-' . sanitize_html_class( $layout );
			$classes[] = 'rx-current-sidebar-' . sanitize_html_class( $sidebar_id );

			if ( $this->should_show_sidebar() ) {
				$classes[] = 'rx-has-sidebar';
			} else {
				$classes[] = 'rx-no-sidebar';
			}

			if ( get_theme_mod( 'rx_sticky_sidebar', true ) ) {
				$classes[] = 'rx-has-sticky-sidebar';
			}

			return array_unique( $classes );
		}

		/**
		 * Build content wrapper classes.
		 *
		 * @return string
		 */
		public function get_content_area_classes() {
			$layout = $this->get_layout();

			$classes = array(
				'rx-content-area',
				'rx-content-layout-' . sanitize_html_class( $layout ),
			);

			if ( $this->should_show_sidebar() ) {
				$classes[] = 'rx-content-with-sidebar';
			} else {
				$classes[] = 'rx-content-without-sidebar';
			}

			return esc_attr( implode( ' ', apply_filters( 'rx_content_area_classes', $classes, $layout ) ) );
		}

		/**
		 * Build main content classes.
		 *
		 * @return string
		 */
		public function get_main_content_classes() {
			$layout = $this->get_layout();

			$classes = array(
				'rx-main-content',
				'rx-main-content-' . sanitize_html_class( $layout ),
			);

			if ( $this->should_show_sidebar() ) {
				$classes[] = 'rx-main-has-sidebar';
			} else {
				$classes[] = 'rx-main-no-sidebar';
			}

			return esc_attr( implode( ' ', apply_filters( 'rx_main_content_classes', $classes, $layout ) ) );
		}

		/**
		 * Build HTML attributes.
		 *
		 * @param array $attributes Attributes.
		 * @return string
		 */
		private function build_attributes( $attributes ) {
			$output = array();

			foreach ( $attributes as $name => $value ) {
				if ( false === $value || null === $value || '' === $value ) {
					continue;
				}

				$name = sanitize_key( $name );

				if ( true === $value ) {
					$output[] = esc_attr( $name );
					continue;
				}

				if ( 'itemscope' === $name && 'itemscope' === $value ) {
					$output[] = 'itemscope';
					continue;
				}

				$output[] = sprintf(
					'%1$s="%2$s"',
					esc_attr( $name ),
					esc_attr( $value )
				);
			}

			return implode( ' ', $output );
		}

		/**
		 * Before sidebar hook.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @return void
		 */
		public function before_sidebar_hook( $sidebar_id ) {
			/**
			 * This method intentionally exists as a public hook point.
			 * Add content before sidebar with:
			 *
			 * add_action( 'rx_before_sidebar', 'your_function' );
			 */
		}

		/**
		 * After sidebar hook.
		 *
		 * @param string $sidebar_id Sidebar ID.
		 * @return void
		 */
		public function after_sidebar_hook( $sidebar_id ) {
			/**
			 * This method intentionally exists as a public hook point.
			 * Add content after sidebar with:
			 *
			 * add_action( 'rx_after_sidebar', 'your_function' );
			 */
		}
	}

endif;

/**
 * Initialize sidebar builder.
 *
 * @return RX_Sidebar_Builder
 */
function rx_sidebar_builder() {
	return RX_Sidebar_Builder::instance();
}

rx_sidebar_builder();

/**
 * Render current sidebar.
 *
 * Usage:
 * rx_render_sidebar();
 *
 * @param string $sidebar_id Sidebar ID.
 * @param array  $args Args.
 * @return void
 */
function rx_render_sidebar( $sidebar_id = '', $args = array() ) {
	rx_sidebar_builder()->render_sidebar( $sidebar_id, $args );
}

/**
 * Get current RX sidebar ID.
 *
 * @return string
 */
function rx_get_current_sidebar_id() {
	return rx_sidebar_builder()->get_current_sidebar_id();
}

/**
 * Get RX sidebar layout.
 *
 * @return string
 */
function rx_get_sidebar_layout() {
	return rx_sidebar_builder()->get_layout();
}

/**
 * Check whether current request should show sidebar.
 *
 * @return bool
 */
function rx_should_show_sidebar() {
	return rx_sidebar_builder()->should_show_sidebar();
}

/**
 * Render above content widget area.
 *
 * @return void
 */
function rx_render_above_content_widgets() {
	rx_sidebar_builder()->render_above_content();
}

/**
 * Render below content widget area.
 *
 * @return void
 */
function rx_render_below_content_widgets() {
	rx_sidebar_builder()->render_below_content();
}

/**
 * Render after post widget area.
 *
 * @return void
 */
function rx_render_after_post_widgets() {
	rx_sidebar_builder()->render_after_post_content();
}

/**
 * Render header widget area.
 *
 * @return void
 */
function rx_render_header_widgets() {
	rx_sidebar_builder()->render_header_widget_area();
}

/**
 * Render mobile sidebar widget area.
 *
 * @return void
 */
function rx_render_mobile_sidebar_widgets() {
	rx_sidebar_builder()->render_mobile_sidebar();
}

/**
 * Render footer widgets.
 *
 * Usage:
 * rx_render_footer_widgets( 4 );
 *
 * @param int $columns Footer columns.
 * @return void
 */
function rx_render_footer_widgets( $columns = 4 ) {
	rx_sidebar_builder()->render_footer_widgets( $columns );
}

/**
 * Get content area classes.
 *
 * @return string
 */
function rx_get_content_area_classes() {
	return rx_sidebar_builder()->get_content_area_classes();
}

/**
 * Get main content classes.
 *
 * @return string
 */
function rx_get_main_content_classes() {
	return rx_sidebar_builder()->get_main_content_classes();
}

/**
 * Open content-sidebar layout wrapper.
 *
 * Usage in templates:
 * rx_content_sidebar_open();
 *
 * @return void
 */
function rx_content_sidebar_open() {
	$layout = rx_get_sidebar_layout();

	$classes = array(
		'rx-layout-wrap',
		'rx-layout-wrap-' . sanitize_html_class( $layout ),
	);

	if ( rx_should_show_sidebar() ) {
		$classes[] = 'rx-layout-has-sidebar';
	} else {
		$classes[] = 'rx-layout-no-sidebar';
	}

	echo '<div class="' . esc_attr( implode( ' ', $classes ) ) . '">';
}

/**
 * Close content-sidebar layout wrapper.
 *
 * @return void
 */
function rx_content_sidebar_close() {
	echo '</div>';
}

/**
 * Open main content area.
 *
 * @return void
 */
function rx_main_content_open() {
	echo '<main id="primary" class="' . esc_attr( rx_get_main_content_classes() ) . '">';
}

/**
 * Close main content area.
 *
 * @return void
 */
function rx_main_content_close() {
	echo '</main>';
}

/**
 * Render sidebar only if available.
 *
 * Useful in index.php, single.php, page.php, archive.php.
 *
 * @return void
 */
function rx_maybe_render_sidebar() {
	if ( rx_should_show_sidebar() ) {
		rx_render_sidebar();
	}
}

/**
 * Add optional layout customizer settings.
 *
 * This gives your theme sidebar controls in WordPress Customizer.
 *
 * @param WP_Customize_Manager $wp_customize Customizer object.
 * @return void
 */
function rx_sidebar_customizer_settings( $wp_customize ) {
	$wp_customize->add_section(
		'rx_sidebar_section',
		array(
			'title'       => esc_html__( 'RX Sidebar Settings', 'rx-theme' ),
			'description' => esc_html__( 'Control sidebar layout, sticky sidebar, and fallback widgets.', 'rx-theme' ),
			'priority'    => 160,
		)
	);

	$wp_customize->add_setting(
		'rx_sidebar_layout',
		array(
			'default'           => 'right-sidebar',
			'sanitize_callback' => 'rx_sanitize_sidebar_layout',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'rx_sidebar_layout',
		array(
			'label'   => esc_html__( 'Default Sidebar Layout', 'rx-theme' ),
			'section' => 'rx_sidebar_section',
			'type'    => 'select',
			'choices' => array(
				'right-sidebar' => esc_html__( 'Right Sidebar', 'rx-theme' ),
				'left-sidebar'  => esc_html__( 'Left Sidebar', 'rx-theme' ),
				'no-sidebar'    => esc_html__( 'No Sidebar', 'rx-theme' ),
				'full-width'    => esc_html__( 'Full Width', 'rx-theme' ),
			),
		)
	);

	$wp_customize->add_setting(
		'rx_sticky_sidebar',
		array(
			'default'           => true,
			'sanitize_callback' => 'wp_validate_boolean',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'rx_sticky_sidebar',
		array(
			'label'   => esc_html__( 'Enable Sticky Sidebar', 'rx-theme' ),
			'section' => 'rx_sidebar_section',
			'type'    => 'checkbox',
		)
	);

	$wp_customize->add_setting(
		'rx_sidebar_fallback_enabled',
		array(
			'default'           => true,
			'sanitize_callback' => 'wp_validate_boolean',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'rx_sidebar_fallback_enabled',
		array(
			'label'       => esc_html__( 'Enable Fallback Sidebar Content', 'rx-theme' ),
			'description' => esc_html__( 'Show search, recent posts, and categories when no widgets are added.', 'rx-theme' ),
			'section'     => 'rx_sidebar_section',
			'type'        => 'checkbox',
		)
	);

	$wp_customize->add_setting(
		'rx_search_sidebar_layout',
		array(
			'default'           => 'right-sidebar',
			'sanitize_callback' => 'rx_sanitize_sidebar_layout',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'rx_search_sidebar_layout',
		array(
			'label'   => esc_html__( 'Search Page Sidebar Layout', 'rx-theme' ),
			'section' => 'rx_sidebar_section',
			'type'    => 'select',
			'choices' => array(
				'right-sidebar' => esc_html__( 'Right Sidebar', 'rx-theme' ),
				'left-sidebar'  => esc_html__( 'Left Sidebar', 'rx-theme' ),
				'no-sidebar'    => esc_html__( 'No Sidebar', 'rx-theme' ),
				'full-width'    => esc_html__( 'Full Width', 'rx-theme' ),
			),
		)
	);

	$wp_customize->add_setting(
		'rx_404_sidebar_layout',
		array(
			'default'           => 'no-sidebar',
			'sanitize_callback' => 'rx_sanitize_sidebar_layout',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'rx_404_sidebar_layout',
		array(
			'label'   => esc_html__( '404 Page Sidebar Layout', 'rx-theme' ),
			'section' => 'rx_sidebar_section',
			'type'    => 'select',
			'choices' => array(
				'right-sidebar' => esc_html__( 'Right Sidebar', 'rx-theme' ),
				'left-sidebar'  => esc_html__( 'Left Sidebar', 'rx-theme' ),
				'no-sidebar'    => esc_html__( 'No Sidebar', 'rx-theme' ),
				'full-width'    => esc_html__( 'Full Width', 'rx-theme' ),
			),
		)
	);
}
add_action( 'customize_register', 'rx_sidebar_customizer_settings' );

/**
 * Sanitize sidebar layout.
 *
 * @param string $layout Layout value.
 * @return string
 */
function rx_sanitize_sidebar_layout( $layout ) {
	$allowed = array(
		'right-sidebar',
		'left-sidebar',
		'no-sidebar',
		'full-width',
	);

	if ( in_array( $layout, $allowed, true ) ) {
		return $layout;
	}

	return 'right-sidebar';
}

/**
 * Add post/page sidebar layout meta box.
 *
 * @return void
 */
function rx_sidebar_layout_meta_box() {
	$post_types = apply_filters(
		'rx_sidebar_layout_meta_box_post_types',
		array( 'post', 'page' )
	);

	foreach ( $post_types as $post_type ) {
		add_meta_box(
			'rx-sidebar-layout-meta-box',
			esc_html__( 'RX Sidebar Layout', 'rx-theme' ),
			'rx_sidebar_layout_meta_box_callback',
			$post_type,
			'side',
			'default'
		);
	}
}
add_action( 'add_meta_boxes', 'rx_sidebar_layout_meta_box' );

/**
 * Sidebar layout meta box callback.
 *
 * @param WP_Post $post Post object.
 * @return void
 */
function rx_sidebar_layout_meta_box_callback( $post ) {
	wp_nonce_field( 'rx_save_sidebar_layout_meta', 'rx_sidebar_layout_nonce' );

	$current = get_post_meta( $post->ID, '_rx_sidebar_layout', true );

	if ( empty( $current ) ) {
		$current = '';
	}

	?>
	<p>
		<label for="rx-sidebar-layout">
			<?php esc_html_e( 'Select sidebar layout for this content.', 'rx-theme' ); ?>
		</label>
	</p>

	<select name="rx_sidebar_layout" id="rx-sidebar-layout" class="widefat">
		<option value="" <?php selected( $current, '' ); ?>>
			<?php esc_html_e( 'Default Customizer Setting', 'rx-theme' ); ?>
		</option>
		<option value="right-sidebar" <?php selected( $current, 'right-sidebar' ); ?>>
			<?php esc_html_e( 'Right Sidebar', 'rx-theme' ); ?>
		</option>
		<option value="left-sidebar" <?php selected( $current, 'left-sidebar' ); ?>>
			<?php esc_html_e( 'Left Sidebar', 'rx-theme' ); ?>
		</option>
		<option value="no-sidebar" <?php selected( $current, 'no-sidebar' ); ?>>
			<?php esc_html_e( 'No Sidebar', 'rx-theme' ); ?>
		</option>
		<option value="full-width" <?php selected( $current, 'full-width' ); ?>>
			<?php esc_html_e( 'Full Width', 'rx-theme' ); ?>
		</option>
	</select>
	<?php
}

/**
 * Save sidebar layout meta.
 *
 * @param int $post_id Post ID.
 * @return void
 */
function rx_save_sidebar_layout_meta( $post_id ) {
	if ( ! isset( $_POST['rx_sidebar_layout_nonce'] ) ) {
		return;
	}

	if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['rx_sidebar_layout_nonce'] ) ), 'rx_save_sidebar_layout_meta' ) ) {
		return;
	}

	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
		return;
	}

	if ( isset( $_POST['post_type'] ) && 'page' === $_POST['post_type'] ) {
		if ( ! current_user_can( 'edit_page', $post_id ) ) {
			return;
		}
	} else {
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}
	}

	$layout = '';

	if ( isset( $_POST['rx_sidebar_layout'] ) ) {
		$layout = sanitize_text_field( wp_unslash( $_POST['rx_sidebar_layout'] ) );
	}

	if ( empty( $layout ) ) {
		delete_post_meta( $post_id, '_rx_sidebar_layout' );
		return;
	}

	$layout = rx_sanitize_sidebar_layout( $layout );

	update_post_meta( $post_id, '_rx_sidebar_layout', $layout );
}
add_action( 'save_post', 'rx_save_sidebar_layout_meta' );

/**
 * Optional helper: register an extra custom sidebar from child theme or plugin.
 *
 * Usage:
 * rx_register_custom_sidebar(
 *     'my-sidebar',
 *     'My Sidebar',
 *     'This is my custom sidebar.'
 * );
 *
 * @param string $id Sidebar ID.
 * @param string $name Sidebar name.
 * @param string $description Sidebar description.
 * @return void
 */
function rx_register_custom_sidebar( $id, $name, $description = '' ) {
	$id = sanitize_key( $id );

	if ( empty( $id ) || empty( $name ) ) {
		return;
	}

	register_sidebar(
		array(
			'id'            => $id,
			'name'          => esc_html( $name ),
			'description'   => esc_html( $description ),
			'before_widget' => '<section id="%1$s" class="widget rx-widget rx-custom-widget %2$s">',
			'after_widget'  => '</section>',
			'before_title'  => '<h2 class="widget-title rx-widget-title">',
			'after_title'   => '</h2>',
		)
	);
}

/**
 * Optional CSS for sidebar layout.
 *
 * You can move this CSS to style.css later.
 *
 * @return void
 */
function rx_sidebar_inline_css() {
	$enable_inline_css = apply_filters( 'rx_sidebar_enable_inline_css', true );

	if ( ! $enable_inline_css ) {
		return;
	}

	$css = '
		.rx-layout-wrap {
			display: grid;
			grid-template-columns: minmax(0, 1fr);
			gap: var(--rx-sidebar-gap, 32px);
			width: 100%;
		}

		.rx-layout-wrap-right-sidebar.rx-layout-has-sidebar {
			grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
		}

		.rx-layout-wrap-left-sidebar.rx-layout-has-sidebar {
			grid-template-columns: minmax(260px, 340px) minmax(0, 1fr);
		}

		.rx-layout-wrap-left-sidebar.rx-layout-has-sidebar .rx-sidebar {
			order: -1;
		}

		.rx-main-content {
			min-width: 0;
		}

		.rx-sidebar {
			min-width: 0;
		}

		.rx-sidebar-inner {
			width: 100%;
		}

		.rx-sidebar-sticky .rx-sidebar-inner {
			position: sticky;
			top: var(--rx-sticky-sidebar-offset, 32px);
		}

		.rx-widget {
			margin-bottom: 28px;
			overflow-wrap: break-word;
		}

		.rx-widget-title {
			margin-top: 0;
			margin-bottom: 16px;
			font-size: 1.125rem;
			line-height: 1.3;
		}

		.rx-footer-widgets {
			width: 100%;
			padding-top: 48px;
			padding-bottom: 48px;
		}

		.rx-footer-widgets-container {
			display: grid;
			gap: 32px;
		}

		.rx-footer-widgets-columns-1 .rx-footer-widgets-container {
			grid-template-columns: 1fr;
		}

		.rx-footer-widgets-columns-2 .rx-footer-widgets-container {
			grid-template-columns: repeat(2, minmax(0, 1fr));
		}

		.rx-footer-widgets-columns-3 .rx-footer-widgets-container {
			grid-template-columns: repeat(3, minmax(0, 1fr));
		}

		.rx-footer-widgets-columns-4 .rx-footer-widgets-container {
			grid-template-columns: repeat(4, minmax(0, 1fr));
		}

		.rx-above-content-area,
		.rx-below-content-area,
		.rx-after-post-content-area {
			margin-top: 32px;
			margin-bottom: 32px;
		}

		.rx-header-widget-area {
			display: flex;
			align-items: center;
			gap: 16px;
		}

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

			.rx-layout-wrap-left-sidebar.rx-layout-has-sidebar .rx-sidebar {
				order: initial;
			}

			.rx-sidebar-sticky .rx-sidebar-inner {
				position: static;
			}

			.rx-footer-widgets-columns-3 .rx-footer-widgets-container,
			.rx-footer-widgets-columns-4 .rx-footer-widgets-container {
				grid-template-columns: repeat(2, minmax(0, 1fr));
			}
		}

		@media (max-width: 640px) {
			.rx-footer-widgets-columns-2 .rx-footer-widgets-container,
			.rx-footer-widgets-columns-3 .rx-footer-widgets-container,
			.rx-footer-widgets-columns-4 .rx-footer-widgets-container {
				grid-template-columns: 1fr;
			}
		}
	';

	wp_register_style( 'rx-sidebar-inline-style', false, array(), defined( 'RX_THEME_VERSION' ) ? RX_THEME_VERSION : '1.0.0' );
	wp_enqueue_style( 'rx-sidebar-inline-style' );
	wp_add_inline_style( 'rx-sidebar-inline-style', $css );
}
add_action( 'wp_enqueue_scripts', 'rx_sidebar_inline_css', 20 );

Now include it in your functions.php:

/**
 * Sidebar Builder.
 */
require_once get_template_directory() . '/inc/builders/sidebar-builder.php';

Use it in your template files like this:

<?php rx_content_sidebar_open(); ?>

	<?php rx_main_content_open(); ?>

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

				the_content();

			endwhile;
		endif;
		?>

	<?php rx_main_content_close(); ?>

	<?php rx_maybe_render_sidebar(); ?>

<?php rx_content_sidebar_close(); ?>

For your footer.php, use:

<?php rx_render_footer_widgets( 4 ); ?>

For your header.php, use:

<?php rx_render_header_widgets(); ?>

For after single post content, use inside single.php:

<?php rx_render_after_post_widgets(); ?>

This file will give your RX Theme a strong sidebar system with many future expansion options.

Leave a Reply

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