在WordPress i18n项目中,通过触发带变量的内部链接来添加前缀

In the WordPress i18n project, add prefixes by triggering internal links with variables

我们正在 WordPress 中进行本地化项目。事实上,我们可以正确地添加具有语言支持的活动浏览器URL。我将在下面添加详细信息和完整代码。别担心,我的问题不会那么开放,我会把它变得更具体。

步骤 1

首先,我们应该在link结构中添加一个变量到WordPress算法中。

function custom_rewrite_basic_query_vars( $query_vars ){
    $query_vars[] = 'lang';
    return $query_vars;
}
add_filter( 'query_vars', 'custom_rewrite_basic_query_vars' );

因此,WordPress 检测到 ?lang= 等变量并将其包含在查询机制中。

步骤 2

使用"add_rewrite_rule"功能,需要在WordPress的persistentlink后台添加变量?lang=到运行结构。

简单示例:

/*
LANG PREFIX + INDEX = localhost/en/ = localhost/?lang=en
*/

add_rewrite_rule(
    '^(en|fr|de|ru|tr)/?$',
    'index.php?lang=$matches[1]',
    'top'
);

我不会一一添加剩余的实例,因为您应该使用接近 20 条重写规则。 (日期、类别、评论、页码、文本、分页等)

注意:那些从事此类项目并希望使用这些规则的人将根据要求添加它。


现在我们的持久连接结构支持语言选项的变量。

localhost/en/hello-world

localhost/ru/hello-world

localhost/de/04/07/2019

localhost/fr/page/2

等所有你能想到的 link。

步骤 3

如果从浏览器检测到变量(例如:lang=en),我们将显示之前保存的跨语言翻译的内容。

此时我们不需要任何支持。但是当我们进行到第 4 步时,我们卡住了。

第 4 步

激活之前添加的前缀语言变量,用户在站点内使用 links 时,在所有站点内导航 links.

这意味着,如果用户可以访问 localhost/fr/hello-world link,他们必须在 return 访问主页时访问 localhost/fr/contact link页面或单击联系人 link。

为此,您需要将当前在浏览器中处于活动状态的语言前缀添加到所有站内 links。

不幸的是,这是我们唯一闲逛的地方,我们找不到解决方案。

事实上,我们在写这里之前尝试了很多东西。 (当然在我们的知识范围内)。我们甚至查看了提供某些语言支持的插件。

例如<WP Multilang>

当然这么复杂,代码那么多。我们连外挂都不懂

当然,这样做有一个合乎逻辑的方法,我希望那个人看到这个 post 并回答。衷心感谢大家的支持。


一步回答

过了一会儿,我得到了以下代码并确认它可以正常工作。

<?php

function link_fn( $url ){

    $lang = get_query_var('lang', false);       

    if( $lang !== false && strpos( $url, $lang ) !== false )
        $url = $url . $lang . '/';

    return $url;
}

add_filter( 'shortcut_link', 'link_fn' );
add_filter( 'post_link', 'link_fn' );
add_filter( 'page_link', 'link_fn' );
add_filter( 'post_type_link', 'link_fn' );
add_filter( 'attachment_link', 'link_fn' );
add_filter( 'term_link', 'link_fn' );
add_filter( 'author_link', 'link_fn' );
add_filter( 'post_type_archive_link', 'link_fn' );
add_filter( 'day_link', 'link_fn' );
add_filter( 'month_link', 'link_fn' );
add_filter( 'year_link', 'link_fn' );

但是此时,我遇到了一个问题。在这里我们得到像“localhost/hello-world/[LANG]/”这样的数据。

我想要的是“localhost/[LANG]/hello-world”。

要解决这种情况,您必须向现有的URL 结构中添加一个REGEX 查询,如果它不包含LANG,则将语言代码添加到BASE URL 中。由于应该添加一个 REGEX 查询,我不能这样做...

我不想回答我自己的问题并确认。除了我上面写的代码,如果有包含我想要的查询的答案,我会把它标记为答案。


回答

function link_fn( $url ){

    $lang = get_query_var('lang', false);

    $site_url = get_option('home');

    if( $lang !== false )
    {
        $new_url = str_replace( $site_url, "", $url );

        if( preg_match('/\b$lang\b/', $new_url) !== false )
        {
            $url = $site_url."/".$lang.$new_url;
        }

    }

    return $url;
}

add_filter( 'home_url', 'link_fn' );

我认为一种可能的方法是使用 ob_start()ob_get_contents() 获取所有 HTML 内容,然后使用正则表达式获取所有 link。

注意:不是所有的link都是post/page,也有一些静态文件。

你能把语言常量作为查询字符串的一部分而不是路径吗?

而不是

localhost/en/hello-world

像这样

localhost/hello-world?lang=en

如果是请看一看How to pass extra variables in URL with WordPress

建议往这个方向深挖

add_action( 'pre_get_posts', 'lang_pre_get_posts', 1 );
function lang_pre_get_posts( $query ) {
    if ( is_admin() || ! $query->is_main_query() ){
        return;
    }
    add_query_arg( 'lang', filter_var( $_COOKIE["lang"], FILTER_SANITIZE_STRING ) );
}

你真的走得太远了。很努力

我明白了,你和胜利之间的关系只是为了改变结果link结构?

如果是,这里有一个解决方案:

function link_fn($url){

    $lang = get_query_var('lang', false);
    $url_parts = explode('/', $url);

    if ( $lang && in_array($lang, $url_parts) === false) { // lang does not exists in URL
        array_splice($url_parts, 1, 0, $lang);
    }
    $url = implode('/', $url_parts);
    return $url;

}