[ 'class' => true, 'style' => true, 'role' => true, 'aria-label' => true ], 'button' => [ 'type' => true, 'class' => true, 'aria-haspopup' => true, 'aria-expanded' => true ], 'span' => [ 'class' => true, 'style' => true, 'aria-hidden' => true ], 'ul' => [ 'class' => true ], 'li' => [ 'class' => true ], 'a' => [ 'class' => true, 'href' => true, 'title' => true, 'rel' => true, 'target' => true ], 'img' => [ 'src' => true, 'class' => true, 'alt' => true, 'width' => true, 'height' => true, 'srcset' => true, 'sizes' => true, 'loading' => true, 'decoding' => true, 'style' => true ], ]; } public function hooks() { add_shortcode( 'abdiel_language_switcher', [ $this, 'shortcode' ] ); add_action( 'wp_footer', [ $this, 'maybe_render_floating' ] ); add_filter( 'wp_nav_menu_items', [ $this, 'maybe_append_menu_switcher' ], 10, 2 ); add_action( 'wp_enqueue_scripts', [ $this, 'assets' ] ); } public function assets() { wp_enqueue_style( 'abdiel-amm-frontend', ABDIEL_AMM_URL . 'assets/frontend.css', [], ABDIEL_AMM_VERSION ); wp_enqueue_script( 'abdiel-amm-frontend', ABDIEL_AMM_URL . 'assets/frontend.js', [], ABDIEL_AMM_VERSION, true ); } public function shortcode( $atts = [] ) { $atts = shortcode_atts( [ 'show' => 'auto', // auto|all ], $atts, 'abdiel_language_switcher' ); return $this->render( [ 'context' => 'shortcode', 'show' => $atts['show'], ] ); } public function maybe_append_menu_switcher( $items, $args ) { $settings = Settings::get_settings_option(); if ( $settings['switcher_mode'] !== 'menu' ) { return $items; } // Optional: restrict by theme location. if ( ! empty( $settings['menu_location'] ) && isset( $args->theme_location ) ) { if ( $args->theme_location !== $settings['menu_location'] ) { return $items; } } // Optional: restrict by specific menu term ID. if ( ! empty( $settings['menu_term_id'] ) ) { $menu_id = 0; if ( isset( $args->menu ) ) { if ( is_object( $args->menu ) && isset( $args->menu->term_id ) ) { $menu_id = (int) $args->menu->term_id; } if ( is_numeric( $args->menu ) ) { $menu_id = (int) $args->menu; } } if ( $menu_id && (int) $settings['menu_term_id'] !== $menu_id ) { return $items; } } $switcher = $this->render( [ 'context' => 'menu', 'show' => 'auto', ] ); if ( empty( $switcher ) ) { return $items; } $items .= ''; return $items; } public function maybe_render_floating() { $settings = Settings::get_settings_option(); if ( $settings['switcher_mode'] !== 'floating' ) { return; } // Escape late: output is HTML, so we whitelist expected tags/attributes. echo wp_kses( $this->render( [ 'context' => 'floating', 'show' => 'auto', ] ), $this->kses_allowed_html() ); } private function get_lang_manager() { return abdiel_amm_boot()->content; } private function get_languages() { $langs = Settings::get_languages_option(); $items = $langs['items']; uasort( $items, function( $a, $b ) { return (int) $a['order'] <=> (int) $b['order']; } ); $langs['items'] = $items; return $langs; } public function render( $args = [] ) { $settings = Settings::get_settings_option(); $content = $this->get_lang_manager(); $langs = $this->get_languages(); $active = []; foreach ( (array) $langs['items'] as $code => $row ) { if ( ! empty( $row['active'] ) ) { $active[ $code ] = $row; } } if ( count( $active ) <= 1 ) { return ''; } $current_id = get_queried_object_id(); $current_code = $content->get_current_language_code( $current_id ); $map = $content->get_translation_map( $current_id ); // Only show languages that have a linked post/page AND are published. $visible = []; foreach ( $active as $code => $row ) { if ( $args['show'] === 'all' ) { $visible[ $code ] = $row; continue; } if ( empty( $map[ $code ] ) ) { continue; } $pid = absint( $map[ $code ] ); if ( $pid <= 0 ) { continue; } if ( get_post_status( $pid ) !== 'publish' ) { continue; } $visible[ $code ] = $row; } if ( count( $visible ) <= 1 ) { return ''; } // Build inline CSS variables so user-defined colors always take precedence. $style_vars = []; if ( ! empty( $settings['btn_bg'] ) ) { $style_vars[] = '--abdiel-amm-btn-bg:' . $settings['btn_bg']; } if ( ! empty( $settings['btn_text'] ) ) { $style_vars[] = '--abdiel-amm-btn-text:' . $settings['btn_text']; } if ( ! empty( $settings['btn_bg_hover'] ) ) { $style_vars[] = '--abdiel-amm-btn-bg-hover:' . $settings['btn_bg_hover']; } if ( ! empty( $settings['btn_text_hover'] ) ) { $style_vars[] = '--abdiel-amm-btn-text-hover:' . $settings['btn_text_hover']; } $style_attr = ! empty( $style_vars ) ? ' style="' . esc_attr( implode( ';', $style_vars ) ) . '"' : ''; $classes = [ 'abdiel-amm-switcher', 'abdiel-amm-context-' . sanitize_html_class( $args['context'] ) ]; if ( $args['context'] === 'floating' ) { $classes[] = 'abdiel-amm-pos-' . sanitize_html_class( $settings['floating_position'] ); } ob_start(); ?>
role="navigation" aria-label="">
content->get_default_language_code(); $url = $target_post_id ? get_permalink( $target_post_id ) : home_url( '/' ); if ( $mode === 'query' ) { if ( $default && $lang_code === $default ) { return $url; } return add_query_arg( 'lang', $lang_code, $url ); } if ( $mode === 'prefix' ) { if ( $default && $lang_code === $default ) { return $url; } $parsed = wp_parse_url( $url ); $host = ( isset( $parsed['scheme'] ) ? $parsed['scheme'] . '://' : '' ) . ( $parsed['host'] ?? '' ); if ( isset( $parsed['port'] ) ) { $host .= ':' . $parsed['port']; } $path = $parsed['path'] ?? '/'; $path = '/' . ltrim( $path, '/' ); // remove existing lang prefix $path = preg_replace( '#^/([a-z]{2})(/|$)#i', '/', $path, 1 ); $path = '/' . $lang_code . rtrim( $path, '/' ); if ( substr( $path, -1 ) !== '/' ) { $path .= '/'; } return $host . $path; } return $url; } }