Skip to content

Wszystko o WordPressie, tworzeniu stron — i nie tylko

🔄 Przełącznik języków WPML: same kody ISO zamiast flag i nazw

🔄 Przełącznik języków WPML: same kody ISO zamiast flag i nazw

Flagi państw w menu witryny to wątpliwe rozwiązanie. W fladze Wielkiej Brytanii połowa kraju rozpozna swoją, a druga połowa nie. Flaga USA zamiast angielskiego? Dla Kanadyjczyków i Australijczyków chybiony wybór. A pełne nazwy języków, «Русский», «Українська», «English», zajmują pół menu na ekranie mobilnym.

Kompaktowy format RU | UK | EN rozwiązuje oba problemy: czyta się natychmiast, miejsca prawie nie zajmuje i nie jest powiązany z geografią. To standardowe kody ISO języków, dwuliterowe, zrozumiałe bez tłumaczenia w każdym kraju.

Poniżej dwa sposoby na zastąpienie standardowego przełącznika WPML kodami ISO. Pierwszy, przez filtr pozycji menu (prosty fragment kodu wstawiony do functions.php). Drugi, shortcode, który wyświetla przełącznik w dowolnym miejscu witryny.

💡 Szybki przegląd:

  • Sposób 1: zamiana pozycji menu nawigacyjnego przez hook wp_nav_menu_items, dla wbudowanego przełącznika w nagłówku
  • Sposób 2: shortcode [wpml_custom_lang_ISO], wstawka w dowolne miejsce motywu (widżet, stopka, menu mobilne)
  • CSS: stylizacja separatora |, ukrywanie aktywnego języka, responsywność

Jak wygląda rezultat

Po dodaniu kodu przełącznik języków wyświetla się w formacie RU | UK | EN, krótko i schludnie. Aktywny język jest wyróżniany lub ukrywany (ustawia się to przez CSS), pozostałe języki są klikalne i prowadzą do odpowiedniej wersji strony.

Перемикач мов WPML у ISO-форматі RU | EN

Kod wykorzystuje standardową funkcję WPML icl_get_languages(), która zwraca tablicę aktywnych języków witryny ze wszystkimi danymi: URL tłumaczenia, kod języka, flaga aktywności. Żadnych zależności zewnętrznych, tylko API samego WPML.

Sposób 1: zamiana pozycji menu przez wp_nav_menu_items

Ta metoda przechwytuje wyjście menu nawigacyjnego WordPress i zamienia standardowe pozycje-języki na kompaktowe kody ISO z separatorem.

Gdzie wstawiać: functions.php motywu potomnego lub przez wtyczkę Code Snippets (bezpieczniej, nie zniknie przy aktualizacji motywu).

Przed dodaniem zrób pełny backup witryny. Kod nie jest destrukcyjny i tylko dodaje wyjście, ale backup to dobra praktyka przy każdej edycji functions.php.

1/**
2 * Zamienia pozycje językowe WPML w menu na kody ISO.
3 * theme_location należy ustawić pod swoje menu.
4 */
5add_filter( 'wp_nav_menu_items', 'wpml_iso_menu_items', 10, 2 );
6
7function wpml_iso_menu_items( $items, $args ) {
8 // Sprawdzamy, czy funkcja WPML jest dostępna
9 if ( ! function_exists( 'icl_get_languages' ) ) {
10 return $items;
11 }
12
13 $languages = icl_get_languages( 'skip_missing=0&orderby=code' );
14
15 // Podaj tutaj theme_location swojego menu (na przykład 'primary', 'top')
16 if ( empty( $languages ) || $args->theme_location !== 'primary' ) {
17 return $items;
18 }
19
20 $lang_links = '';
21
22 foreach ( $languages as $lang ) {
23 $code = strtoupper( $lang['language_code'] );
24
25 if ( $lang['active'] ) {
26 $lang_links .= '<span class="wpml-lang-item active">' . $code . '</span>';
27 } else {
28 $lang_links .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>';
29 }
30
31 $lang_links .= '<span class="wpml-lang-sep">|</span>';
32 }
33
34 // Usuwamy ostatni separator
35 $lang_links = rtrim( $lang_links, '<span class="wpml-lang-sep">|</span>' );
36
37 return $items . '<li class="menu-item wpml-iso-switcher">' . $lang_links . '</li>';
38}

Co się tutaj dzieje. Hook wp_nav_menu_items uruchamia się podczas tworzenia każdego menu w witrynie. Warunek $args->theme_location !== 'primary' ogranicza zamianę tylko do potrzebnego menu, zamień 'primary' na theme_location swojego menu (sprawdź w wp_nav_menu() w szablonie lub w panelu administracyjnym: Wygląd → Menu → lokalizacje).

Funkcja icl_get_languages('skip_missing=0') pobiera wszystkie opublikowane języki. skip_missing=0 oznacza „pokaż język, nawet jeśli bieżąca strona nie ma tłumaczenia", użytkownik trafi na stronę główną tego języka zamiast na 404.

strtoupper() zamienia kody na wielkie litery: ruRU. Jeśli potrzebne są małe litery, usuń to wywołanie.

Sposób 2: shortcode [wpml_custom_lang_ISO]

Shortcode jest bardziej uniwersalny: wstawiaj [wpml_custom_lang_ISO] w dowolne miejsce, widżet, tekst strony, szablon PHP przez do_shortcode(). Nadaje się do menu mobilnego, stopki lub bloku pod nagłówkiem.

Gdzie wstawiać: functions.php (ten sam plik, co dla sposobu 1). Można trzymać oba sposoby jednocześnie, konfliktu nie będzie.

1/**
2 * Shortkod [wpml_custom_lang_ISO] — wyświetla przełącznik języków w formacie ISO.
3 * Wstawianie: [wpml_custom_lang_ISO] w tekście lub <?php echo do_shortcode('[wpml_custom_lang_ISO]'); ?> w szablonie.
4 */
5add_shortcode( 'wpml_custom_lang_ISO', 'wpml_shortcode_lang_iso' );
6
7function wpml_shortcode_lang_iso() {
8 if ( ! function_exists( 'icl_get_languages' ) ) {
9 return '';
10 }
11
12 $languages = icl_get_languages( 'skip_missing=0&orderby=code&order=desc' );
13 $output = '';
14
15 if ( empty( $languages ) ) {
16 return '';
17 }
18
19 foreach ( $languages as $lang ) {
20 $code = strtoupper( $lang['language_code'] );
21
22 if ( $lang['active'] ) {
23 $output .= '<span class="wpml-lang-item active">' . $code . '</span>';
24 } else {
25 $output .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>';
26 }
27
28 $output .= '<span class="wpml-lang-sep">|</span>';
29 }
30
31 // Usuwamy ostatni separator
32 $output = rtrim( $output, '<span class="wpml-lang-sep">|</span>' );
33
34 return '<div class="wpml-iso-lang-switcher">' . $output . '</div>';
35}

Różnica w stosunku do sposobu 1: shortcode zwraca ciąg HTML, a nie uzupełnia pozycji menu. Dlatego można go umieścić wszędzie, nie jest powiązany z theme_location. Parametr order=desc zmienia kolejność języków na odwrotną (opcjonalnie, usuń jeśli niepotrzebny).

Jak znaleźć theme_location swojego menu

Jeśli używasz Sposobu 1, musisz dokładnie wskazać argument theme_location. Otwórz plik szablonu, w którym wywoływane jest menu (zwykle header.php), i znajdź linię postaci:

1wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 'primary-menu' ) );

Wartość w pojedynczych cudzysłowach, na przykład 'primary', to właśnie twój theme_location. Popularne nazwy: primary dla menu głównego, top dla panelu górnego. Podstaw swoją wartość do warunku $args->theme_location !== 'primary' z kodu powyżej.

Inny sposób: w panelu administracyjnym otwórz Wygląd → Menu → zakładka «Lokalizacje», tam wymienione są wszystkie zarejestrowane theme_location motywu.

Style CSS dla przełącznika

Minimalny zestaw stylów, aby przełącznik wyglądał schludnie. Dodaj w Wygląd → Personalizuj → Dodatkowy CSS lub w pliku style.css motywu potomnego.

1/* Kontener przełącznika */
2.wpml-iso-lang-switcher,
3.wpml-iso-switcher {
4 display: flex;
5 align-items: center;
6 gap: 0;
7 font-family: 'Oswald', sans-serif;
8 font-size: 16px;
9 font-weight: 600;
10 text-transform: uppercase;
11}
12
13/* Linki i aktywny język */
14.wpml-lang-item {
15 color: #33445d;
16 text-decoration: none;
17 padding: 4px 2px;
18 transition: color 0.2s;
19}
20
21a.wpml-lang-item:hover {
22 color: #0073aa;
23}
24
25.wpml-lang-item.active {
26 color: #999;
27 cursor: default;
28}
29
30/* Separator */
31.wpml-lang-sep {
32 margin: 0 6px;
33 color: #ccc;
34 font-weight: 400;
35}
36
37/* Ukryj aktywny język i następujący po nim separator */
38.wpml-lang-item.active,
39.wpml-lang-item.active + .wpml-lang-sep {
40 display: none;
41}
42
43/* Adaptacja mobilna */
44@media screen and (max-width: 768px) {
45 .wpml-iso-lang-switcher,
46 .wpml-iso-switcher {
47 font-size: 18px;
48 padding: 8px 0;
49 }
50}

Kluczowy trik: selektor .wpml-lang-item.active + .wpml-lang-sep ukrywa separator zaraz za aktywnym językiem. Jeśli aktywny język jest ukryty, to i separator za nim znika, nie zostaje wiszący znak | na początku lub na końcu wiersza.

Czcionka Oswald podana jest jako przykład. Zamień na czcionkę swojego motywu lub usuń linię font-family całkowicie, aby dziedziczyć z motywu. Po dodaniu CSS sprawdź przełącznik w rozdzielczości mobilnej za pomocą narzędzi deweloperskich (F12 → Toggle device toolbar).

⁉️🤔 Najczęściej zadawane pytania

Czy można wyświetlać nazwy języków zamiast kodów ISO?

> Tak, zamień $lang['language_code'] na $lang['native_name'] w obu wariantach kodu. Otrzymasz «Русский | English | Українська». Alternatywnie, $lang['translated_name'] wyświetla nazwy w języku bieżącej strony: jeśli odwiedzający jest na wersji angielskiej, zobaczy «Russian | English | Ukrainian». Wszystkie dostępne klucze tablicy są wymienione w oficjalnej dokumentacji WPML dotyczącej funkcji icl_get_languages().

Jak usunąć język, który nie ma tłumaczenia bieżącej strony?

Zmień w wywołaniu icl_get_languages() parametr skip_missing=0 na skip_missing=1. Języki bez tłumaczenia po prostu znikną z przełącznika, zamiast nich nie będzie zepsutego linku. Wygodne dla witryn, gdzie nie wszystkie strony są przetłumaczone: menu pozostanie czyste, bez linków prowadzących na stronę główną lub na 404.

Przełącznik się nie pojawia, w czym problem?

Sprawdź trzy rzeczy. Pierwsze: czy wtyczka WPML jest aktywna i czy dodane są języki w WPML → Languages. Drugie: czy theme_location w kodzie zgadza się z rzeczywistym menu (Sposób 1). Trzecie: czy shortcode jest wstawiony przez do_shortcode(), jeśli używasz go w szablonie PHP, a nie w tekście strony (Sposób 2). Jeśli wszystko jest poprawne, a przełącznika nadal nie ma, włącz WP_DEBUG w wp-config.php i sprawdź error.log, być może w functions.php jest błąd składni.

Jak zrobić flagi razem z kodami, na przykład flaga 🇬🇧 + EN?

Dodaj przed $code emoji flagi warunkowo: if ($lang['language_code'] === 'en') $code = '🇬🇧 ' . $code;. Ale pamiętaj, emoji flag mogą nie wyświetlać się w Windows. Bezpieczniej jest użyć flag CSS przez ::before z background-image lub wbudowanych flag WPML.

Czy ten kod zadziała dla Polylang lub TranslatePress?

Nie: icl_get_languages() to API właśnie WPML. Dla Polylang odpowiednikiem będzie funkcja pll_the_languages(), dla TranslatePress własny zestaw hooków. Logika ta sama, ale nazwy funkcji różne.

Podsumowanie: menu czy shortcode

Sposób z filtrem menu jest dla tych, którzy potrzebują przełącznika ściśle w nawigacji i dokładnie znają theme_location. Minimum działań: wstawiłeś kod, zamieniłeś nazwę lokalizacji, gotowe. Wada: powiązany z jednym menu, dla drugiego trzeba będzie zduplikować hook z innym theme_location.

Shortcode, jeśli przełącznik ma być w nietypowym miejscu: panel mobilny, stopka, sidebar. Dodałeś shortcode do widżetu «Kod HTML» lub do szablonu, i zarządzasz pozycją za pomocą standardowych narzędzi WordPress. Plus: można wstawić w kilku miejscach bez duplikowania kodu.

W praktyce oba sposoby spokojnie współistnieją w jednym pliku functions.php. Ustaw filtr dla menu głównego i shortcode dla wersji mobilnej, otrzymasz schludny RU | UK | EN na wszystkich urządzeniach. A jeśli przełącznik jest potrzebny po raz trzeci (na przykład w stopce), po prostu dodaj kolejny do_shortcode('[wpml_custom_lang_ISO]') do odpowiedniego szablonu.

Jakiego formatu przełącznika używasz: flagi, nazwy czy kody ISO? Podziel się w komentarzach swoim doświadczeniem konfigurowania witryn wielojęzycznych, ciekawie porównać podejścia.