Вопрос или проблема
Я создаю пользовательские правила перезаписи для категорий в двуязычном проекте (немецкий как основной, английский как второй язык). URL-адреса выглядят так:
example.com/fliegen
> показывает archive.php для категории fliegen
example.com/en/aviation
> показывает archive.php для категории aviation
(переведённое fliegen
)
Это можно было бы достичь, изменив category-base на .
(хотя, похоже, это не работает в моем случае?)
К сожалению, этого было бы недостаточно для меня; в игре также есть пользовательская таксономия под названием filter
, которая требует URL-адреса следующего вида:
example.com/fliegen/filter/some-filter
example.com/en/aviation/filter/some-filter-translated
Когда проект был однолингвальным, я пошёл этим путём:
add_filter("rewrite_rules_array", function($rules) {
$newRules = array();
$cats = get_terms("category", array("hide_empty" => false));
foreach ($cats as $id => $cat) {
$slug = $cat->slug;
$newRules[$slug . "/?$"] = "index.php?category_name=" . $slug;
$newRules[$slug . "/filter/(.+?)/?$"] = 'index.php?category_name=" . $slug . "&filter=$matches[1]';
}
return $newRules;
});
Этот код теперь также включает переведенные категории, но, очевидно, не учитывает необходимый /en/
в правиле переписывания; Поэтому мне сейчас нужен способ узнать внутри цикла foreach
, какой язык представляет текущий термин.
Как я могу это сделать?
.
.
PS: Если кто-нибудь знает, где можно найти соответствующую документацию для всех функций icl_
-php, которые, кажется, идут с WPML, пожалуйста, дайте знать!
.
Правка
Я сам нашел решение этой проблемы.
Ключом является фильтр-хук под названием wpml_element_language_details
. Но WPML изменяет основные функции, такие как get_terms
, так что вы получите только термины для текущего языка. Это может быть очень удобно в большинстве случаев, создавая правила переписывания на основе текущего активного языка в бэкенде? Не лучшая идея… поэтому вам нужно временно удалить фильтры wpml. Какие фильтры удалить? Без понятия, .. нашел это в интернете.
add_filter("rewrite_rules_array", function($rules) {
$newRules = array();
// удалить фильтры термина WPML
global $sitepress;
remove_filter('get_term', array($sitepress,'get_term_adjust_id'));
remove_filter('get_terms_args', array($sitepress, 'get_terms_args_filter'));
remove_filter('terms_clauses', array($sitepress,'terms_clauses'));
// теперь получить ВСЕ категории ВСЕХ языков,
$cats = get_terms("category", array("hide_empty" => false));
// восстановить фильтры термина WPML
add_filter('get_term', array($sitepress,'get_term_adjust_id'));
add_filter('get_terms_args', array($sitepress, 'get_terms_args_filter'));
add_filter('terms_clauses', array($sitepress,'terms_clauses'));
// Цикл по $cats
foreach ($cats as $id => $cat) {
$details = apply_filters("wpml_element_language_details", null, array("element_id" => $cat->term_id, "element_type" => "category"));
$slug = $cat->slug;
// если необходимо, добавить языковой префикс
// отсутствие source_language_code означает, что это часть основного языка и (в нашем случае) следовательно, префикс вообще не нужен
// (!) это может быть иначе для вашей установки WPML!
$lang_prefix = ($details->source_language_code != NULL)
? $details->language_code . "/"
: ""
;
$newRules[$lang_prefix . $slug . "/?$"] = "index.php?category_name=" . $slug;
$newRules[$lang_prefix . $slug . "/filter/(.+?)/?$"] = 'index.php?category_name=" . $slug . "&filter=$matches[1]';
}
.
Переключатель языков
На данный момент мой переключатель языков выглядит так:
$lang_switcher = icl_get_languages("skip_missing=0");
foreach ($lang_switcher as $lang) {
$activeClass = (($lang["active"])) ? " active" : "";
echo '
<a href="' . $lang["url"] . '" class="'.$activeClass.'">'. $lang["native_name"] .'</a>
';
}
У меня есть больше специальных случаев, таких как фильтруемая страница поиска, фильтруемые страницы авторов.
Как теперь правильно связать эти разные пользовательские URL между собой?
Более простым решением для генерации правил перезаписи было бы временно отключить плагин WPML. Я сделал это с помощью WP-CLI следующим образом:
wp plugin deactivate sitepress-multilingual-cms
wp rewrite flush
wp plugin activate sitepress-multilingual-cms
Обратите внимание, что это работает только один раз. Каждый раз, когда вы добавляете/изменяете категорию, список перезаписи очищается, и там отображаются только категории текущего языка. Поэтому это решение подходит только в том случае, если ваши категории не меняются или меняются редко.
Ответ или решение
Конечно! Давайте рассмотрим вопрос настройки переключателя языков WPML для нестандартных правил перезаписи в проекте с поддержкой двух языков, где немецкий является основным, а английский — второстепенным.
Проблема
Вы создаете нестандартные правила перезаписи для категорий на двух языках. Например, адреса для категорий могут выглядеть так:
example.com/fliegen
— для немецкой категорииfliegen
example.com/en/aviation
— для английской категорииaviation
Кроме того, у вас есть настраиваемая таксономия (фильтры), для которой требуются такие URL:
example.com/fliegen/filter/some-filter
example.com/en/aviation/filter/some-filter-translated
На начальном этапе вы реализовали базу категорий с использованием кода, однако он не учитывает языковые префиксы и не позволяет динамически определять язык для термов.
Решение
Вы нашли способ использовать фильтр wpml_element_language_details
, тем не менее, WPML изменяет стандартные функции WordPress, что может вызвать проблемы при получении всех терминов во всех языках.
Первоначально вы правильно временно отключили фильтры WPML, чтобы получить все категории, а затем восстановили их. Ваш подход хороший, и вот как он выглядит:
add_filter("rewrite_rules_array", function($rules) {
$newRules = array();
// Убираем фильтры WPML
global $sitepress;
remove_filter('get_term', array($sitepress,'get_term_adjust_id'));
remove_filter('get_terms_args', array($sitepress, 'get_terms_args_filter'));
remove_filter('terms_clauses', array($sitepress,'terms_clauses'));
// Получаем все категории всех языков
$cats = get_terms("category", array("hide_empty" => false));
// Восстанавливаем фильтры WPML
add_filter('get_term', array($sitepress,'get_term_adjust_id'));
add_filter('get_terms_args', array($sitepress, 'get_terms_args_filter'));
add_filter('terms_clauses', array($sitepress,'terms_clauses'));
// Пробегаем по всем категориям
foreach ($cats as $id => $cat) {
$details = apply_filters("wpml_element_language_details", null, array("element_id" => $cat->term_id, "element_type" => "category"));
$slug = $cat->slug;
// Добавляем языковой префикс
$lang_prefix = ($details->source_language_code != NULL)
? $details->language_code . "/"
: ""
;
$newRules[$lang_prefix . $slug . "/?$"] = "index.php?category_name=" . $slug;
$newRules[$lang_prefix . $slug . "/filter/(.+?)/?$"] = 'index.php?category_name=' . $slug . "&filter=$matches[1]";
}
return $newRules;
});
Переключатель языков
Ваш текущий код для генерации переключателя языков выглядит хорошо. Он отображает активный язык и предоставляет ссылки для переключения между языками:
$lang_switcher = icl_get_languages("skip_missing=0");
foreach ($lang_switcher as $lang) {
$activeClass = (($lang["active"])) ? " active" : "";
echo '
<a href="' . $lang["url"] . '" class="'.$activeClass.'">' . $lang["native_name"] . '</a>
';
}
Привязка различных URL
Чтобы правильно связать различные настраиваемые URL (например, фильтры и страницы авторов), вы можете использовать параметры URL, которые будут включены в связи. Убедитесь, что при создании ссылок вы включаете соответствующий языковой префикс для каждой ссылки.
Для создания соответствующих ссылок можно использовать функцию icl_permalink
, которая адаптирует URL в соответствии с языковыми настройками:
$filtered_link = icl_permalink(get_perm_link($slug, 'filter', $lang_code)); // Предполагается, что get_perm_link — это ваша функция для получения URL.
Теперь при переключении языка ваши ссылки будут встроены в соответствующие адреса.
Дополнительные ресурсы
Для глубокого понимания функционала WPML в области языкозависимых элементов, ознакомьтесь с документацией WPML, где найдёте множество примеров и описаний функций.
Таким образом, с помощью вышеописанных решений вы сможете успешно настроить реализацию переключателя языков и поддерживать правильные URL для ваших категорий и фильтров в многоязычном проекте.