用于自定义重写规则的WPML语言切换器

时间:2017-12-20 作者:kater louis

我正在一个双语项目中为类别制定自定义重写规则(德语为主,英语为第二语言)。URL如下所示

example.com/fliegen &燃气轮机;显示存档。类别的phpfliegen

example.com/en/aviation &燃气轮机;显示存档。类别的phpaviation (翻译后的fliegen)

这可以通过将类别基础更改为. (虽然对我来说似乎不起作用?)

不幸的是,无论如何,这对我来说还不够;有一种自定义分类法,称为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/ 在重写规则中;So I now need a way to ask inside the foreach loop what language the current term represents.

我能做到吗?

PS:如果有人知道在哪里可以找到合适的文档icl_-php函数,似乎是WPML附带的,请告诉我!

编辑我自己找到了一个解决方案。

关键是一个名为wpml_element_language_details. 但是WPML改变了核心功能,如get_terms 所以我们只能得到当前语言的术语。这在大多数情况下可能非常方便,根据后端当前的活动语言创建重写规则?不是个好主意。。。因此,您必须临时删除wpml过滤器。要删除哪些过滤器?不知道。。在网上找到的。

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]\';
    }

到目前为止,我的语言切换器是这样的,

$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正确地链接到彼此?

1 个回复
SO网友:Tim Havinga

生成重写规则的一个更简单的解决方案是暂时禁用WPML插件。我使用WP-CLI进行了如下操作:

wp plugin deactivate sitepress-multilingual-cms
wp rewrite flush
wp plugin activate sitepress-multilingual-cms
请注意,这只适用于一次。每次添加/修改类别时,都会刷新“重写”列表,并且仅显示当前语言类别。因此,只有当您的类别不改变或不经常改变时,这才是一个解决方案。

结束

相关推荐

multi-language WordPress site

我正在制作由WordPress支持的多语言网站。WPML 不是免费的,而且它对数据库进行了太多额外的sql查询,所以对于我的站点来说,这不是一个好的解决方案。qTranslate 将所有语言保存在一个数据库行中,以后移动到另一个多语言插件非常复杂。<?php _e( \'<!--:en-->english text<!--:--><!--:de-->german text<!--:-->\' ); ?> xLanguage 两年多没有更新