search-toggle.php

I’ll build this as a strong search-toggle.php template part for your RX Theme: accessible button, overlay/modal search, mobile-friendly UI, keyboard support hooks, schema-friendly markup, security escaping, and WordPress fallback support.

Absolutely, my friend. Create this file:

rx-theme/template-parts/header/search-toggle.php

This is an advanced RX Theme search toggle template part with: search button, accessible search dialog, overlay, close button, popular keywords area, category quick links, post type selector support, live-search ready attributes, keyboard-accessible markup, fallback form, hooks, and safe WordPress escaping.

<?php
/**
 * Template Part: Header Search Toggle
 *
 * File: template-parts/header/search-toggle.php
 *
 * Advanced search toggle component for RX Theme.
 *
 * Features:
 * - Accessible search toggle button
 * - Fullscreen / dropdown search overlay
 * - WordPress search form
 * - ARIA attributes
 * - Keyboard friendly structure
 * - Close button
 * - Popular search suggestions
 * - Category quick links
 * - Optional post type selector
 * - Live search ready data attributes
 * - Noscript fallback
 * - Theme hooks for future extension
 *
 * @package RX_Theme
 */

defined( 'ABSPATH' ) || exit;

/**
 * ------------------------------------------------------------
 * Basic Component Settings
 * ------------------------------------------------------------
 */

$rx_search_id        = wp_unique_id( 'rx-header-search-' );
$rx_dialog_id        = $rx_search_id . '-dialog';
$rx_input_id         = $rx_search_id . '-input';
$rx_label_id         = $rx_search_id . '-label';
$rx_description_id   = $rx_search_id . '-description';
$rx_search_query     = get_search_query();
$rx_home_url         = home_url( '/' );
$rx_search_action    = esc_url( $rx_home_url );
$rx_enable_live      = apply_filters( 'rx_theme_header_search_enable_live_search', true );
$rx_enable_post_type = apply_filters( 'rx_theme_header_search_enable_post_type_selector', true );
$rx_enable_popular   = apply_filters( 'rx_theme_header_search_enable_popular_keywords', true );
$rx_enable_category  = apply_filters( 'rx_theme_header_search_enable_category_links', true );
$rx_enable_overlay   = apply_filters( 'rx_theme_header_search_enable_overlay', true );
$rx_min_chars        = absint( apply_filters( 'rx_theme_header_search_live_min_chars', 2 ) );
$rx_delay            = absint( apply_filters( 'rx_theme_header_search_live_delay', 300 ) );

/**
 * ------------------------------------------------------------
 * Search Placeholder
 * ------------------------------------------------------------
 */

$rx_placeholder = apply_filters(
	'rx_theme_header_search_placeholder',
	__( 'Search articles, diseases, symptoms, treatments...', 'rx-theme' )
);

/**
 * ------------------------------------------------------------
 * Popular Keywords
 * ------------------------------------------------------------
 */

$rx_popular_keywords = apply_filters(
	'rx_theme_header_search_popular_keywords',
	array(
		__( 'Back Pain', 'rx-theme' ),
		__( 'Diabetes', 'rx-theme' ),
		__( 'Hypertension', 'rx-theme' ),
		__( 'Neck Pain', 'rx-theme' ),
		__( 'Eye Disease', 'rx-theme' ),
		__( 'Blood Test', 'rx-theme' ),
	)
);

/**
 * ------------------------------------------------------------
 * Searchable Post Types
 * ------------------------------------------------------------
 */

$rx_searchable_post_types = apply_filters(
	'rx_theme_header_search_post_types',
	array(
		'post' => __( 'Articles', 'rx-theme' ),
		'page' => __( 'Pages', 'rx-theme' ),
	)
);

/**
 * ------------------------------------------------------------
 * Categories
 * ------------------------------------------------------------
 */

$rx_search_categories = array();

if ( $rx_enable_category ) {
	$rx_search_categories = get_categories(
		array(
			'orderby'    => 'count',
			'order'      => 'DESC',
			'number'     => 6,
			'hide_empty' => true,
		)
	);
}

/**
 * ------------------------------------------------------------
 * Component Classes
 * ------------------------------------------------------------
 */

$rx_component_classes = array(
	'rx-header-search',
	'rx-header-search--advanced',
);

if ( $rx_enable_overlay ) {
	$rx_component_classes[] = 'rx-header-search--overlay-enabled';
}

if ( $rx_enable_live ) {
	$rx_component_classes[] = 'rx-header-search--live-enabled';
}

$rx_component_class = implode( ' ', array_map( 'sanitize_html_class', $rx_component_classes ) );

?>

<div
	class="<?php echo esc_attr( $rx_component_class ); ?>"
	data-rx-header-search
	data-live-search="<?php echo $rx_enable_live ? 'true' : 'false'; ?>"
	data-min-chars="<?php echo esc_attr( $rx_min_chars ); ?>"
	data-delay="<?php echo esc_attr( $rx_delay ); ?>"
>
	<?php
	/**
	 * Hook: Before header search toggle.
	 */
	do_action( 'rx_theme_before_header_search_toggle' );
	?>

	<button
		type="button"
		class="rx-header-search__toggle"
		aria-label="<?php esc_attr_e( 'Open search', 'rx-theme' ); ?>"
		aria-expanded="false"
		aria-controls="<?php echo esc_attr( $rx_dialog_id ); ?>"
		data-rx-search-open
	>
		<span class="rx-header-search__toggle-icon" aria-hidden="true">
			<svg
				width="22"
				height="22"
				viewBox="0 0 24 24"
				fill="none"
				xmlns="http://www.w3.org/2000/svg"
				focusable="false"
			>
				<path
					d="M10.75 18.5C6.47 18.5 3 15.03 3 10.75S6.47 3 10.75 3s7.75 3.47 7.75 7.75a7.72 7.72 0 0 1-1.73 4.88l3.8 3.8a1 1 0 0 1-1.42 1.42l-3.8-3.8a7.72 7.72 0 0 1-4.6 1.45Zm0-2C13.93 16.5 16.5 13.93 16.5 10.75S13.93 5 10.75 5 5 7.57 5 10.75s2.57 5.75 5.75 5.75Z"
					fill="currentColor"
				/>
			</svg>
		</span>

		<span class="rx-header-search__toggle-text">
			<?php esc_html_e( 'Search', 'rx-theme' ); ?>
		</span>
	</button>

	<div
		id="<?php echo esc_attr( $rx_dialog_id ); ?>"
		class="rx-header-search__dialog"
		role="dialog"
		aria-modal="true"
		aria-labelledby="<?php echo esc_attr( $rx_label_id ); ?>"
		aria-describedby="<?php echo esc_attr( $rx_description_id ); ?>"
		hidden
		data-rx-search-dialog
	>
		<div
			class="rx-header-search__backdrop"
			data-rx-search-close
			aria-hidden="true"
		></div>

		<div class="rx-header-search__panel" role="document">
			<div class="rx-header-search__panel-inner">

				<div class="rx-header-search__top">
					<div class="rx-header-search__heading-wrap">
						<h2
							id="<?php echo esc_attr( $rx_label_id ); ?>"
							class="rx-header-search__heading"
						>
							<?php esc_html_e( 'Search RX Theme', 'rx-theme' ); ?>
						</h2>

						<p
							id="<?php echo esc_attr( $rx_description_id ); ?>"
							class="rx-header-search__description"
						>
							<?php esc_html_e( 'Type your keyword and press Enter to search.', 'rx-theme' ); ?>
						</p>
					</div>

					<button
						type="button"
						class="rx-header-search__close"
						aria-label="<?php esc_attr_e( 'Close search', 'rx-theme' ); ?>"
						data-rx-search-close
					>
						<span aria-hidden="true">
							<svg
								width="24"
								height="24"
								viewBox="0 0 24 24"
								fill="none"
								xmlns="http://www.w3.org/2000/svg"
								focusable="false"
							>
								<path
									d="M6.22 4.81a1 1 0 0 1 1.41 0L12 9.17l4.37-4.36a1 1 0 1 1 1.41 1.41L13.41 10.6l4.37 4.36a1 1 0 0 1-1.41 1.42L12 12.01l-4.37 4.37a1 1 0 0 1-1.41-1.42l4.36-4.36-4.36-4.38a1 1 0 0 1 0-1.41Z"
									fill="currentColor"
								/>
							</svg>
						</span>
					</button>
				</div>

				<?php
				/**
				 * Hook: Before header search form.
				 */
				do_action( 'rx_theme_before_header_search_form' );
				?>

				<form
					role="search"
					method="get"
					class="rx-header-search__form"
					action="<?php echo $rx_search_action; ?>"
					data-rx-search-form
				>
					<div class="rx-header-search__form-row">

						<label
							class="screen-reader-text"
							for="<?php echo esc_attr( $rx_input_id ); ?>"
						>
							<?php esc_html_e( 'Search for:', 'rx-theme' ); ?>
						</label>

						<div class="rx-header-search__input-wrap">
							<span class="rx-header-search__input-icon" aria-hidden="true">
								<svg
									width="22"
									height="22"
									viewBox="0 0 24 24"
									fill="none"
									xmlns="http://www.w3.org/2000/svg"
									focusable="false"
								>
									<path
										d="M10.75 18.5C6.47 18.5 3 15.03 3 10.75S6.47 3 10.75 3s7.75 3.47 7.75 7.75a7.72 7.72 0 0 1-1.73 4.88l3.8 3.8a1 1 0 0 1-1.42 1.42l-3.8-3.8a7.72 7.72 0 0 1-4.6 1.45Zm0-2C13.93 16.5 16.5 13.93 16.5 10.75S13.93 5 10.75 5 5 7.57 5 10.75s2.57 5.75 5.75 5.75Z"
										fill="currentColor"
									/>
								</svg>
							</span>

							<input
								id="<?php echo esc_attr( $rx_input_id ); ?>"
								type="search"
								class="rx-header-search__input"
								name="s"
								value="<?php echo esc_attr( $rx_search_query ); ?>"
								placeholder="<?php echo esc_attr( $rx_placeholder ); ?>"
								autocomplete="off"
								autocapitalize="none"
								spellcheck="true"
								inputmode="search"
								data-rx-search-input
							/>

							<button
								type="button"
								class="rx-header-search__clear"
								aria-label="<?php esc_attr_e( 'Clear search text', 'rx-theme' ); ?>"
								data-rx-search-clear
								hidden
							>
								<?php esc_html_e( 'Clear', 'rx-theme' ); ?>
							</button>
						</div>

						<button
							type="submit"
							class="rx-header-search__submit"
						>
							<span class="rx-header-search__submit-text">
								<?php esc_html_e( 'Search', 'rx-theme' ); ?>
							</span>

							<span class="rx-header-search__submit-icon" aria-hidden="true">
								<svg
									width="20"
									height="20"
									viewBox="0 0 24 24"
									fill="none"
									xmlns="http://www.w3.org/2000/svg"
									focusable="false"
								>
									<path
										d="M13.29 5.29a1 1 0 0 1 1.42 0l6 6a1 1 0 0 1 0 1.42l-6 6a1 1 0 0 1-1.42-1.42L17.59 13H4a1 1 0 1 1 0-2h13.59l-4.3-4.29a1 1 0 0 1 0-1.42Z"
										fill="currentColor"
									/>
								</svg>
							</span>
						</button>
					</div>

					<?php if ( $rx_enable_post_type && ! empty( $rx_searchable_post_types ) ) : ?>
						<div class="rx-header-search__filters">
							<label
								class="rx-header-search__filter-label"
								for="<?php echo esc_attr( $rx_search_id . '-post-type' ); ?>"
							>
								<?php esc_html_e( 'Search in', 'rx-theme' ); ?>
							</label>

							<select
								id="<?php echo esc_attr( $rx_search_id . '-post-type' ); ?>"
								class="rx-header-search__post-type"
								name="post_type"
								data-rx-search-post-type
							>
								<option value="">
									<?php esc_html_e( 'Everything', 'rx-theme' ); ?>
								</option>

								<?php foreach ( $rx_searchable_post_types as $rx_post_type_key => $rx_post_type_label ) : ?>
									<option value="<?php echo esc_attr( $rx_post_type_key ); ?>">
										<?php echo esc_html( $rx_post_type_label ); ?>
									</option>
								<?php endforeach; ?>
							</select>
						</div>
					<?php endif; ?>

					<?php
					/**
					 * Hook: Inside header search form bottom.
					 */
					do_action( 'rx_theme_header_search_form_bottom' );
					?>
				</form>

				<?php
				/**
				 * Hook: After header search form.
				 */
				do_action( 'rx_theme_after_header_search_form' );
				?>

				<?php if ( $rx_enable_live ) : ?>
					<div
						class="rx-header-search__live"
						aria-live="polite"
						aria-relevant="additions text"
						data-rx-search-live
					>
						<div
							class="rx-header-search__live-status"
							data-rx-search-status
							hidden
						>
							<?php esc_html_e( 'Searching...', 'rx-theme' ); ?>
						</div>

						<div
							class="rx-header-search__live-results"
							data-rx-search-results
						></div>
					</div>
				<?php endif; ?>

				<?php if ( $rx_enable_popular && ! empty( $rx_popular_keywords ) ) : ?>
					<div class="rx-header-search__popular">
						<h3 class="rx-header-search__section-title">
							<?php esc_html_e( 'Popular Searches', 'rx-theme' ); ?>
						</h3>

						<ul class="rx-header-search__popular-list">
							<?php foreach ( $rx_popular_keywords as $rx_keyword ) : ?>
								<?php
								$rx_keyword = trim( wp_strip_all_tags( $rx_keyword ) );

								if ( '' === $rx_keyword ) {
									continue;
								}

								$rx_keyword_url = add_query_arg(
									array(
										's' => rawurlencode( $rx_keyword ),
									),
									$rx_home_url
								);
								?>

								<li class="rx-header-search__popular-item">
									<a
										class="rx-header-search__popular-link"
										href="<?php echo esc_url( $rx_keyword_url ); ?>"
									>
										<?php echo esc_html( $rx_keyword ); ?>
									</a>
								</li>
							<?php endforeach; ?>
						</ul>
					</div>
				<?php endif; ?>

				<?php if ( $rx_enable_category && ! empty( $rx_search_categories ) && ! is_wp_error( $rx_search_categories ) ) : ?>
					<div class="rx-header-search__categories">
						<h3 class="rx-header-search__section-title">
							<?php esc_html_e( 'Browse Categories', 'rx-theme' ); ?>
						</h3>

						<ul class="rx-header-search__category-list">
							<?php foreach ( $rx_search_categories as $rx_category ) : ?>
								<li class="rx-header-search__category-item">
									<a
										class="rx-header-search__category-link"
										href="<?php echo esc_url( get_category_link( $rx_category ) ); ?>"
									>
										<span class="rx-header-search__category-name">
											<?php echo esc_html( $rx_category->name ); ?>
										</span>

										<span class="rx-header-search__category-count">
											<?php echo esc_html( number_format_i18n( $rx_category->count ) ); ?>
										</span>
									</a>
								</li>
							<?php endforeach; ?>
						</ul>
					</div>
				<?php endif; ?>

				<div class="rx-header-search__help">
					<p>
						<?php esc_html_e( 'Tip: Use simple medical words such as pain, fever, blood test, eye disease, or back pain.', 'rx-theme' ); ?>
					</p>
				</div>

				<noscript>
					<div class="rx-header-search__noscript">
						<p>
							<?php esc_html_e( 'JavaScript is disabled. You can still use the search form above.', 'rx-theme' ); ?>
						</p>
					</div>
				</noscript>

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

	<?php
	/**
	 * Hook: After header search toggle.
	 */
	do_action( 'rx_theme_after_header_search_toggle' );
	?>
</div>

Add it in your header.php where you want the search icon to appear:

<?php get_template_part( 'template-parts/header/search-toggle' ); ?>

For this template to fully work, add this JavaScript file later:

assets/js/header-search.js

And enqueue it from your RX Theme inc/core/enqueue.php or functions.php. The PHP file above is ready for advanced styling and future live AJAX search.

Leave a Reply

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