theme-options.php

I’ll build this as a strong WordPress theme options file for your RX theme: admin menu, settings sections, sanitization, defaults, Customizer support, frontend helpers, and output hooks.

Below is an advanced inc/options/theme-options.php file for your RX Theme. It adds many possible theme settings: logo, colors, typography, header, footer, SEO, performance, scripts, breadcrumbs, posts, archive, social links, contact info, ad slots, custom CSS/JS, security, and helper functions.

Create this file:

rx-theme/inc/options/theme-options.php

Then include it from your functions.php:

require_once get_template_directory() . '/inc/options/theme-options.php';

inc/options/theme-options.php

<?php
/**
 * RX Theme Options
 *
 * Path: inc/options/theme-options.php
 *
 * Advanced theme options panel for RX Theme.
 *
 * @package RX_Theme
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Define RX option key.
 */
if ( ! defined( 'RX_THEME_OPTION_KEY' ) ) {
	define( 'RX_THEME_OPTION_KEY', 'rx_theme_options' );
}

/**
 * Get all default theme options.
 *
 * @return array
 */
function rx_theme_default_options() {
	return array(

		/* General */
		'site_layout'               => 'right-sidebar',
		'container_width'           => 1200,
		'enable_dark_mode'          => 0,
		'enable_sticky_sidebar'     => 1,
		'enable_back_to_top'        => 1,
		'enable_preloader'          => 0,
		'enable_smooth_scroll'      => 1,

		/* Branding */
		'custom_logo_url'           => '',
		'retina_logo_url'           => '',
		'favicon_url'               => '',
		'footer_logo_url'           => '',
		'show_site_title'           => 1,
		'show_site_tagline'         => 1,

		/* Header */
		'header_layout'             => 'default',
		'enable_sticky_header'      => 1,
		'enable_top_bar'            => 1,
		'top_bar_text'              => 'Welcome to RX Theme',
		'top_bar_phone'             => '',
		'top_bar_email'             => '',
		'enable_header_search'      => 1,
		'enable_header_social'      => 1,
		'enable_mobile_menu'        => 1,

		/* Footer */
		'footer_layout'             => 'four-columns',
		'footer_copyright'          => 'Copyright © {year} {site_name}. All rights reserved.',
		'enable_footer_widgets'     => 1,
		'enable_footer_menu'        => 1,
		'enable_footer_social'      => 1,
		'enable_footer_back_top'    => 1,

		/* Colors */
		'primary_color'             => '#0d6efd',
		'secondary_color'           => '#6610f2',
		'accent_color'              => '#198754',
		'body_bg_color'             => '#ffffff',
		'body_text_color'           => '#212529',
		'heading_color'             => '#111111',
		'link_color'                => '#0d6efd',
		'link_hover_color'          => '#084298',
		'header_bg_color'           => '#ffffff',
		'footer_bg_color'           => '#111111',
		'footer_text_color'         => '#ffffff',

		/* Typography */
		'body_font_family'          => 'system',
		'heading_font_family'       => 'system',
		'body_font_size'            => 16,
		'body_line_height'          => 1.7,
		'heading_line_height'       => 1.3,
		'enable_google_fonts'       => 0,
		'google_fonts_url'          => '',

		/* Blog */
		'blog_layout'               => 'grid',
		'archive_columns'           => 3,
		'show_post_thumbnail'       => 1,
		'show_post_author'          => 1,
		'show_post_date'            => 1,
		'show_post_category'        => 1,
		'show_post_tags'            => 1,
		'show_post_excerpt'         => 1,
		'excerpt_length'            => 30,
		'read_more_text'            => 'Read More',
		'enable_related_posts'      => 1,
		'related_posts_count'       => 3,
		'enable_author_box'         => 1,
		'enable_post_navigation'    => 1,
		'enable_comments'           => 1,

		/* SEO */
		'enable_basic_seo'          => 1,
		'enable_meta_description'   => 1,
		'default_meta_description'  => '',
		'enable_og_tags'            => 1,
		'og_default_image'          => '',
		'enable_schema'             => 1,
		'enable_breadcrumbs'        => 1,
		'enable_noindex_search'     => 0,
		'enable_noindex_404'        => 1,

		/* Performance */
		'enable_dns_prefetch'       => 1,
		'dns_prefetch_urls'         => "https://fonts.googleapis.com\nhttps://fonts.gstatic.com",
		'enable_preconnect'         => 1,
		'preconnect_urls'           => "https://fonts.googleapis.com\nhttps://fonts.gstatic.com",
		'enable_preload_fonts'      => 0,
		'preload_font_urls'         => '',
		'enable_lazy_loading'       => 1,
		'disable_emoji_scripts'     => 1,
		'disable_wp_embed'          => 0,
		'remove_wp_version'         => 1,
		'enable_defer_js'           => 0,
		'enable_async_js'           => 0,
		'defer_exclude_handles'     => 'jquery',
		'async_exclude_handles'     => 'jquery',

		/* Scripts */
		'header_scripts'            => '',
		'footer_scripts'            => '',
		'custom_css'                => '',
		'custom_js'                 => '',

		/* Analytics */
		'google_analytics_id'        => '',
		'google_tag_manager_id'     => '',
		'facebook_pixel_id'         => '',
		'bing_webmaster_code'       => '',
		'google_site_verification'  => '',

		/* Social */
		'facebook_url'              => '',
		'twitter_url'               => '',
		'linkedin_url'              => '',
		'instagram_url'             => '',
		'youtube_url'               => '',
		'pinterest_url'             => '',
		'tiktok_url'                => '',
		'github_url'                => '',
		'telegram_url'              => '',
		'whatsapp_url'              => '',

		/* Contact */
		'contact_phone'             => '',
		'contact_email'             => '',
		'contact_address'           => '',
		'contact_map_embed'         => '',

		/* Ads */
		'enable_ads'                => 0,
		'ad_header'                 => '',
		'ad_before_content'         => '',
		'ad_after_content'          => '',
		'ad_sidebar'                => '',
		'ad_footer'                 => '',

		/* WooCommerce */
		'enable_woocommerce_style'  => 1,
		'woo_shop_layout'           => 'grid',
		'woo_products_per_page'     => 12,
		'woo_columns'               => 4,
		'woo_show_cart_header'      => 1,

		/* Security */
		'disable_xmlrpc'            => 0,
		'disable_rest_user_links'   => 1,
		'remove_shortlink'          => 1,
	);
}

/**
 * Get theme options merged with defaults.
 *
 * @param string|null $key Option key.
 * @param mixed       $default Default value.
 * @return mixed
 */
function rx_theme_get_option( $key = null, $default = null ) {
	$defaults = rx_theme_default_options();
	$options  = get_option( RX_THEME_OPTION_KEY, array() );

	if ( ! is_array( $options ) ) {
		$options = array();
	}

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

	if ( null === $key ) {
		return $options;
	}

	if ( isset( $options[ $key ] ) ) {
		return $options[ $key ];
	}

	return $default;
}

/**
 * Update single theme option.
 *
 * @param string $key Option key.
 * @param mixed  $value Option value.
 * @return bool
 */
function rx_theme_update_option( $key, $value ) {
	$options         = rx_theme_get_option();
	$options[ $key ] = $value;

	return update_option( RX_THEME_OPTION_KEY, $options );
}

/**
 * Sanitize checkbox.
 *
 * @param mixed $value Value.
 * @return int
 */
function rx_theme_sanitize_checkbox( $value ) {
	return ! empty( $value ) ? 1 : 0;
}

/**
 * Sanitize select field.
 *
 * @param string $value Value.
 * @param array  $allowed Allowed values.
 * @param string $fallback Fallback value.
 * @return string
 */
function rx_theme_sanitize_select( $value, $allowed, $fallback ) {
	$value = sanitize_key( $value );

	return in_array( $value, $allowed, true ) ? $value : $fallback;
}

/**
 * Sanitize textarea allowing safe HTML.
 *
 * @param string $value Value.
 * @return string
 */
function rx_theme_sanitize_safe_html( $value ) {
	return wp_kses_post( $value );
}

/**
 * Sanitize script textarea.
 *
 * Admins with unfiltered_html can save scripts.
 *
 * @param string $value Value.
 * @return string
 */
function rx_theme_sanitize_script( $value ) {
	if ( current_user_can( 'unfiltered_html' ) ) {
		return $value;
	}

	return wp_kses_post( $value );
}

/**
 * Sanitize multiline URLs.
 *
 * @param string $value Value.
 * @return string
 */
function rx_theme_sanitize_multiline_urls( $value ) {
	$lines = preg_split( '/\r\n|\r|\n/', (string) $value );
	$clean = array();

	foreach ( $lines as $line ) {
		$line = trim( $line );

		if ( empty( $line ) ) {
			continue;
		}

		$clean[] = esc_url_raw( $line );
	}

	return implode( "\n", $clean );
}

/**
 * Sanitize all theme options.
 *
 * @param array $input Input.
 * @return array
 */
function rx_theme_sanitize_options( $input ) {
	$defaults = rx_theme_default_options();
	$output   = rx_theme_get_option();

	if ( ! is_array( $input ) ) {
		return $output;
	}

	$checkboxes = array(
		'enable_dark_mode',
		'enable_sticky_sidebar',
		'enable_back_to_top',
		'enable_preloader',
		'enable_smooth_scroll',
		'show_site_title',
		'show_site_tagline',
		'enable_sticky_header',
		'enable_top_bar',
		'enable_header_search',
		'enable_header_social',
		'enable_mobile_menu',
		'enable_footer_widgets',
		'enable_footer_menu',
		'enable_footer_social',
		'enable_footer_back_top',
		'enable_google_fonts',
		'show_post_thumbnail',
		'show_post_author',
		'show_post_date',
		'show_post_category',
		'show_post_tags',
		'show_post_excerpt',
		'enable_related_posts',
		'enable_author_box',
		'enable_post_navigation',
		'enable_comments',
		'enable_basic_seo',
		'enable_meta_description',
		'enable_og_tags',
		'enable_schema',
		'enable_breadcrumbs',
		'enable_noindex_search',
		'enable_noindex_404',
		'enable_dns_prefetch',
		'enable_preconnect',
		'enable_preload_fonts',
		'enable_lazy_loading',
		'disable_emoji_scripts',
		'disable_wp_embed',
		'remove_wp_version',
		'enable_defer_js',
		'enable_async_js',
		'enable_ads',
		'enable_woocommerce_style',
		'woo_show_cart_header',
		'disable_xmlrpc',
		'disable_rest_user_links',
		'remove_shortlink',
	);

	foreach ( $checkboxes as $key ) {
		$output[ $key ] = isset( $input[ $key ] ) ? rx_theme_sanitize_checkbox( $input[ $key ] ) : 0;
	}

	$url_fields = array(
		'custom_logo_url',
		'retina_logo_url',
		'favicon_url',
		'footer_logo_url',
		'og_default_image',
		'facebook_url',
		'twitter_url',
		'linkedin_url',
		'instagram_url',
		'youtube_url',
		'pinterest_url',
		'tiktok_url',
		'github_url',
		'telegram_url',
		'whatsapp_url',
	);

	foreach ( $url_fields as $key ) {
		if ( isset( $input[ $key ] ) ) {
			$output[ $key ] = esc_url_raw( $input[ $key ] );
		}
	}

	$text_fields = array(
		'top_bar_text',
		'top_bar_phone',
		'top_bar_email',
		'footer_copyright',
		'body_font_family',
		'heading_font_family',
		'read_more_text',
		'default_meta_description',
		'google_analytics_id',
		'google_tag_manager_id',
		'facebook_pixel_id',
		'bing_webmaster_code',
		'google_site_verification',
		'contact_phone',
		'contact_email',
		'contact_address',
		'defer_exclude_handles',
		'async_exclude_handles',
	);

	foreach ( $text_fields as $key ) {
		if ( isset( $input[ $key ] ) ) {
			$output[ $key ] = sanitize_text_field( $input[ $key ] );
		}
	}

	$color_fields = array(
		'primary_color',
		'secondary_color',
		'accent_color',
		'body_bg_color',
		'body_text_color',
		'heading_color',
		'link_color',
		'link_hover_color',
		'header_bg_color',
		'footer_bg_color',
		'footer_text_color',
	);

	foreach ( $color_fields as $key ) {
		if ( isset( $input[ $key ] ) ) {
			$output[ $key ] = sanitize_hex_color( $input[ $key ] ) ? sanitize_hex_color( $input[ $key ] ) : $defaults[ $key ];
		}
	}

	$int_fields = array(
		'container_width'       => array( 720, 1920 ),
		'body_font_size'        => array( 10, 30 ),
		'excerpt_length'        => array( 5, 100 ),
		'related_posts_count'   => array( 1, 12 ),
		'archive_columns'       => array( 1, 6 ),
		'woo_products_per_page' => array( 1, 60 ),
		'woo_columns'           => array( 1, 6 ),
	);

	foreach ( $int_fields as $key => $range ) {
		if ( isset( $input[ $key ] ) ) {
			$value          = absint( $input[ $key ] );
			$output[ $key ] = min( max( $value, $range[0] ), $range[1] );
		}
	}

	$float_fields = array(
		'body_line_height'    => array( 1, 3 ),
		'heading_line_height' => array( 1, 3 ),
	);

	foreach ( $float_fields as $key => $range ) {
		if ( isset( $input[ $key ] ) ) {
			$value          = floatval( $input[ $key ] );
			$output[ $key ] = min( max( $value, $range[0] ), $range[1] );
		}
	}

	if ( isset( $input['site_layout'] ) ) {
		$output['site_layout'] = rx_theme_sanitize_select(
			$input['site_layout'],
			array( 'full-width', 'left-sidebar', 'right-sidebar', 'no-sidebar' ),
			$defaults['site_layout']
		);
	}

	if ( isset( $input['header_layout'] ) ) {
		$output['header_layout'] = rx_theme_sanitize_select(
			$input['header_layout'],
			array( 'default', 'centered', 'split', 'minimal' ),
			$defaults['header_layout']
		);
	}

	if ( isset( $input['footer_layout'] ) ) {
		$output['footer_layout'] = rx_theme_sanitize_select(
			$input['footer_layout'],
			array( 'one-column', 'two-columns', 'three-columns', 'four-columns' ),
			$defaults['footer_layout']
		);
	}

	if ( isset( $input['blog_layout'] ) ) {
		$output['blog_layout'] = rx_theme_sanitize_select(
			$input['blog_layout'],
			array( 'list', 'grid', 'masonry' ),
			$defaults['blog_layout']
		);
	}

	if ( isset( $input['woo_shop_layout'] ) ) {
		$output['woo_shop_layout'] = rx_theme_sanitize_select(
			$input['woo_shop_layout'],
			array( 'grid', 'list' ),
			$defaults['woo_shop_layout']
		);
	}

	$textarea_safe_html = array(
		'contact_map_embed',
		'ad_header',
		'ad_before_content',
		'ad_after_content',
		'ad_sidebar',
		'ad_footer',
	);

	foreach ( $textarea_safe_html as $key ) {
		if ( isset( $input[ $key ] ) ) {
			$output[ $key ] = rx_theme_sanitize_safe_html( $input[ $key ] );
		}
	}

	$script_fields = array(
		'header_scripts',
		'footer_scripts',
		'custom_js',
	);

	foreach ( $script_fields as $key ) {
		if ( isset( $input[ $key ] ) ) {
			$output[ $key ] = rx_theme_sanitize_script( $input[ $key ] );
		}
	}

	if ( isset( $input['custom_css'] ) ) {
		$output['custom_css'] = wp_strip_all_tags( $input['custom_css'] );
	}

	if ( isset( $input['dns_prefetch_urls'] ) ) {
		$output['dns_prefetch_urls'] = rx_theme_sanitize_multiline_urls( $input['dns_prefetch_urls'] );
	}

	if ( isset( $input['preconnect_urls'] ) ) {
		$output['preconnect_urls'] = rx_theme_sanitize_multiline_urls( $input['preconnect_urls'] );
	}

	if ( isset( $input['preload_font_urls'] ) ) {
		$output['preload_font_urls'] = rx_theme_sanitize_multiline_urls( $input['preload_font_urls'] );
	}

	if ( isset( $input['google_fonts_url'] ) ) {
		$output['google_fonts_url'] = esc_url_raw( $input['google_fonts_url'] );
	}

	return $output;
}

/**
 * Register admin settings.
 */
function rx_theme_register_options() {
	register_setting(
		'rx_theme_options_group',
		RX_THEME_OPTION_KEY,
		array(
			'type'              => 'array',
			'sanitize_callback' => 'rx_theme_sanitize_options',
			'default'           => rx_theme_default_options(),
		)
	);
}
add_action( 'admin_init', 'rx_theme_register_options' );

/**
 * Add admin menu page.
 */
function rx_theme_options_menu() {
	add_theme_page(
		esc_html__( 'RX Theme Options', 'rx-theme' ),
		esc_html__( 'RX Theme Options', 'rx-theme' ),
		'manage_options',
		'rx-theme-options',
		'rx_theme_options_page'
	);
}
add_action( 'admin_menu', 'rx_theme_options_menu' );

/**
 * Enqueue admin assets.
 *
 * @param string $hook Hook.
 */
function rx_theme_options_admin_assets( $hook ) {
	if ( 'appearance_page_rx-theme-options' !== $hook ) {
		return;
	}

	wp_enqueue_style( 'wp-color-picker' );
	wp_enqueue_media();
	wp_enqueue_script( 'wp-color-picker' );

	$css = '
		.rx-options-wrap { max-width: 1200px; }
		.rx-options-header { background:#111827;color:#fff;padding:24px;border-radius:10px;margin:20px 0; }
		.rx-options-header h1 { color:#fff;margin:0 0 8px; }
		.rx-options-tabs { display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px; }
		.rx-options-tab { background:#fff;border:1px solid #ccd0d4;padding:10px 14px;border-radius:6px;text-decoration:none;color:#1d2327;font-weight:600; }
		.rx-options-tab.active { background:#2271b1;color:#fff;border-color:#2271b1; }
		.rx-section { background:#fff;border:1px solid #ccd0d4;border-radius:8px;margin-bottom:20px;padding:20px; }
		.rx-section h2 { margin-top:0;border-bottom:1px solid #eee;padding-bottom:10px; }
		.rx-field { display:grid;grid-template-columns:260px 1fr;gap:20px;padding:16px 0;border-bottom:1px solid #f0f0f0; }
		.rx-field:last-child { border-bottom:none; }
		.rx-field label { font-weight:600; }
		.rx-field input[type="text"],
		.rx-field input[type="url"],
		.rx-field input[type="email"],
		.rx-field input[type="number"],
		.rx-field textarea,
		.rx-field select { width:100%;max-width:680px; }
		.rx-field textarea { min-height:110px; }
		.rx-help { color:#646970;font-size:13px;margin-top:6px; }
		.rx-upload-row { display:flex;gap:8px;align-items:center;max-width:680px; }
		.rx-upload-row input { flex:1; }
		@media(max-width:782px){ .rx-field{grid-template-columns:1fr;} }
	';

	wp_add_inline_style( 'wp-color-picker', $css );

	$js = "
		jQuery(function($){
			$('.rx-color-field').wpColorPicker();

			$(document).on('click', '.rx-upload-button', function(e){
				e.preventDefault();

				var button = $(this);
				var input = button.closest('.rx-upload-row').find('input');
				var frame = wp.media({
					title: 'Select or Upload Media',
					button: { text: 'Use this file' },
					multiple: false
				});

				frame.on('select', function(){
					var attachment = frame.state().get('selection').first().toJSON();
					input.val(attachment.url).trigger('change');
				});

				frame.open();
			});

			$(document).on('click', '.rx-clear-button', function(e){
				e.preventDefault();
				$(this).closest('.rx-upload-row').find('input').val('').trigger('change');
			});

			$('.rx-options-tab').on('click', function(e){
				e.preventDefault();

				var target = $(this).attr('href');

				$('.rx-options-tab').removeClass('active');
				$(this).addClass('active');

				$('.rx-section').hide();
				$(target).show();

				window.location.hash = target;
			});

			var hash = window.location.hash;

			if(hash && $(hash).length){
				$('.rx-options-tab[href=\"' + hash + '\"]').trigger('click');
			}else{
				$('.rx-options-tab:first').trigger('click');
			}
		});
	";

	wp_add_inline_script( 'wp-color-picker', $js );
}
add_action( 'admin_enqueue_scripts', 'rx_theme_options_admin_assets' );

/**
 * Render text field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 * @param string $type Type.
 */
function rx_theme_render_text_field( $key, $label, $help = '', $type = 'text' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<input
				type="<?php echo esc_attr( $type ); ?>"
				id="rx_<?php echo esc_attr( $key ); ?>"
				name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
				value="<?php echo esc_attr( $value ); ?>"
			/>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render number field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 * @param int    $min Min.
 * @param int    $max Max.
 * @param string $step Step.
 */
function rx_theme_render_number_field( $key, $label, $help = '', $min = 0, $max = 9999, $step = '1' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<input
				type="number"
				id="rx_<?php echo esc_attr( $key ); ?>"
				name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
				value="<?php echo esc_attr( $value ); ?>"
				min="<?php echo esc_attr( $min ); ?>"
				max="<?php echo esc_attr( $max ); ?>"
				step="<?php echo esc_attr( $step ); ?>"
			/>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render textarea field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 */
function rx_theme_render_textarea_field( $key, $label, $help = '' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<textarea
				id="rx_<?php echo esc_attr( $key ); ?>"
				name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
				rows="6"
			><?php echo esc_textarea( $value ); ?></textarea>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render checkbox field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 */
function rx_theme_render_checkbox_field( $key, $label, $help = '' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<label>
				<input
					type="checkbox"
					id="rx_<?php echo esc_attr( $key ); ?>"
					name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
					value="1"
					<?php checked( 1, $value ); ?>
				/>
				<?php esc_html_e( 'Enable', 'rx-theme' ); ?>
			</label>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render select field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param array  $choices Choices.
 * @param string $help Help.
 */
function rx_theme_render_select_field( $key, $label, $choices, $help = '' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<select
				id="rx_<?php echo esc_attr( $key ); ?>"
				name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
			>
				<?php foreach ( $choices as $choice_value => $choice_label ) : ?>
					<option value="<?php echo esc_attr( $choice_value ); ?>" <?php selected( $value, $choice_value ); ?>>
						<?php echo esc_html( $choice_label ); ?>
					</option>
				<?php endforeach; ?>
			</select>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render color field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 */
function rx_theme_render_color_field( $key, $label, $help = '' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<input
				type="text"
				class="rx-color-field"
				id="rx_<?php echo esc_attr( $key ); ?>"
				name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
				value="<?php echo esc_attr( $value ); ?>"
			/>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render media upload field.
 *
 * @param string $key Key.
 * @param string $label Label.
 * @param string $help Help.
 */
function rx_theme_render_upload_field( $key, $label, $help = '' ) {
	$value = rx_theme_get_option( $key );
	?>
	<div class="rx-field">
		<label for="rx_<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $label ); ?></label>
		<div>
			<div class="rx-upload-row">
				<input
					type="url"
					id="rx_<?php echo esc_attr( $key ); ?>"
					name="<?php echo esc_attr( RX_THEME_OPTION_KEY ); ?>[<?php echo esc_attr( $key ); ?>]"
					value="<?php echo esc_url( $value ); ?>"
				/>
				<button class="button rx-upload-button"><?php esc_html_e( 'Upload', 'rx-theme' ); ?></button>
				<button class="button rx-clear-button"><?php esc_html_e( 'Clear', 'rx-theme' ); ?></button>
			</div>
			<?php if ( $help ) : ?>
				<p class="rx-help"><?php echo esc_html( $help ); ?></p>
			<?php endif; ?>
		</div>
	</div>
	<?php
}

/**
 * Render options page.
 */
function rx_theme_options_page() {
	if ( ! current_user_can( 'manage_options' ) ) {
		return;
	}
	?>
	<div class="wrap rx-options-wrap">
		<div class="rx-options-header">
			<h1><?php esc_html_e( 'RX Theme Options', 'rx-theme' ); ?></h1>
			<p><?php esc_html_e( 'Control branding, layout, colors, SEO, performance, scripts, social links, ads, footer, and more.', 'rx-theme' ); ?></p>
		</div>

		<form method="post" action="options.php">
			<?php settings_fields( 'rx_theme_options_group' ); ?>

			<div class="rx-options-tabs">
				<a class="rx-options-tab" href="#rx-general"><?php esc_html_e( 'General', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-branding"><?php esc_html_e( 'Branding', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-header"><?php esc_html_e( 'Header', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-footer"><?php esc_html_e( 'Footer', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-colors"><?php esc_html_e( 'Colors', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-typography"><?php esc_html_e( 'Typography', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-blog"><?php esc_html_e( 'Blog', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-seo"><?php esc_html_e( 'SEO', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-performance"><?php esc_html_e( 'Performance', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-scripts"><?php esc_html_e( 'Scripts', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-social"><?php esc_html_e( 'Social', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-contact"><?php esc_html_e( 'Contact', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-ads"><?php esc_html_e( 'Ads', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-woocommerce"><?php esc_html_e( 'WooCommerce', 'rx-theme' ); ?></a>
				<a class="rx-options-tab" href="#rx-security"><?php esc_html_e( 'Security', 'rx-theme' ); ?></a>
			</div>

			<section id="rx-general" class="rx-section">
				<h2><?php esc_html_e( 'General Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_select_field(
					'site_layout',
					'Site Layout',
					array(
						'full-width'    => 'Full Width',
						'left-sidebar'  => 'Left Sidebar',
						'right-sidebar' => 'Right Sidebar',
						'no-sidebar'    => 'No Sidebar',
					)
				);
				rx_theme_render_number_field( 'container_width', 'Container Width', 'Main container width in pixels.', 720, 1920 );
				rx_theme_render_checkbox_field( 'enable_dark_mode', 'Dark Mode', 'Enable dark mode class support.' );
				rx_theme_render_checkbox_field( 'enable_sticky_sidebar', 'Sticky Sidebar' );
				rx_theme_render_checkbox_field( 'enable_back_to_top', 'Back To Top Button' );
				rx_theme_render_checkbox_field( 'enable_preloader', 'Page Preloader' );
				rx_theme_render_checkbox_field( 'enable_smooth_scroll', 'Smooth Scroll' );
				?>
			</section>

			<section id="rx-branding" class="rx-section">
				<h2><?php esc_html_e( 'Branding Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_upload_field( 'custom_logo_url', 'Custom Logo URL' );
				rx_theme_render_upload_field( 'retina_logo_url', 'Retina Logo URL' );
				rx_theme_render_upload_field( 'favicon_url', 'Favicon URL' );
				rx_theme_render_upload_field( 'footer_logo_url', 'Footer Logo URL' );
				rx_theme_render_checkbox_field( 'show_site_title', 'Show Site Title' );
				rx_theme_render_checkbox_field( 'show_site_tagline', 'Show Site Tagline' );
				?>
			</section>

			<section id="rx-header" class="rx-section">
				<h2><?php esc_html_e( 'Header Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_select_field(
					'header_layout',
					'Header Layout',
					array(
						'default'  => 'Default',
						'centered' => 'Centered',
						'split'    => 'Split',
						'minimal'  => 'Minimal',
					)
				);
				rx_theme_render_checkbox_field( 'enable_sticky_header', 'Sticky Header' );
				rx_theme_render_checkbox_field( 'enable_top_bar', 'Top Bar' );
				rx_theme_render_text_field( 'top_bar_text', 'Top Bar Text' );
				rx_theme_render_text_field( 'top_bar_phone', 'Top Bar Phone' );
				rx_theme_render_text_field( 'top_bar_email', 'Top Bar Email', '', 'email' );
				rx_theme_render_checkbox_field( 'enable_header_search', 'Header Search' );
				rx_theme_render_checkbox_field( 'enable_header_social', 'Header Social Icons' );
				rx_theme_render_checkbox_field( 'enable_mobile_menu', 'Mobile Menu' );
				?>
			</section>

			<section id="rx-footer" class="rx-section">
				<h2><?php esc_html_e( 'Footer Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_select_field(
					'footer_layout',
					'Footer Layout',
					array(
						'one-column'    => 'One Column',
						'two-columns'   => 'Two Columns',
						'three-columns' => 'Three Columns',
						'four-columns'  => 'Four Columns',
					)
				);
				rx_theme_render_text_field( 'footer_copyright', 'Footer Copyright', 'Use {year} and {site_name} placeholders.' );
				rx_theme_render_checkbox_field( 'enable_footer_widgets', 'Footer Widgets' );
				rx_theme_render_checkbox_field( 'enable_footer_menu', 'Footer Menu' );
				rx_theme_render_checkbox_field( 'enable_footer_social', 'Footer Social Icons' );
				rx_theme_render_checkbox_field( 'enable_footer_back_top', 'Footer Back To Top' );
				?>
			</section>

			<section id="rx-colors" class="rx-section">
				<h2><?php esc_html_e( 'Color Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_color_field( 'primary_color', 'Primary Color' );
				rx_theme_render_color_field( 'secondary_color', 'Secondary Color' );
				rx_theme_render_color_field( 'accent_color', 'Accent Color' );
				rx_theme_render_color_field( 'body_bg_color', 'Body Background Color' );
				rx_theme_render_color_field( 'body_text_color', 'Body Text Color' );
				rx_theme_render_color_field( 'heading_color', 'Heading Color' );
				rx_theme_render_color_field( 'link_color', 'Link Color' );
				rx_theme_render_color_field( 'link_hover_color', 'Link Hover Color' );
				rx_theme_render_color_field( 'header_bg_color', 'Header Background Color' );
				rx_theme_render_color_field( 'footer_bg_color', 'Footer Background Color' );
				rx_theme_render_color_field( 'footer_text_color', 'Footer Text Color' );
				?>
			</section>

			<section id="rx-typography" class="rx-section">
				<h2><?php esc_html_e( 'Typography Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_text_field( 'body_font_family', 'Body Font Family', 'Example: Arial, system, Roboto, Open Sans.' );
				rx_theme_render_text_field( 'heading_font_family', 'Heading Font Family' );
				rx_theme_render_number_field( 'body_font_size', 'Body Font Size', 'Pixel value.', 10, 30 );
				rx_theme_render_number_field( 'body_line_height', 'Body Line Height', 'Example: 1.7', 1, 3, '0.1' );
				rx_theme_render_number_field( 'heading_line_height', 'Heading Line Height', 'Example: 1.3', 1, 3, '0.1' );
				rx_theme_render_checkbox_field( 'enable_google_fonts', 'Enable Google Fonts' );
				rx_theme_render_text_field( 'google_fonts_url', 'Google Fonts URL', 'Paste full Google Fonts CSS URL.', 'url' );
				?>
			</section>

			<section id="rx-blog" class="rx-section">
				<h2><?php esc_html_e( 'Blog Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_select_field(
					'blog_layout',
					'Blog Layout',
					array(
						'list'    => 'List',
						'grid'    => 'Grid',
						'masonry' => 'Masonry',
					)
				);
				rx_theme_render_number_field( 'archive_columns', 'Archive Columns', '', 1, 6 );
				rx_theme_render_checkbox_field( 'show_post_thumbnail', 'Show Post Thumbnail' );
				rx_theme_render_checkbox_field( 'show_post_author', 'Show Post Author' );
				rx_theme_render_checkbox_field( 'show_post_date', 'Show Post Date' );
				rx_theme_render_checkbox_field( 'show_post_category', 'Show Post Category' );
				rx_theme_render_checkbox_field( 'show_post_tags', 'Show Post Tags' );
				rx_theme_render_checkbox_field( 'show_post_excerpt', 'Show Post Excerpt' );
				rx_theme_render_number_field( 'excerpt_length', 'Excerpt Length', 'Number of words.', 5, 100 );
				rx_theme_render_text_field( 'read_more_text', 'Read More Text' );
				rx_theme_render_checkbox_field( 'enable_related_posts', 'Related Posts' );
				rx_theme_render_number_field( 'related_posts_count', 'Related Posts Count', '', 1, 12 );
				rx_theme_render_checkbox_field( 'enable_author_box', 'Author Box' );
				rx_theme_render_checkbox_field( 'enable_post_navigation', 'Post Navigation' );
				rx_theme_render_checkbox_field( 'enable_comments', 'Comments' );
				?>
			</section>

			<section id="rx-seo" class="rx-section">
				<h2><?php esc_html_e( 'SEO Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_checkbox_field( 'enable_basic_seo', 'Basic SEO' );
				rx_theme_render_checkbox_field( 'enable_meta_description', 'Meta Description' );
				rx_theme_render_textarea_field( 'default_meta_description', 'Default Meta Description' );
				rx_theme_render_checkbox_field( 'enable_og_tags', 'Open Graph Tags' );
				rx_theme_render_upload_field( 'og_default_image', 'Default Open Graph Image' );
				rx_theme_render_checkbox_field( 'enable_schema', 'Basic Schema Markup' );
				rx_theme_render_checkbox_field( 'enable_breadcrumbs', 'Breadcrumbs' );
				rx_theme_render_checkbox_field( 'enable_noindex_search', 'Noindex Search Pages' );
				rx_theme_render_checkbox_field( 'enable_noindex_404', 'Noindex 404 Pages' );
				?>
			</section>

			<section id="rx-performance" class="rx-section">
				<h2><?php esc_html_e( 'Performance Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_checkbox_field( 'enable_dns_prefetch', 'DNS Prefetch' );
				rx_theme_render_textarea_field( 'dns_prefetch_urls', 'DNS Prefetch URLs', 'One URL per line.' );
				rx_theme_render_checkbox_field( 'enable_preconnect', 'Preconnect' );
				rx_theme_render_textarea_field( 'preconnect_urls', 'Preconnect URLs', 'One URL per line.' );
				rx_theme_render_checkbox_field( 'enable_preload_fonts', 'Preload Fonts' );
				rx_theme_render_textarea_field( 'preload_font_urls', 'Preload Font URLs', 'One font URL per line.' );
				rx_theme_render_checkbox_field( 'enable_lazy_loading', 'Lazy Loading' );
				rx_theme_render_checkbox_field( 'disable_emoji_scripts', 'Disable Emoji Scripts' );
				rx_theme_render_checkbox_field( 'disable_wp_embed', 'Disable WP Embed' );
				rx_theme_render_checkbox_field( 'remove_wp_version', 'Remove WordPress Version' );
				rx_theme_render_checkbox_field( 'enable_defer_js', 'Defer JavaScript' );
				rx_theme_render_text_field( 'defer_exclude_handles', 'Defer Exclude Handles', 'Comma-separated script handles.' );
				rx_theme_render_checkbox_field( 'enable_async_js', 'Async JavaScript' );
				rx_theme_render_text_field( 'async_exclude_handles', 'Async Exclude Handles', 'Comma-separated script handles.' );
				?>
			</section>

			<section id="rx-scripts" class="rx-section">
				<h2><?php esc_html_e( 'Scripts and Custom Code', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_text_field( 'google_analytics_id', 'Google Analytics ID', 'Example: G-XXXXXXXXXX' );
				rx_theme_render_text_field( 'google_tag_manager_id', 'Google Tag Manager ID', 'Example: GTM-XXXXXXX' );
				rx_theme_render_text_field( 'facebook_pixel_id', 'Facebook Pixel ID' );
				rx_theme_render_text_field( 'google_site_verification', 'Google Site Verification Code' );
				rx_theme_render_text_field( 'bing_webmaster_code', 'Bing Webmaster Verification Code' );
				rx_theme_render_textarea_field( 'header_scripts', 'Header Scripts', 'Added before closing </head>. Use carefully.' );
				rx_theme_render_textarea_field( 'footer_scripts', 'Footer Scripts', 'Added before closing </body>. Use carefully.' );
				rx_theme_render_textarea_field( 'custom_css', 'Custom CSS' );
				rx_theme_render_textarea_field( 'custom_js', 'Custom JS', 'JS only, without opening script tag.' );
				?>
			</section>

			<section id="rx-social" class="rx-section">
				<h2><?php esc_html_e( 'Social Links', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_text_field( 'facebook_url', 'Facebook URL', '', 'url' );
				rx_theme_render_text_field( 'twitter_url', 'Twitter/X URL', '', 'url' );
				rx_theme_render_text_field( 'linkedin_url', 'LinkedIn URL', '', 'url' );
				rx_theme_render_text_field( 'instagram_url', 'Instagram URL', '', 'url' );
				rx_theme_render_text_field( 'youtube_url', 'YouTube URL', '', 'url' );
				rx_theme_render_text_field( 'pinterest_url', 'Pinterest URL', '', 'url' );
				rx_theme_render_text_field( 'tiktok_url', 'TikTok URL', '', 'url' );
				rx_theme_render_text_field( 'github_url', 'GitHub URL', '', 'url' );
				rx_theme_render_text_field( 'telegram_url', 'Telegram URL', '', 'url' );
				rx_theme_render_text_field( 'whatsapp_url', 'WhatsApp URL', '', 'url' );
				?>
			</section>

			<section id="rx-contact" class="rx-section">
				<h2><?php esc_html_e( 'Contact Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_text_field( 'contact_phone', 'Contact Phone' );
				rx_theme_render_text_field( 'contact_email', 'Contact Email', '', 'email' );
				rx_theme_render_text_field( 'contact_address', 'Contact Address' );
				rx_theme_render_textarea_field( 'contact_map_embed', 'Google Map Embed Code' );
				?>
			</section>

			<section id="rx-ads" class="rx-section">
				<h2><?php esc_html_e( 'Advertisement Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_checkbox_field( 'enable_ads', 'Enable Ads' );
				rx_theme_render_textarea_field( 'ad_header', 'Header Ad Code' );
				rx_theme_render_textarea_field( 'ad_before_content', 'Before Content Ad Code' );
				rx_theme_render_textarea_field( 'ad_after_content', 'After Content Ad Code' );
				rx_theme_render_textarea_field( 'ad_sidebar', 'Sidebar Ad Code' );
				rx_theme_render_textarea_field( 'ad_footer', 'Footer Ad Code' );
				?>
			</section>

			<section id="rx-woocommerce" class="rx-section">
				<h2><?php esc_html_e( 'WooCommerce Settings', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_checkbox_field( 'enable_woocommerce_style', 'WooCommerce Theme Style' );
				rx_theme_render_select_field(
					'woo_shop_layout',
					'Shop Layout',
					array(
						'grid' => 'Grid',
						'list' => 'List',
					)
				);
				rx_theme_render_number_field( 'woo_products_per_page', 'Products Per Page', '', 1, 60 );
				rx_theme_render_number_field( 'woo_columns', 'Product Columns', '', 1, 6 );
				rx_theme_render_checkbox_field( 'woo_show_cart_header', 'Show Cart Icon In Header' );
				?>
			</section>

			<section id="rx-security" class="rx-section">
				<h2><?php esc_html_e( 'Security and Cleanup', 'rx-theme' ); ?></h2>
				<?php
				rx_theme_render_checkbox_field( 'disable_xmlrpc', 'Disable XML-RPC' );
				rx_theme_render_checkbox_field( 'disable_rest_user_links', 'Remove REST API User Links' );
				rx_theme_render_checkbox_field( 'remove_shortlink', 'Remove Shortlink' );
				?>
			</section>

			<?php submit_button( esc_html__( 'Save RX Theme Options', 'rx-theme' ) ); ?>
		</form>
	</div>
	<?php
}

/**
 * Add body classes based on options.
 *
 * @param array $classes Body classes.
 * @return array
 */
function rx_theme_body_classes( $classes ) {
	$classes[] = 'rx-layout-' . sanitize_html_class( rx_theme_get_option( 'site_layout' ) );
	$classes[] = 'rx-header-' . sanitize_html_class( rx_theme_get_option( 'header_layout' ) );
	$classes[] = 'rx-blog-' . sanitize_html_class( rx_theme_get_option( 'blog_layout' ) );

	if ( rx_theme_get_option( 'enable_dark_mode' ) ) {
		$classes[] = 'rx-dark-mode';
	}

	if ( rx_theme_get_option( 'enable_sticky_header' ) ) {
		$classes[] = 'rx-sticky-header-enabled';
	}

	if ( rx_theme_get_option( 'enable_sticky_sidebar' ) ) {
		$classes[] = 'rx-sticky-sidebar-enabled';
	}

	return $classes;
}
add_filter( 'body_class', 'rx_theme_body_classes' );

/**
 * Output dynamic CSS.
 */
function rx_theme_dynamic_css() {
	$body_font    = rx_theme_get_option( 'body_font_family' );
	$heading_font = rx_theme_get_option( 'heading_font_family' );

	if ( 'system' === $body_font ) {
		$body_font = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif';
	}

	if ( 'system' === $heading_font ) {
		$heading_font = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif';
	}

	$css = '
		:root {
			--rx-primary-color: ' . esc_html( rx_theme_get_option( 'primary_color' ) ) . ';
			--rx-secondary-color: ' . esc_html( rx_theme_get_option( 'secondary_color' ) ) . ';
			--rx-accent-color: ' . esc_html( rx_theme_get_option( 'accent_color' ) ) . ';
			--rx-body-bg-color: ' . esc_html( rx_theme_get_option( 'body_bg_color' ) ) . ';
			--rx-body-text-color: ' . esc_html( rx_theme_get_option( 'body_text_color' ) ) . ';
			--rx-heading-color: ' . esc_html( rx_theme_get_option( 'heading_color' ) ) . ';
			--rx-link-color: ' . esc_html( rx_theme_get_option( 'link_color' ) ) . ';
			--rx-link-hover-color: ' . esc_html( rx_theme_get_option( 'link_hover_color' ) ) . ';
			--rx-header-bg-color: ' . esc_html( rx_theme_get_option( 'header_bg_color' ) ) . ';
			--rx-footer-bg-color: ' . esc_html( rx_theme_get_option( 'footer_bg_color' ) ) . ';
			--rx-footer-text-color: ' . esc_html( rx_theme_get_option( 'footer_text_color' ) ) . ';
			--rx-container-width: ' . absint( rx_theme_get_option( 'container_width' ) ) . 'px;
			--rx-body-font-family: ' . esc_html( $body_font ) . ';
			--rx-heading-font-family: ' . esc_html( $heading_font ) . ';
			--rx-body-font-size: ' . absint( rx_theme_get_option( 'body_font_size' ) ) . 'px;
			--rx-body-line-height: ' . esc_html( rx_theme_get_option( 'body_line_height' ) ) . ';
			--rx-heading-line-height: ' . esc_html( rx_theme_get_option( 'heading_line_height' ) ) . ';
		}

		body {
			background: var(--rx-body-bg-color);
			color: var(--rx-body-text-color);
			font-family: var(--rx-body-font-family);
			font-size: var(--rx-body-font-size);
			line-height: var(--rx-body-line-height);
		}

		h1, h2, h3, h4, h5, h6 {
			color: var(--rx-heading-color);
			font-family: var(--rx-heading-font-family);
			line-height: var(--rx-heading-line-height);
		}

		a {
			color: var(--rx-link-color);
		}

		a:hover {
			color: var(--rx-link-hover-color);
		}

		.rx-container,
		.container,
		.site-container {
			max-width: var(--rx-container-width);
			margin-left: auto;
			margin-right: auto;
		}

		.site-header {
			background: var(--rx-header-bg-color);
		}

		.site-footer {
			background: var(--rx-footer-bg-color);
			color: var(--rx-footer-text-color);
		}

		.site-footer a {
			color: var(--rx-footer-text-color);
		}

		.rx-sticky-header-enabled .site-header {
			position: sticky;
			top: 0;
			z-index: 999;
		}

		.rx-sticky-sidebar-enabled .widget-area {
			position: sticky;
			top: 90px;
		}

		.rx-back-to-top {
			position: fixed;
			right: 20px;
			bottom: 20px;
			z-index: 9999;
			display: inline-flex;
			align-items: center;
			justify-content: center;
			width: 44px;
			height: 44px;
			border-radius: 999px;
			text-decoration: none;
			background: var(--rx-primary-color);
			color: #fff;
		}

		.rx-dark-mode {
			--rx-body-bg-color: #0f172a;
			--rx-body-text-color: #e5e7eb;
			--rx-heading-color: #ffffff;
			--rx-header-bg-color: #111827;
			--rx-footer-bg-color: #020617;
		}
	';

	$custom_css = rx_theme_get_option( 'custom_css' );

	if ( ! empty( $custom_css ) ) {
		$css .= "\n" . $custom_css;
	}

	echo '<style id="rx-theme-dynamic-css">' . wp_strip_all_tags( $css ) . '</style>' . "\n";
}
add_action( 'wp_head', 'rx_theme_dynamic_css', 99 );

/**
 * Enqueue Google fonts if enabled.
 */
function rx_theme_enqueue_google_fonts() {
	if ( ! rx_theme_get_option( 'enable_google_fonts' ) ) {
		return;
	}

	$url = rx_theme_get_option( 'google_fonts_url' );

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

	wp_enqueue_style(
		'rx-google-fonts',
		esc_url( $url ),
		array(),
		null
	);
}
add_action( 'wp_enqueue_scripts', 'rx_theme_enqueue_google_fonts' );

/**
 * Output resource hints.
 */
function rx_theme_resource_hints() {
	if ( rx_theme_get_option( 'enable_dns_prefetch' ) ) {
		$urls = preg_split( '/\r\n|\r|\n/', rx_theme_get_option( 'dns_prefetch_urls' ) );

		foreach ( $urls as $url ) {
			$url = trim( $url );

			if ( $url ) {
				echo '<link rel="dns-prefetch" href="' . esc_url( $url ) . '">' . "\n";
			}
		}
	}

	if ( rx_theme_get_option( 'enable_preconnect' ) ) {
		$urls = preg_split( '/\r\n|\r|\n/', rx_theme_get_option( 'preconnect_urls' ) );

		foreach ( $urls as $url ) {
			$url = trim( $url );

			if ( $url ) {
				echo '<link rel="preconnect" href="' . esc_url( $url ) . '" crossorigin>' . "\n";
			}
		}
	}

	if ( rx_theme_get_option( 'enable_preload_fonts' ) ) {
		$urls = preg_split( '/\r\n|\r|\n/', rx_theme_get_option( 'preload_font_urls' ) );

		foreach ( $urls as $url ) {
			$url = trim( $url );

			if ( $url ) {
				echo '<link rel="preload" href="' . esc_url( $url ) . '" as="font" type="font/woff2" crossorigin>' . "\n";
			}
		}
	}
}
add_action( 'wp_head', 'rx_theme_resource_hints', 1 );

/**
 * Output verification tags.
 */
function rx_theme_verification_tags() {
	$google = rx_theme_get_option( 'google_site_verification' );
	$bing   = rx_theme_get_option( 'bing_webmaster_code' );

	if ( ! empty( $google ) ) {
		echo '<meta name="google-site-verification" content="' . esc_attr( $google ) . '">' . "\n";
	}

	if ( ! empty( $bing ) ) {
		echo '<meta name="msvalidate.01" content="' . esc_attr( $bing ) . '">' . "\n";
	}
}
add_action( 'wp_head', 'rx_theme_verification_tags', 2 );

/**
 * Output analytics scripts.
 */
function rx_theme_analytics_scripts() {
	$ga_id  = rx_theme_get_option( 'google_analytics_id' );
	$gtm_id = rx_theme_get_option( 'google_tag_manager_id' );
	$pixel  = rx_theme_get_option( 'facebook_pixel_id' );

	if ( ! empty( $gtm_id ) ) :
		?>
		<script>
			(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
			new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
			j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
			'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
			})(window,document,'script','dataLayer','<?php echo esc_js( $gtm_id ); ?>');
		</script>
		<?php
	endif;

	if ( ! empty( $ga_id ) ) :
		?>
		<script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo esc_attr( $ga_id ); ?>"></script>
		<script>
			window.dataLayer = window.dataLayer || [];
			function gtag(){dataLayer.push(arguments);}
			gtag('js', new Date());
			gtag('config', '<?php echo esc_js( $ga_id ); ?>');
		</script>
		<?php
	endif;

	if ( ! empty( $pixel ) ) :
		?>
		<script>
			!function(f,b,e,v,n,t,s)
			{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
			n.callMethod.apply(n,arguments):n.queue.push(arguments)};
			if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
			n.queue=[];t=b.createElement(e);t.async=!0;
			t.src=v;s=b.getElementsByTagName(e)[0];
			s.parentNode.insertBefore(t,s)}(window, document,'script',
			'https://connect.facebook.net/en_US/fbevents.js');
			fbq('init', '<?php echo esc_js( $pixel ); ?>');
			fbq('track', 'PageView');
		</script>
		<?php
	endif;
}
add_action( 'wp_head', 'rx_theme_analytics_scripts', 20 );

/**
 * Output custom header scripts.
 */
function rx_theme_custom_header_scripts() {
	$scripts = rx_theme_get_option( 'header_scripts' );

	if ( ! empty( $scripts ) ) {
		echo "\n<!-- RX Header Scripts -->\n";
		echo $scripts . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}
}
add_action( 'wp_head', 'rx_theme_custom_header_scripts', 100 );

/**
 * Output footer scripts and custom JS.
 */
function rx_theme_custom_footer_scripts() {
	$scripts = rx_theme_get_option( 'footer_scripts' );
	$custom  = rx_theme_get_option( 'custom_js' );

	if ( ! empty( $scripts ) ) {
		echo "\n<!-- RX Footer Scripts -->\n";
		echo $scripts . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	if ( ! empty( $custom ) ) {
		echo "\n<script id=\"rx-custom-js\">\n";
		echo $custom; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo "\n</script>\n";
	}
}
add_action( 'wp_footer', 'rx_theme_custom_footer_scripts', 100 );

/**
 * Add basic SEO meta tags.
 */
function rx_theme_basic_seo_tags() {
	if ( ! rx_theme_get_option( 'enable_basic_seo' ) ) {
		return;
	}

	if ( rx_theme_get_option( 'enable_noindex_search' ) && is_search() ) {
		echo '<meta name="robots" content="noindex,follow">' . "\n";
	}

	if ( rx_theme_get_option( 'enable_noindex_404' ) && is_404() ) {
		echo '<meta name="robots" content="noindex,follow">' . "\n";
	}

	if ( rx_theme_get_option( 'enable_meta_description' ) ) {
		$description = '';

		if ( is_singular() ) {
			global $post;

			if ( $post instanceof WP_Post ) {
				$description = has_excerpt( $post ) ? get_the_excerpt( $post ) : wp_trim_words( wp_strip_all_tags( $post->post_content ), 28 );
			}
		}

		if ( empty( $description ) ) {
			$description = rx_theme_get_option( 'default_meta_description' );
		}

		if ( empty( $description ) ) {
			$description = get_bloginfo( 'description' );
		}

		if ( ! empty( $description ) ) {
			echo '<meta name="description" content="' . esc_attr( wp_strip_all_tags( $description ) ) . '">' . "\n";
		}
	}

	if ( rx_theme_get_option( 'enable_og_tags' ) ) {
		$title       = wp_get_document_title();
		$url         = is_singular() ? get_permalink() : home_url( add_query_arg( array(), $GLOBALS['wp']->request ?? '' ) );
		$description = rx_theme_get_option( 'default_meta_description' );
		$image       = rx_theme_get_option( 'og_default_image' );

		if ( is_singular() ) {
			global $post;

			if ( $post instanceof WP_Post ) {
				$description = has_excerpt( $post ) ? get_the_excerpt( $post ) : wp_trim_words( wp_strip_all_tags( $post->post_content ), 28 );

				if ( has_post_thumbnail( $post ) ) {
					$image = get_the_post_thumbnail_url( $post, 'large' );
				}
			}
		}

		echo '<meta property="og:title" content="' . esc_attr( $title ) . '">' . "\n";
		echo '<meta property="og:type" content="' . ( is_singular() ? 'article' : 'website' ) . '">' . "\n";
		echo '<meta property="og:url" content="' . esc_url( $url ) . '">' . "\n";

		if ( ! empty( $description ) ) {
			echo '<meta property="og:description" content="' . esc_attr( wp_strip_all_tags( $description ) ) . '">' . "\n";
		}

		if ( ! empty( $image ) ) {
			echo '<meta property="og:image" content="' . esc_url( $image ) . '">' . "\n";
		}
	}
}
add_action( 'wp_head', 'rx_theme_basic_seo_tags', 5 );

/**
 * Add JSON-LD schema.
 */
function rx_theme_schema_markup() {
	if ( ! rx_theme_get_option( 'enable_schema' ) ) {
		return;
	}

	$schema = array(
		'@context' => 'https://schema.org',
		'@type'    => 'WebSite',
		'name'     => get_bloginfo( 'name' ),
		'url'      => home_url( '/' ),
	);

	if ( is_singular( 'post' ) ) {
		global $post;

		if ( $post instanceof WP_Post ) {
			$schema = array(
				'@context'      => 'https://schema.org',
				'@type'         => 'Article',
				'headline'      => get_the_title( $post ),
				'datePublished' => get_the_date( DATE_W3C, $post ),
				'dateModified'  => get_the_modified_date( DATE_W3C, $post ),
				'author'        => array(
					'@type' => 'Person',
					'name'  => get_the_author_meta( 'display_name', $post->post_author ),
				),
				'publisher'     => array(
					'@type' => 'Organization',
					'name'  => get_bloginfo( 'name' ),
				),
				'mainEntityOfPage' => get_permalink( $post ),
			);

			if ( has_post_thumbnail( $post ) ) {
				$schema['image'] = get_the_post_thumbnail_url( $post, 'large' );
			}
		}
	}

	echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
}
add_action( 'wp_head', 'rx_theme_schema_markup', 30 );

/**
 * Disable emojis.
 */
function rx_theme_disable_emojis() {
	if ( ! rx_theme_get_option( 'disable_emoji_scripts' ) ) {
		return;
	}

	remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
	remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
	remove_action( 'wp_print_styles', 'print_emoji_styles' );
	remove_action( 'admin_print_styles', 'print_emoji_styles' );
	remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
	remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
	remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
}
add_action( 'init', 'rx_theme_disable_emojis' );

/**
 * Disable WP embed.
 */
function rx_theme_disable_embed() {
	if ( ! rx_theme_get_option( 'disable_wp_embed' ) ) {
		return;
	}

	wp_deregister_script( 'wp-embed' );
}
add_action( 'wp_footer', 'rx_theme_disable_embed' );

/**
 * Remove WordPress version.
 *
 * @return string
 */
function rx_theme_remove_wp_version() {
	if ( rx_theme_get_option( 'remove_wp_version' ) ) {
		return '';
	}

	return get_bloginfo( 'version' );
}
add_filter( 'the_generator', 'rx_theme_remove_wp_version' );

/**
 * Remove shortlink.
 */
function rx_theme_remove_shortlink() {
	if ( rx_theme_get_option( 'remove_shortlink' ) ) {
		remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
		remove_action( 'template_redirect', 'wp_shortlink_header', 11 );
	}
}
add_action( 'init', 'rx_theme_remove_shortlink' );

/**
 * Disable XML-RPC.
 *
 * @param bool $enabled Enabled.
 * @return bool
 */
function rx_theme_disable_xmlrpc( $enabled ) {
	if ( rx_theme_get_option( 'disable_xmlrpc' ) ) {
		return false;
	}

	return $enabled;
}
add_filter( 'xmlrpc_enabled', 'rx_theme_disable_xmlrpc' );

/**
 * Remove REST user links.
 *
 * @param array $response Response.
 * @param object $user User.
 * @param object $request Request.
 * @return array
 */
function rx_theme_remove_rest_user_links( $response, $user, $request ) {
	if ( rx_theme_get_option( 'disable_rest_user_links' ) && isset( $response->data['link'] ) ) {
		unset( $response->data['link'] );
	}

	return $response;
}
add_filter( 'rest_prepare_user', 'rx_theme_remove_rest_user_links', 10, 3 );

/**
 * Add defer or async to scripts.
 *
 * @param string $tag Script tag.
 * @param string $handle Handle.
 * @param string $src Source.
 * @return string
 */
function rx_theme_script_loader_tag( $tag, $handle, $src ) {
	if ( is_admin() ) {
		return $tag;
	}

	$defer_enabled = rx_theme_get_option( 'enable_defer_js' );
	$async_enabled = rx_theme_get_option( 'enable_async_js' );

	if ( ! $defer_enabled && ! $async_enabled ) {
		return $tag;
	}

	$defer_excludes = array_map( 'trim', explode( ',', rx_theme_get_option( 'defer_exclude_handles' ) ) );
	$async_excludes = array_map( 'trim', explode( ',', rx_theme_get_option( 'async_exclude_handles' ) ) );

	if ( $async_enabled && ! in_array( $handle, $async_excludes, true ) ) {
		return str_replace( ' src', ' async src', $tag );
	}

	if ( $defer_enabled && ! in_array( $handle, $defer_excludes, true ) ) {
		return str_replace( ' src', ' defer src', $tag );
	}

	return $tag;
}
add_filter( 'script_loader_tag', 'rx_theme_script_loader_tag', 10, 3 );

/**
 * Lazy loading images.
 *
 * @param string $content Content.
 * @return string
 */
function rx_theme_lazy_loading_content_images( $content ) {
	if ( ! rx_theme_get_option( 'enable_lazy_loading' ) ) {
		return $content;
	}

	if ( false === strpos( $content, '<img' ) ) {
		return $content;
	}

	return preg_replace( '/<img(?![^>]+loading=)/i', '<img loading="lazy"', $content );
}
add_filter( 'the_content', 'rx_theme_lazy_loading_content_images' );

/**
 * Excerpt length.
 *
 * @param int $length Length.
 * @return int
 */
function rx_theme_excerpt_length( $length ) {
	return absint( rx_theme_get_option( 'excerpt_length', $length ) );
}
add_filter( 'excerpt_length', 'rx_theme_excerpt_length' );

/**
 * Excerpt more.
 *
 * @param string $more More.
 * @return string
 */
function rx_theme_excerpt_more( $more ) {
	return '...';
}
add_filter( 'excerpt_more', 'rx_theme_excerpt_more' );

/**
 * Comment open control.
 *
 * @param bool $open Open.
 * @param int  $post_id Post ID.
 * @return bool
 */
function rx_theme_comments_open_control( $open, $post_id ) {
	if ( ! rx_theme_get_option( 'enable_comments' ) && is_singular() ) {
		return false;
	}

	return $open;
}
add_filter( 'comments_open', 'rx_theme_comments_open_control', 10, 2 );

/**
 * Get footer copyright with placeholders.
 *
 * @return string
 */
function rx_theme_get_footer_copyright() {
	$text = rx_theme_get_option( 'footer_copyright' );

	$text = str_replace(
		array( '{year}', '{site_name}' ),
		array( date_i18n( 'Y' ), get_bloginfo( 'name' ) ),
		$text
	);

	return wp_kses_post( $text );
}

/**
 * Render social links.
 */
function rx_theme_social_links() {
	$socials = array(
		'facebook_url'  => 'Facebook',
		'twitter_url'   => 'X',
		'linkedin_url'  => 'LinkedIn',
		'instagram_url' => 'Instagram',
		'youtube_url'   => 'YouTube',
		'pinterest_url' => 'Pinterest',
		'tiktok_url'    => 'TikTok',
		'github_url'    => 'GitHub',
		'telegram_url'  => 'Telegram',
		'whatsapp_url'  => 'WhatsApp',
	);

	echo '<ul class="rx-social-links">';

	foreach ( $socials as $key => $label ) {
		$url = rx_theme_get_option( $key );

		if ( ! empty( $url ) ) {
			echo '<li><a href="' . esc_url( $url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html( $label ) . '</a></li>';
		}
	}

	echo '</ul>';
}

/**
 * Render breadcrumb.
 */
function rx_theme_breadcrumbs() {
	if ( ! rx_theme_get_option( 'enable_breadcrumbs' ) ) {
		return;
	}

	if ( is_front_page() ) {
		return;
	}

	echo '<nav class="rx-breadcrumbs" aria-label="' . esc_attr__( 'Breadcrumbs', 'rx-theme' ) . '">';
	echo '<a href="' . esc_url( home_url( '/' ) ) . '">' . esc_html__( 'Home', 'rx-theme' ) . '</a>';

	if ( is_category() || is_single() ) {
		echo ' <span>/</span> ';

		$category = get_the_category();

		if ( ! empty( $category ) ) {
			echo '<a href="' . esc_url( get_category_link( $category[0]->term_id ) ) . '">' . esc_html( $category[0]->name ) . '</a>';
		}

		if ( is_single() ) {
			echo ' <span>/</span> ';
			echo '<span>' . esc_html( get_the_title() ) . '</span>';
		}
	} elseif ( is_page() ) {
		echo ' <span>/</span> ';
		echo '<span>' . esc_html( get_the_title() ) . '</span>';
	} elseif ( is_search() ) {
		echo ' <span>/</span> ';
		echo '<span>' . esc_html__( 'Search', 'rx-theme' ) . '</span>';
	} elseif ( is_404() ) {
		echo ' <span>/</span> ';
		echo '<span>' . esc_html__( '404', 'rx-theme' ) . '</span>';
	}

	echo '</nav>';
}

/**
 * Render ad slot.
 *
 * @param string $slot Slot key.
 */
function rx_theme_ad_slot( $slot ) {
	if ( ! rx_theme_get_option( 'enable_ads' ) ) {
		return;
	}

	$key  = 'ad_' . $slot;
	$code = rx_theme_get_option( $key );

	if ( ! empty( $code ) ) {
		echo '<div class="rx-ad rx-ad-' . esc_attr( $slot ) . '">';
		echo $code; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo '</div>';
	}
}

/**
 * Add before and after content ads automatically.
 *
 * @param string $content Content.
 * @return string
 */
function rx_theme_content_ads( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}

	if ( ! rx_theme_get_option( 'enable_ads' ) ) {
		return $content;
	}

	ob_start();
	rx_theme_ad_slot( 'before_content' );
	$before = ob_get_clean();

	ob_start();
	rx_theme_ad_slot( 'after_content' );
	$after = ob_get_clean();

	return $before . $content . $after;
}
add_filter( 'the_content', 'rx_theme_content_ads', 8 );

/**
 * Render related posts.
 *
 * @param int|null $post_id Post ID.
 */
function rx_theme_related_posts( $post_id = null ) {
	if ( ! rx_theme_get_option( 'enable_related_posts' ) ) {
		return;
	}

	$post_id = $post_id ? absint( $post_id ) : get_the_ID();

	if ( ! $post_id ) {
		return;
	}

	$categories = wp_get_post_categories( $post_id );

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

	$query = new WP_Query(
		array(
			'post_type'           => 'post',
			'posts_per_page'      => absint( rx_theme_get_option( 'related_posts_count', 3 ) ),
			'post__not_in'        => array( $post_id ),
			'category__in'        => $categories,
			'ignore_sticky_posts' => true,
		)
	);

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

	echo '<section class="rx-related-posts">';
	echo '<h2>' . esc_html__( 'Related Posts', 'rx-theme' ) . '</h2>';
	echo '<div class="rx-related-posts-grid">';

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

		echo '<article class="rx-related-post">';
		if ( has_post_thumbnail() ) {
			echo '<a href="' . esc_url( get_permalink() ) . '">' . get_the_post_thumbnail( get_the_ID(), 'medium' ) . '</a>';
		}
		echo '<h3><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a></h3>';
		echo '</article>';
	}

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

	wp_reset_postdata();
}

/**
 * Render author box.
 */
function rx_theme_author_box() {
	if ( ! rx_theme_get_option( 'enable_author_box' ) || ! is_single() ) {
		return;
	}

	$author_id = get_the_author_meta( 'ID' );

	echo '<section class="rx-author-box">';
	echo get_avatar( $author_id, 80 );
	echo '<div class="rx-author-info">';
	echo '<h3>' . esc_html( get_the_author_meta( 'display_name', $author_id ) ) . '</h3>';
	echo '<p>' . esc_html( get_the_author_meta( 'description', $author_id ) ) . '</p>';
	echo '</div>';
	echo '</section>';
}

/**
 * WooCommerce product count.
 *
 * @param int $count Count.
 * @return int
 */
function rx_theme_woo_products_per_page( $count ) {
	return absint( rx_theme_get_option( 'woo_products_per_page', $count ) );
}
add_filter( 'loop_shop_per_page', 'rx_theme_woo_products_per_page', 20 );

/**
 * WooCommerce columns.
 *
 * @param int $columns Columns.
 * @return int
 */
function rx_theme_woo_columns( $columns ) {
	return absint( rx_theme_get_option( 'woo_columns', $columns ) );
}
add_filter( 'loop_shop_columns', 'rx_theme_woo_columns' );

/**
 * Back to top button.
 */
function rx_theme_back_to_top_button() {
	if ( ! rx_theme_get_option( 'enable_back_to_top' ) && ! rx_theme_get_option( 'enable_footer_back_top' ) ) {
		return;
	}

	echo '<a class="rx-back-to-top" href="#page" aria-label="' . esc_attr__( 'Back to top', 'rx-theme' ) . '">↑</a>';
}
add_action( 'wp_footer', 'rx_theme_back_to_top_button', 20 );

/**
 * Preloader markup.
 */
function rx_theme_preloader_markup() {
	if ( ! rx_theme_get_option( 'enable_preloader' ) ) {
		return;
	}

	echo '<div id="rx-preloader" class="rx-preloader"><div class="rx-preloader-spinner"></div></div>';
}
add_action( 'wp_body_open', 'rx_theme_preloader_markup' );

/**
 * Preloader script.
 */
function rx_theme_preloader_script() {
	if ( ! rx_theme_get_option( 'enable_preloader' ) ) {
		return;
	}
	?>
	<script>
		window.addEventListener('load', function(){
			var preloader = document.getElementById('rx-preloader');
			if(preloader){
				preloader.style.opacity = '0';
				setTimeout(function(){
					preloader.remove();
				}, 300);
			}
		});
	</script>
	<?php
}
add_action( 'wp_footer', 'rx_theme_preloader_script' );

/**
 * Add Customizer settings linked to same option array.
 *
 * @param WP_Customize_Manager $wp_customize Customizer.
 */
function rx_theme_customize_register( $wp_customize ) {
	$wp_customize->add_panel(
		'rx_theme_panel',
		array(
			'title'       => esc_html__( 'RX Theme Options', 'rx-theme' ),
			'description' => esc_html__( 'RX Theme quick customization options.', 'rx-theme' ),
			'priority'    => 30,
		)
	);

	$wp_customize->add_section(
		'rx_theme_colors',
		array(
			'title' => esc_html__( 'RX Colors', 'rx-theme' ),
			'panel' => 'rx_theme_panel',
		)
	);

	$colors = array(
		'primary_color'     => 'Primary Color',
		'secondary_color'   => 'Secondary Color',
		'accent_color'      => 'Accent Color',
		'body_bg_color'     => 'Body Background Color',
		'body_text_color'   => 'Body Text Color',
		'heading_color'     => 'Heading Color',
		'link_color'        => 'Link Color',
		'link_hover_color'  => 'Link Hover Color',
		'header_bg_color'   => 'Header Background Color',
		'footer_bg_color'   => 'Footer Background Color',
		'footer_text_color' => 'Footer Text Color',
	);

	foreach ( $colors as $key => $label ) {
		$wp_customize->add_setting(
			RX_THEME_OPTION_KEY . '[' . $key . ']',
			array(
				'type'              => 'option',
				'default'           => rx_theme_get_option( $key ),
				'sanitize_callback' => 'sanitize_hex_color',
			)
		);

		$wp_customize->add_control(
			new WP_Customize_Color_Control(
				$wp_customize,
				'rx_' . $key,
				array(
					'label'    => esc_html( $label ),
					'section'  => 'rx_theme_colors',
					'settings' => RX_THEME_OPTION_KEY . '[' . $key . ']',
				)
			)
		);
	}

	$wp_customize->add_section(
		'rx_theme_layout',
		array(
			'title' => esc_html__( 'RX Layout', 'rx-theme' ),
			'panel' => 'rx_theme_panel',
		)
	);

	$wp_customize->add_setting(
		RX_THEME_OPTION_KEY . '[site_layout]',
		array(
			'type'              => 'option',
			'default'           => rx_theme_get_option( 'site_layout' ),
			'sanitize_callback' => function( $value ) {
				return rx_theme_sanitize_select(
					$value,
					array( 'full-width', 'left-sidebar', 'right-sidebar', 'no-sidebar' ),
					'right-sidebar'
				);
			},
		)
	);

	$wp_customize->add_control(
		'rx_site_layout',
		array(
			'label'    => esc_html__( 'Site Layout', 'rx-theme' ),
			'section'  => 'rx_theme_layout',
			'settings' => RX_THEME_OPTION_KEY . '[site_layout]',
			'type'     => 'select',
			'choices'  => array(
				'full-width'    => 'Full Width',
				'left-sidebar'  => 'Left Sidebar',
				'right-sidebar' => 'Right Sidebar',
				'no-sidebar'    => 'No Sidebar',
			),
		)
	);
}
add_action( 'customize_register', 'rx_theme_customize_register' );

/**
 * Reset options by URL action.
 *
 * Example:
 * /wp-admin/themes.php?page=rx-theme-options&rx_reset_options=1&_wpnonce=...
 */
function rx_theme_maybe_reset_options() {
	if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
		return;
	}

	if ( ! isset( $_GET['rx_reset_options'] ) ) {
		return;
	}

	check_admin_referer( 'rx_reset_theme_options' );

	update_option( RX_THEME_OPTION_KEY, rx_theme_default_options() );

	wp_safe_redirect( admin_url( 'themes.php?page=rx-theme-options&reset=success' ) );
	exit;
}
add_action( 'admin_init', 'rx_theme_maybe_reset_options' );

Useful template calls

You can use these inside theme files:

<?php rx_theme_breadcrumbs(); ?>
<?php rx_theme_social_links(); ?>
<?php echo rx_theme_get_footer_copyright(); ?>
<?php rx_theme_related_posts(); ?>
<?php rx_theme_author_box(); ?>
<?php rx_theme_ad_slot( 'header' ); ?>
<?php rx_theme_ad_slot( 'sidebar' ); ?>
<?php rx_theme_ad_slot( 'footer' ); ?>

Recommended folder structure

rx-theme/
├── functions.php
├── style.css
├── header.php
├── footer.php
├── single.php
├── archive.php
├── inc/
│   └── options/
│       └── theme-options.php

This file creates a full admin panel under:

Appearance > RX Theme Options

Leave a Reply

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