Created
September 11, 2025 10:12
-
-
Save JusTruetice/fa919e87494e74f4e94bc8e6b6ffc443 to your computer and use it in GitHub Desktop.
Language switcher
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if (!defined('ABSPATH')) exit; | |
| add_shortcode('custom_lang_switcher', function () { | |
| ob_start(); | |
| // 1) Determine current language (WPML-aware) | |
| $current_lang = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : apply_filters('wpml_current_language', null); | |
| // 2) Get a robust "current URL" for many contexts | |
| if (is_singular()) { | |
| $current_url = get_permalink(); | |
| } elseif (is_category() || is_tag() || is_tax()) { | |
| $term = get_queried_object(); | |
| $current_url = ($term && !is_wp_error($term)) ? get_term_link($term) : home_url(add_query_arg(null, null)); | |
| } elseif (is_post_type_archive()) { | |
| $current_url = get_post_type_archive_link(get_post_type()) ?: home_url(add_query_arg(null, null)); | |
| } else { | |
| $current_url = home_url(add_query_arg(null, null)); | |
| } | |
| // 3) Try to get WPML translated URLs; otherwise fallback (naive) | |
| if ( defined('ICL_SITEPRESS_VERSION') || function_exists('icl_object_id') ) { | |
| $ka_url = apply_filters('wpml_permalink', $current_url, 'ka'); | |
| $en_url = apply_filters('wpml_permalink', $current_url, 'en'); | |
| } else { | |
| // fallback: naive add/remove /en/ prefix | |
| $parsed = wp_parse_url($current_url); | |
| $path = !empty($parsed['path']) ? $parsed['path'] : '/'; | |
| if (strpos($path, '/en/') === 0 || rtrim($path, '/') === '/en') { | |
| $en_url = $current_url; | |
| $ka_url = home_url( preg_replace('#^/en#', '', $path) ?: '/' ); | |
| } else { | |
| $ka_url = $current_url; | |
| $en_url = home_url( '/en' . $path ); | |
| } | |
| } | |
| // Output container with data-attributes (JS გამოიყენებს) | |
| ?> | |
| <div class="lsw" | |
| data-current="<?php echo esc_attr( $current_lang ); ?>" | |
| data-ka-url="<?php echo esc_attr( $ka_url ); ?>" | |
| data-en-url="<?php echo esc_attr( $en_url ); ?>"></div> | |
| <style> | |
| /* (ჩაწერე აქ შენი არსებული CSS — იმავეით როგორც ადრე) */ | |
| .lsw { display: inline-block; } | |
| .lsw-wrap { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| .lsw-flag { width: 26px; height: auto; display: block; } | |
| .lsw-toggle { | |
| position: relative; | |
| width: 56px; | |
| height: 30px; | |
| padding: 0; | |
| border: 0; | |
| background: transparent; | |
| cursor: pointer; | |
| outline: none; | |
| border-radius: 999px; | |
| } | |
| .lsw-toggle:hover .lsw-track { | |
| background: #FFBD14 !important; | |
| box-shadow: inset 0 0 0 2px rgba(0,0,0,.6); | |
| } | |
| .lsw-toggle:focus-visible { | |
| outline: none; | |
| box-shadow: 0 0 0 2px #111 inset; | |
| border-radius: 999px; | |
| } | |
| .lsw-track { | |
| position: absolute; | |
| inset: 0; | |
| background: #FFBD14; | |
| border-radius: 999px; | |
| box-shadow: inset 0 0 0 2px rgba(0,0,0,.6); | |
| } | |
| .lsw-thumb { | |
| position: absolute; | |
| top: 4px; | |
| left: 4px; | |
| width: 22px; | |
| height: 22px; | |
| background: #111; | |
| border-radius: 50%; | |
| transition: left .25s ease; | |
| } | |
| .lsw-wrap.is-en .lsw-thumb { left: 30px; } | |
| @media (max-width: 420px){ | |
| .lsw-flag { width: 22px; } | |
| .lsw-toggle { width: 50px; height: 22px; } | |
| .lsw-thumb { width: 14px; height: 14px; top: 4px; left: 4px; } | |
| .lsw-wrap.is-en .lsw-thumb { left: 26px; } | |
| .lsw-wrap { gap: 2px !important; } | |
| } | |
| </style> | |
| <script> | |
| (function () { | |
| const CONFIG = { | |
| flags: { | |
| ka: 'https://upload.wikimedia.org/wikipedia/commons/0/0f/Flag_of_Georgia.svg', | |
| en: 'https://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_United_Kingdom_%283-5%29.svg' | |
| } | |
| }; | |
| function ensureAbsolute(url) { | |
| if (!url) return url; | |
| try { | |
| const u = new URL(url); | |
| return u.href; | |
| } catch (e) { | |
| // relative path -> make absolute | |
| if (url.charAt(0) !== '/') url = '/' + url; | |
| return location.origin + url; | |
| } | |
| } | |
| function render(container, currentLang, targetUrl) { | |
| const wrap = document.createElement('div'); | |
| wrap.className = 'lsw-wrap ' + (currentLang === 'en' ? 'is-en' : 'is-ka'); | |
| wrap.setAttribute('role', 'group'); | |
| wrap.setAttribute('aria-label', 'Language switcher'); | |
| const flag = document.createElement('img'); | |
| flag.className = 'lsw-flag'; | |
| flag.alt = currentLang === 'en' ? 'English' : 'ქართული'; | |
| flag.src = CONFIG.flags[currentLang] || CONFIG.flags.ka; | |
| flag.referrerPolicy = 'no-referrer'; | |
| flag.decoding = 'async'; | |
| flag.loading = 'lazy'; | |
| flag.onerror = function(){ this.style.display='none'; }; | |
| const btn = document.createElement('button'); | |
| btn.className = 'lsw-toggle'; | |
| btn.type = 'button'; | |
| btn.setAttribute('role', 'switch'); | |
| btn.setAttribute('aria-checked', currentLang === 'en' ? 'true' : 'false'); | |
| btn.setAttribute('aria-label', 'Switch language'); | |
| const track = document.createElement('span'); | |
| track.className = 'lsw-track'; | |
| const thumb = document.createElement('span'); | |
| thumb.className = 'lsw-thumb'; | |
| btn.appendChild(track); | |
| btn.appendChild(thumb); | |
| btn.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const abs = ensureAbsolute(targetUrl || '/'); | |
| window.location.href = abs; | |
| }); | |
| wrap.appendChild(flag); | |
| wrap.appendChild(btn); | |
| container.innerHTML = ''; | |
| container.appendChild(wrap); | |
| } | |
| function initOne(container) { | |
| const dataKa = (container.getAttribute('data-ka-url') || '').trim(); | |
| const dataEn = (container.getAttribute('data-en-url') || '').trim(); | |
| let current = (container.getAttribute('data-current') || '').toLowerCase(); | |
| if (current !== 'ka' && current !== 'en') { | |
| const htmlLang = (document.documentElement.lang || '').toLowerCase(); | |
| if (htmlLang.startsWith('ka')) current = 'ka'; | |
| else if (htmlLang.startsWith('en')) current = 'en'; | |
| else current = location.pathname.toLowerCase().startsWith('/en') ? 'en' : 'ka'; | |
| } | |
| let target = ''; | |
| if (dataKa && dataEn) { | |
| target = (current === 'ka') ? dataEn : dataKa; | |
| } else { | |
| // fallback: try transform path by adding/removing /en prefix | |
| const here = location.pathname + location.search + location.hash; | |
| if (current === 'ka') { | |
| target = '/en' + (here === '/' ? '/' : here); | |
| } else { | |
| target = here.replace(/^\/en/, '') || '/'; | |
| } | |
| } | |
| render(container, current, target); | |
| } | |
| function init() { | |
| document.querySelectorAll('.lsw').forEach(el => initOne(el)); | |
| } | |
| if (document.readyState !== 'loading') init(); | |
| else document.addEventListener('DOMContentLoaded', init); | |
| })(); | |
| </script> | |
| <?php | |
| return ob_get_clean(); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment