__( 'Primary Navigation', 'wp-bootstrap' ), 'footer' => __( 'Footer Navigation', 'wp-bootstrap' ), ) ); } endif; add_action( 'after_setup_theme', 'wp_bootstrap_setup' ); /** * Register widget areas. * * @since 1.0.0 */ if ( ! function_exists( 'wp_bootstrap_register_sidebars' ) ) : function wp_bootstrap_register_sidebars() { register_sidebar( array( 'name' => __( 'Sidebar', 'wp-bootstrap' ), 'id' => 'primary-sidebar', 'description' => __( 'Add widgets here to appear in the sidebar.', 'wp-bootstrap' ), 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '', ) ); } endif; add_action( 'widgets_init', 'wp_bootstrap_register_sidebars' ); /** * Enqueue theme scripts and styles. */ if ( ! function_exists( 'wp_bootstrap_enqueue_scripts' ) ) : function wp_bootstrap_enqueue_scripts() { $theme_version = wp_get_theme()->get( 'Version' ); $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; // Enqueue the compiled Bootstrap + custom CSS. wp_enqueue_style( 'wp-bootstrap-style', get_template_directory_uri() . '/assets/css/style' . $suffix . '.css', array(), $theme_version ); // Enqueue Bootstrap JS bundle (includes Popper). wp_enqueue_script( 'wp-bootstrap-js', get_template_directory_uri() . '/assets/js/bootstrap.bundle.min.js', array(), $theme_version, true ); // Enqueue dark mode toggle script. wp_enqueue_script( 'wp-bootstrap-dark-mode', get_template_directory_uri() . '/assets/js/dark-mode.js', array(), $theme_version, array( 'strategy' => 'defer', 'in_footer' => false, ) ); // Inline script to prevent flash of wrong theme. wp_add_inline_script( 'wp-bootstrap-dark-mode', '(function(){var t=localStorage.getItem("wp-bootstrap-theme")||(window.matchMedia("(prefers-color-scheme:dark)").matches?"dark":"light");document.documentElement.setAttribute("data-bs-theme",t)})();', 'before' ); } endif; add_action( 'wp_enqueue_scripts', 'wp_bootstrap_enqueue_scripts' ); /** * Preload critical fonts for performance. * * @since 0.3.0 */ if ( ! function_exists( 'wp_bootstrap_preload_fonts' ) ) : function wp_bootstrap_preload_fonts() { $fonts = array( 'inter/InterVariable.woff2', 'lora/Lora-VariableFont.woff2', ); $base = get_template_directory_uri() . '/assets/fonts/'; foreach ( $fonts as $font ) { printf( '' . "\n", esc_url( $base . $font ) ); } } endif; add_action( 'wp_head', 'wp_bootstrap_preload_fonts', 1 ); /** * Enqueue RTL stylesheet for right-to-left languages. * * @since 0.3.0 */ if ( ! function_exists( 'wp_bootstrap_rtl_styles' ) ) : function wp_bootstrap_rtl_styles() { if ( ! is_rtl() ) { return; } $theme_version = wp_get_theme()->get( 'Version' ); wp_enqueue_style( 'wp-bootstrap-rtl', get_template_directory_uri() . '/assets/css/rtl.css', array( 'wp-bootstrap-style' ), $theme_version ); } endif; add_action( 'wp_enqueue_scripts', 'wp_bootstrap_rtl_styles', 20 ); /** * Bridge WordPress style variation colors to Bootstrap CSS custom properties. * * Reads the active color palette (theme.json + variation + user overrides) * and outputs inline CSS for both light and dark modes so the dark-mode toggle * switches between two variation-aware color schemes. * * Theme colors (primary–info) go into :root and apply in both modes. * Surface colors (body-bg, tertiary-bg, etc.) are computed separately for * [data-bs-theme=light] and [data-bs-theme=dark]. * * For light palettes: light mode uses base/contrast; dark mode uses dark/light slugs. * For dark palettes: dark mode uses base/contrast; light mode swaps them. * * @since 0.3.2 */ if ( ! function_exists( 'wp_bootstrap_variation_colors' ) ) : function wp_bootstrap_variation_colors() { $transient_key = 'wp_bootstrap_variation_css_' . md5( get_stylesheet() ); $cached_css = get_transient( $transient_key ); if ( false !== $cached_css ) { // '' means default palette (no inline CSS needed); non-empty string is the computed CSS. if ( '' !== $cached_css ) { wp_add_inline_style( 'wp-bootstrap-style', $cached_css ); } return; } // Read the theme origin palette — this contains the base theme.json // colors merged with the active style variation (if any). $theme_palette = wp_get_global_settings( array( 'color', 'palette', 'theme' ) ); $colors = array(); if ( ! empty( $theme_palette ) && is_array( $theme_palette ) ) { foreach ( $theme_palette as $entry ) { if ( ! empty( $entry['slug'] ) && ! empty( $entry['color'] ) ) { $colors[ $entry['slug'] ] = $entry['color']; } } } // Compare against base theme.json defaults to detect an active variation. // WordPress puts variation colors in the 'theme' origin, not 'custom'. $base_defaults = array( 'base' => '#ffffff', 'contrast' => '#212529', 'primary' => '#0d6efd', ); $is_default = true; foreach ( $base_defaults as $slug => $default_color ) { if ( ! empty( $colors[ $slug ] ) && strtolower( $colors[ $slug ] ) !== $default_color ) { $is_default = false; break; } } // No variation active — let Bootstrap's compiled CSS handle both modes. if ( $is_default ) { set_transient( $transient_key, '', DAY_IN_SECONDS ); return; } if ( empty( $colors['base'] ) || empty( $colors['contrast'] ) ) { set_transient( $transient_key, '', DAY_IN_SECONDS ); return; } // Theme colors apply in both modes via :root. $theme_slugs = array( 'primary' => '--bs-primary', 'secondary' => '--bs-secondary', 'success' => '--bs-success', 'danger' => '--bs-danger', 'warning' => '--bs-warning', 'info' => '--bs-info', ); $root_css = ''; foreach ( $theme_slugs as $slug => $var ) { if ( ! empty( $colors[ $slug ] ) ) { $hex = esc_attr( $colors[ $slug ] ); $rgb = wp_bootstrap_hex_to_rgb( $colors[ $slug ] ); $root_css .= "{$var}:{$hex};"; if ( $rgb ) { $root_css .= "{$var}-rgb:{$rgb};"; } } } // Link colors from primary (both modes). if ( ! empty( $colors['primary'] ) ) { $primary_rgb = wp_bootstrap_hex_to_rgb( $colors['primary'] ); $root_css .= '--bs-link-color:' . esc_attr( $colors['primary'] ) . ';'; $root_css .= '--bs-link-color-rgb:' . $primary_rgb . ';'; $root_css .= '--bs-link-hover-color:' . esc_attr( $colors['primary'] ) . ';'; $root_css .= '--bs-link-hover-color-rgb:' . $primary_rgb . ';'; } // Determine if this is a dark palette (base luminance < contrast luminance). $is_dark = wp_bootstrap_relative_luminance( $colors['base'] ) < wp_bootstrap_relative_luminance( $colors['contrast'] ); // Resolve light-mode and dark-mode base colors. if ( $is_dark ) { // Dark palette: dark mode is native, light mode swaps base↔contrast. $light_bg = $colors['contrast']; $light_fg = $colors['base']; $dark_bg = $colors['base']; $dark_fg = $colors['contrast']; } else { // Light palette: light mode is native, dark mode uses dark/light slugs. $light_bg = $colors['base']; $light_fg = $colors['contrast']; $dark_bg = $colors['dark'] ?? '#212529'; $dark_fg = $colors['light'] ?? '#f8f9fa'; } // Also set light/dark slug variables for utilities like bg-light, bg-dark. if ( ! empty( $colors['light'] ) ) { $root_css .= '--bs-light:' . esc_attr( $colors['light'] ) . ';'; $root_css .= '--bs-light-rgb:' . wp_bootstrap_hex_to_rgb( $colors['light'] ) . ';'; } if ( ! empty( $colors['dark'] ) ) { $root_css .= '--bs-dark:' . esc_attr( $colors['dark'] ) . ';'; $root_css .= '--bs-dark-rgb:' . wp_bootstrap_hex_to_rgb( $colors['dark'] ) . ';'; } // Build surface CSS for a given bg/fg pair. $light_css = wp_bootstrap_build_surface_css( $light_bg, $light_fg, false ); $dark_css = wp_bootstrap_build_surface_css( $dark_bg, $dark_fg, true ); $css = ':root{' . $root_css . '}' . '[data-bs-theme=light]{' . $light_css . '}' . '[data-bs-theme=dark]{' . $dark_css . '}'; // Cache for 24 hours; invalidated on theme switch or global-styles save. set_transient( $transient_key, $css, DAY_IN_SECONDS ); // Attach after the compiled stylesheet so variation values override // Bootstrap's hardcoded dark-mode defaults via source order. wp_add_inline_style( 'wp-bootstrap-style', $css ); } endif; add_action( 'wp_enqueue_scripts', 'wp_bootstrap_variation_colors', 30 ); /** * Invalidate the color variation CSS transient when global styles or theme change. */ add_action( 'switch_theme', function () { delete_transient( 'wp_bootstrap_variation_css_' . md5( get_stylesheet() ) ); } ); add_action( 'save_post_wp_global_styles', function () { delete_transient( 'wp_bootstrap_variation_css_' . md5( get_stylesheet() ) ); } ); /** * Build Bootstrap surface CSS variables for a given background/foreground pair. * * Computes body-bg, body-color, tertiary-bg, secondary-bg, secondary-color, * emphasis-color, and border-color — mirroring how Bootstrap derives them. * * @since 0.3.2 * * @param string $bg Background hex color. * @param string $fg Foreground (text) hex color. * @param bool $is_dark Whether this is for dark mode. * @return string CSS declarations (no selector). */ if ( ! function_exists( 'wp_bootstrap_build_surface_css' ) ) : function wp_bootstrap_build_surface_css( $bg, $fg, $is_dark ) { $bg_rgb = wp_bootstrap_hex_to_rgb( $bg ); $fg_rgb = wp_bootstrap_hex_to_rgb( $fg ); $css = '--bs-body-bg:' . esc_attr( $bg ) . ';'; $css .= '--bs-body-bg-rgb:' . $bg_rgb . ';'; $css .= '--bs-body-color:' . esc_attr( $fg ) . ';'; $css .= '--bs-body-color-rgb:' . $fg_rgb . ';'; if ( $is_dark ) { $secondary_bg = wp_bootstrap_mix_hex( $fg, $bg, 0.16 ); $tertiary_bg = wp_bootstrap_mix_hex( $fg, $bg, 0.08 ); $border_color = wp_bootstrap_mix_hex( $fg, $bg, 0.24 ); $emphasis = '#FFFFFF'; } else { $secondary_bg = wp_bootstrap_mix_hex( $fg, $bg, 0.08 ); $tertiary_bg = wp_bootstrap_mix_hex( $fg, $bg, 0.04 ); $border_color = wp_bootstrap_mix_hex( $fg, $bg, 0.16 ); $emphasis = '#000000'; } $css .= '--bs-secondary-color:rgba(' . $fg_rgb . ',0.75);'; $css .= '--bs-secondary-bg:' . $secondary_bg . ';'; $css .= '--bs-secondary-bg-rgb:' . wp_bootstrap_hex_to_rgb( $secondary_bg ) . ';'; $css .= '--bs-tertiary-color:rgba(' . $fg_rgb . ',0.5);'; $css .= '--bs-tertiary-bg:' . $tertiary_bg . ';'; $css .= '--bs-tertiary-bg-rgb:' . wp_bootstrap_hex_to_rgb( $tertiary_bg ) . ';'; $css .= '--bs-emphasis-color:' . $emphasis . ';'; $css .= '--bs-emphasis-color-rgb:' . wp_bootstrap_hex_to_rgb( $emphasis ) . ';'; $css .= '--bs-border-color:' . $border_color . ';'; return $css; } endif; /** * Convert a hex color string to an RGB triplet string. * * @since 0.3.2 * * @param string $hex Hex color (e.g. "#0d6efd" or "0d6efd"). * @return string RGB triplet (e.g. "13,110,253") or empty string on failure. */ if ( ! function_exists( 'wp_bootstrap_hex_to_rgb' ) ) : function wp_bootstrap_hex_to_rgb( $hex ) { $hex = ltrim( $hex, '#' ); if ( strlen( $hex ) === 3 ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } if ( strlen( $hex ) !== 6 ) { return ''; } return hexdec( substr( $hex, 0, 2 ) ) . ',' . hexdec( substr( $hex, 2, 2 ) ) . ',' . hexdec( substr( $hex, 4, 2 ) ); } endif; /** * Mix two hex colors by a given weight. * * @since 0.3.2 * * @param string $color1 Hex color to mix in. * @param string $color2 Base hex color. * @param float $weight Weight of color1 (0.0 to 1.0). * @return string Resulting hex color. */ if ( ! function_exists( 'wp_bootstrap_mix_hex' ) ) : function wp_bootstrap_mix_hex( $color1, $color2, $weight ) { $c1 = wp_bootstrap_hex_to_rgb_array( $color1 ); $c2 = wp_bootstrap_hex_to_rgb_array( $color2 ); if ( ! $c1 || ! $c2 ) { return $color2; } $r = (int) round( $c1[0] * $weight + $c2[0] * ( 1 - $weight ) ); $g = (int) round( $c1[1] * $weight + $c2[1] * ( 1 - $weight ) ); $b = (int) round( $c1[2] * $weight + $c2[2] * ( 1 - $weight ) ); return sprintf( '#%02x%02x%02x', max( 0, min( 255, $r ) ), max( 0, min( 255, $g ) ), max( 0, min( 255, $b ) ) ); } endif; /** * Convert a hex color to an array of [r, g, b] integers. * * @since 0.3.2 * * @param string $hex Hex color. * @return array|false Array of [r, g, b] or false on failure. */ if ( ! function_exists( 'wp_bootstrap_hex_to_rgb_array' ) ) : function wp_bootstrap_hex_to_rgb_array( $hex ) { $hex = ltrim( $hex, '#' ); if ( strlen( $hex ) === 3 ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } if ( strlen( $hex ) !== 6 ) { return false; } return array( hexdec( substr( $hex, 0, 2 ) ), hexdec( substr( $hex, 2, 2 ) ), hexdec( substr( $hex, 4, 2 ) ), ); } endif; /** * Compute relative luminance of a hex color (0.0 = black, 1.0 = white). * * @since 0.3.2 * * @param string $hex Hex color. * @return float Relative luminance. */ if ( ! function_exists( 'wp_bootstrap_relative_luminance' ) ) : function wp_bootstrap_relative_luminance( $hex ) { $rgb = wp_bootstrap_hex_to_rgb_array( $hex ); if ( ! $rgb ) { return 0.0; } $channels = array(); foreach ( $rgb as $val ) { $val /= 255; $channels[] = ( $val <= 0.03928 ) ? $val / 12.92 : pow( ( $val + 0.055 ) / 1.055, 2.4 ); } return 0.2126 * $channels[0] + 0.7152 * $channels[1] + 0.0722 * $channels[2]; } endif; /** * Enqueue Bootstrap JS in the block editor for interactive previews. * * @since 0.2.0 */ if ( ! function_exists( 'wp_bootstrap_enqueue_editor_assets' ) ) : function wp_bootstrap_enqueue_editor_assets() { $theme_version = wp_get_theme()->get( 'Version' ); wp_enqueue_script( 'wp-bootstrap-editor-js', get_template_directory_uri() . '/assets/js/bootstrap.bundle.min.js', array(), $theme_version, true ); } endif; add_action( 'enqueue_block_editor_assets', 'wp_bootstrap_enqueue_editor_assets' ); /** * Register custom block categories for Bootstrap components. * * @since 0.2.0 * * @param array $categories Existing block categories. * @param WP_Block_Editor_Context $context Block editor context. * @return array Modified categories. */ if ( ! function_exists( 'wp_bootstrap_block_categories' ) ) : function wp_bootstrap_block_categories( array $categories, $context ): array { $bootstrap_categories = array( array( 'slug' => 'wp-bootstrap-layout', 'title' => __( 'Bootstrap Layout', 'wp-bootstrap' ), 'icon' => 'layout', ), array( 'slug' => 'wp-bootstrap-components', 'title' => __( 'Bootstrap Components', 'wp-bootstrap' ), 'icon' => 'grid-view', ), array( 'slug' => 'wp-bootstrap-navigation', 'title' => __( 'Bootstrap Navigation', 'wp-bootstrap' ), 'icon' => 'menu', ), ); return array_merge( $bootstrap_categories, $categories ); } endif; add_filter( 'block_categories_all', 'wp_bootstrap_block_categories', 10, 2 ); /** * Register block pattern categories. */ if ( ! function_exists( 'wp_bootstrap_pattern_categories' ) ) : function wp_bootstrap_pattern_categories() { register_block_pattern_category( 'wp-bootstrap_page', array( 'label' => __( 'Pages', 'wp-bootstrap' ), 'description' => __( 'A collection of full page layouts.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_hero', array( 'label' => __( 'Hero Sections', 'wp-bootstrap' ), 'description' => __( 'Large hero and banner sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_cta', array( 'label' => __( 'Call to Action', 'wp-bootstrap' ), 'description' => __( 'Call to action sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_features', array( 'label' => __( 'Features', 'wp-bootstrap' ), 'description' => __( 'Feature and service showcase sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_testimonials', array( 'label' => __( 'Testimonials', 'wp-bootstrap' ), 'description' => __( 'Testimonial and review sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_pricing', array( 'label' => __( 'Pricing', 'wp-bootstrap' ), 'description' => __( 'Pricing table sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_contact', array( 'label' => __( 'Contact', 'wp-bootstrap' ), 'description' => __( 'Contact information sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap_text', array( 'label' => __( 'Text & Content', 'wp-bootstrap' ), 'description' => __( 'Text-focused content sections.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap-layout', array( 'label' => __( 'Layout', 'wp-bootstrap' ), 'description' => __( 'Layout building blocks for page structure.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap-components', array( 'label' => __( 'Components', 'wp-bootstrap' ), 'description' => __( 'Reusable Bootstrap component patterns.', 'wp-bootstrap' ), ) ); register_block_pattern_category( 'wp-bootstrap-navigation', array( 'label' => __( 'Navigation', 'wp-bootstrap' ), 'description' => __( 'Navigation and header patterns.', 'wp-bootstrap' ), ) ); } endif; add_action( 'init', 'wp_bootstrap_pattern_categories' ); /** * Register custom block styles for Bootstrap components. * * @since 0.1.0 */ if ( ! function_exists( 'wp_bootstrap_block_styles' ) ) : function wp_bootstrap_block_styles() { // core/list - Checkmark style. register_block_style( 'core/list', array( 'name' => 'checkmark-list', 'label' => __( 'Checkmark', 'wp-bootstrap' ), 'inline_style' => ' ul.is-style-checkmark-list { list-style-type: "\2713"; } ul.is-style-checkmark-list li { padding-inline-start: 1ch; }', ) ); // core/list - Unstyled. register_block_style( 'core/list', array( 'name' => 'list-unstyled', 'label' => __( 'Unstyled', 'wp-bootstrap' ), 'inline_style' => ' ul.is-style-list-unstyled, ol.is-style-list-unstyled { list-style: none; padding-inline-start: 0; }', ) ); // core/group - Card. register_block_style( 'core/group', array( 'name' => 'card', 'label' => __( 'Card', 'wp-bootstrap' ), 'inline_style' => ' .is-style-card { border: 1px solid var(--wp--preset--color--light, #dee2e6); border-radius: 0.375rem; padding: var(--wp--preset--spacing--40); background: var(--wp--preset--color--base); }', ) ); // core/group - Card with Shadow. register_block_style( 'core/group', array( 'name' => 'card-shadow', 'label' => __( 'Card with Shadow', 'wp-bootstrap' ), 'inline_style' => ' .is-style-card-shadow { border: 1px solid var(--wp--preset--color--light, #dee2e6); border-radius: 0.375rem; padding: var(--wp--preset--spacing--40); background: var(--wp--preset--color--base); box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); }', ) ); // core/group - Alert Info. register_block_style( 'core/group', array( 'name' => 'alert-info', 'label' => __( 'Alert - Info', 'wp-bootstrap' ), 'inline_style' => ' .is-style-alert-info { background-color: #cff4fc; border: 1px solid #9eeaf9; color: #055160; border-radius: 0.375rem; padding: var(--wp--preset--spacing--30); }', ) ); // core/group - Alert Success. register_block_style( 'core/group', array( 'name' => 'alert-success', 'label' => __( 'Alert - Success', 'wp-bootstrap' ), 'inline_style' => ' .is-style-alert-success { background-color: #d1e7dd; border: 1px solid #a3cfbb; color: #0a3622; border-radius: 0.375rem; padding: var(--wp--preset--spacing--30); }', ) ); // core/group - Alert Warning. register_block_style( 'core/group', array( 'name' => 'alert-warning', 'label' => __( 'Alert - Warning', 'wp-bootstrap' ), 'inline_style' => ' .is-style-alert-warning { background-color: #fff3cd; border: 1px solid #ffe69c; color: #664d03; border-radius: 0.375rem; padding: var(--wp--preset--spacing--30); }', ) ); // core/group - Alert Danger. register_block_style( 'core/group', array( 'name' => 'alert-danger', 'label' => __( 'Alert - Danger', 'wp-bootstrap' ), 'inline_style' => ' .is-style-alert-danger { background-color: #f8d7da; border: 1px solid #f1aeb5; color: #58151c; border-radius: 0.375rem; padding: var(--wp--preset--spacing--30); }', ) ); // core/table - Striped Rows. register_block_style( 'core/table', array( 'name' => 'table-striped', 'label' => __( 'Striped Rows', 'wp-bootstrap' ), 'inline_style' => ' .is-style-table-striped tbody tr:nth-of-type(odd) > * { background-color: rgba(0, 0, 0, 0.05); }', ) ); // core/table - Hover Rows. register_block_style( 'core/table', array( 'name' => 'table-hover', 'label' => __( 'Hover Rows', 'wp-bootstrap' ), 'inline_style' => ' .is-style-table-hover tbody tr:hover > * { background-color: rgba(0, 0, 0, 0.075); }', ) ); // core/table - Bordered. register_block_style( 'core/table', array( 'name' => 'table-bordered', 'label' => __( 'Bordered', 'wp-bootstrap' ), 'inline_style' => ' .is-style-table-bordered, .is-style-table-bordered td, .is-style-table-bordered th { border: 1px solid var(--wp--preset--color--light, #dee2e6); }', ) ); // core/quote - Accent Border. register_block_style( 'core/quote', array( 'name' => 'blockquote-accent', 'label' => __( 'Accent Border', 'wp-bootstrap' ), 'inline_style' => ' .is-style-blockquote-accent { border-inline-start: 4px solid var(--wp--preset--color--primary); background: var(--wp--preset--color--light); padding: var(--wp--preset--spacing--30); border-start-start-radius: 0; border-start-end-radius: 0.375rem; border-end-end-radius: 0.375rem; border-end-start-radius: 0; }', ) ); // core/image - Shadow. register_block_style( 'core/image', array( 'name' => 'shadow', 'label' => __( 'Shadow', 'wp-bootstrap' ), 'inline_style' => ' .is-style-shadow img { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); }', ) ); // core/image - Large Rounded. register_block_style( 'core/image', array( 'name' => 'rounded-lg', 'label' => __( 'Large Rounded', 'wp-bootstrap' ), 'inline_style' => ' .is-style-rounded-lg img { border-radius: 0.75rem; }', ) ); // core/button - Large. register_block_style( 'core/button', array( 'name' => 'btn-lg', 'label' => __( 'Large', 'wp-bootstrap' ), 'inline_style' => ' .is-style-btn-lg .wp-block-button__link { padding: 0.75rem 1.5rem; font-size: 1.25rem; border-radius: 0.5rem; }', ) ); // core/button - Small. register_block_style( 'core/button', array( 'name' => 'btn-sm', 'label' => __( 'Small', 'wp-bootstrap' ), 'inline_style' => ' .is-style-btn-sm .wp-block-button__link { padding: 0.25rem 0.5rem; font-size: 0.875rem; border-radius: 0.25rem; }', ) ); // core/separator - Wide. register_block_style( 'core/separator', array( 'name' => 'separator-wide', 'label' => __( 'Wide', 'wp-bootstrap' ), 'inline_style' => ' .is-style-separator-wide { max-width: none; }', ) ); } endif; add_action( 'init', 'wp_bootstrap_block_styles' ); /** * Initialize Twig template engine. */ if ( ! function_exists( 'wp_bootstrap_init_twig' ) ) : function wp_bootstrap_init_twig() { if ( class_exists( '\\WPBootstrap\\Twig\\TwigService' ) ) { \WPBootstrap\Twig\TwigService::getInstance(); } } endif; add_action( 'after_setup_theme', 'wp_bootstrap_init_twig' ); /** * Initialize Twig template controller for frontend rendering. * * Hooks into template_redirect to render Bootstrap 5 HTML * via Twig templates instead of FSE block markup on the frontend. * * @since 0.1.1 */ if ( ! function_exists( 'wp_bootstrap_init_templates' ) ) : function wp_bootstrap_init_templates() { if ( class_exists( '\\WPBootstrap\\Template\\TemplateController' ) ) { new \WPBootstrap\Template\TemplateController(); } } endif; add_action( 'after_setup_theme', 'wp_bootstrap_init_templates' ); /** * Customize comment form fields with Bootstrap classes. * * @since 0.1.1 * * @param array $fields Default comment form fields. * @return array Modified fields with Bootstrap classes. */ if ( ! function_exists( 'wp_bootstrap_comment_form_fields' ) ) : function wp_bootstrap_comment_form_fields( array $fields ): array { $commenter = wp_get_current_commenter(); $required = get_option( 'require_name_email' ); $req_attr = $required ? ' required' : ''; $fields['author'] = '
' . '' . '' . '
'; $fields['email'] = '
' . '' . '' . '
'; $fields['url'] = '
' . '' . '' . '
'; if ( isset( $fields['cookies'] ) ) { $fields['cookies'] = '
' . '' . '
'; } return $fields; } endif; add_filter( 'comment_form_default_fields', 'wp_bootstrap_comment_form_fields' );