I am making custom rewrite rules for categories in a dual-language project (german as main, english as second language). The urls look like this

example.com/fliegen > shows archive.php for category fliegen

example.com/en/aviation > shows archive.php for category aviation (the translated fliegen)

This could be achieved by changing the category-base to . (although it doesn't seem to work in my case?)

Unfortunately that wouldn't be enough for me, anyways; there is a custom taxonomy called filter in the game aswell, which requires urls like this:



When the project was still single-language, I went that route:

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;

This code now also includes the translated category-terms, but obviously doesn't care about the needed /en/ in the rewrite-rule; So I now need a way to ask inside the foreach loop what language the current term represents.

Hoooow can I do that?



PS: If anybody knows where to find proper Docs for all the icl_-php functions, that seem to come with WPML, please let me know!



I found a solution to this myself.

The key is a filter-hook called wpml_element_language_details. But WPML changes core functions like get_terms so one gets only the terms for the current language. This may be very convenient in most cases, creating rewrite rules based on the currently active language in the backend? Not a good idea... therefore you have to temporarily remove the wpml-filters. Which filters to remove? No idea, .. found that online.

add_filter("rewrite_rules_array", function($rules) {
    $newRules = array();

    // remove WPML term filters
    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'));
    // now get ALL categories of ALL languages,
    $cats = get_terms("category", array("hide_empty" => false)); 
    // restore WPML term filters
    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'));

    // Loop through the $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;

        // if necessary, add language prefix
        // not having a source_language_code means this is part of the main language and (in our case) therefore doesn't need a prefix at all
        // (!) this may be different for your WPML installation!
        $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]';


Language switcher

So far my language switcher looks like this,

$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>

I have more special cases, like filterable search-page, filterable author-pages.

How can I now link these different custom urls to each other properly?

1 Answer 1


A more simple solution for generating the rewrite rules would be to temporarily disable the WPML plugin. I did this using WP-CLI as follows:

wp plugin deactivate sitepress-multilingual-cms
wp rewrite flush
wp plugin activate sitepress-multilingual-cms

Note that this only works a single time. Each time you add/modify a category, the rewrite list is flushed and only the current language categories show up there. So this is only a solution when your categories do not change, or not often.

  • wp-cli is not an option for me Commented Jun 13, 2018 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.