WordPress中移除REST API端点前的语言slug以解决插件端点授权问题
WordPress中移除REST API端点前的语言slug以解决插件端点授权问题
嘿,我太懂你这个困扰了——翻译插件自动给所有内部链接加上语言slug(比如domainname.com/en)确实让多语言站点管理方便不少,但偏偏把REST API端点也带上了,变成en/plugin-name/v1这种格式,导致插件的接口因为路径不匹配触发授权失败,一个个手动注册路由又实在太繁琐对吧?别慌,这里有几个更高效的解决思路,不用挨个改插件代码:
方法一:直接让翻译插件排除REST API路径(最省心)
大部分主流翻译插件(比如WPML、Polylang)都自带“路径排除”功能,你可以找到插件的URL设置或高级配置页面,把REST API的基础路径(默认是/wp-json/)添加到排除列表里。这样翻译插件就不会给REST端点自动加上语言slug了,从根源上解决问题。
如果你的翻译插件没找到这个选项,再试试下面的代码方案。
方法二:拦截请求并重写REST路由路径
通过WordPress的parse_request钩子,我们可以在系统解析请求的时候,自动移除REST路由开头的语言slug,让请求指向原本的插件端点。把这段代码加到你的主题functions.php或者自定义插件里:
add_action('parse_request', function($wp) { // 先确认当前是REST API请求 if (!isset($wp->query_vars['rest_route'])) { return; } // 这里替换成你站点实际使用的语言slug列表 $language_slugs = ['en', 'fr', 'de']; $current_route = $wp->query_vars['rest_route']; // 检查路由是否以语言slug开头,如果是就移除它 foreach ($language_slugs as $slug) { if (strpos($current_route, "/{$slug}/") === 0) { $wp->query_vars['rest_route'] = substr($current_route, strlen("/{$slug}/")); break; } } });
这个方法的好处是不用修改任何插件的路由逻辑,只是在请求层面做了路径修正,兼容性很强。
方法三:批量注册带语言slug的REST路由(兜底方案)
如果上面两种方法都不适用,我们可以用代码批量给所有已注册的REST路由生成带语言slug的版本,这样不管请求带不带slug都能被正确处理。代码如下:
add_action('rest_api_init', function() { global $wp_rest_server; if (!isset($wp_rest_server)) { return; } // 替换成你的语言slug列表 $language_slugs = ['en', 'fr']; $existing_routes = $wp_rest_server->get_routes(); foreach ($existing_routes as $route_path => $route_handlers) { // 跳过已经带语言slug的路由,避免重复注册 if (preg_match('/^\/(' . implode('|', $language_slugs) . ')\/', $route_path)) { continue; } // 给每个路由添加带语言前缀的版本 foreach ($language_slugs as $slug) { $new_route = "/{$slug}{$route_path}"; // 复制原路由的配置进行注册 $wp_rest_server->register_route( $route_handlers[0]['callback'][0]->namespace, $new_route, $route_handlers[0]['args'] ); } } }, 100); // 用100的优先级,确保在所有插件注册路由之后执行
这个方案会自动适配所有已注册的REST路由,不用你手动一个个去写register_rest_route,不过要注意少数特殊路由可能会有参数兼容问题,测试一下没问题再用。
备注:内容来源于stack exchange,提问作者janlindso
相关产品推荐
相关产品推荐

