WordPress add_rewrite_rule()未显示预期页面问题求助
看起来你碰到的是Nginx和Apache URL重写机制差异导致的典型问题——Apache依赖.htaccess处理WordPress的动态rewrite规则,但Nginx得在服务器配置里明确把所有非静态请求转发给WordPress的index.php,不然你的自定义规则根本没机会被WordPress解析。下面是针对Laravel Valet和Forge环境的具体解决方案:
1. 先注册Rewrite Tag(可选但更保险)
虽说category是WordPress的默认查询变量,但明确注册它能避免潜在的规则冲突。在你的插件类里添加这段代码:
function __construct() { add_action('init', array($this, 'register_custom_query_var'), 5); // 提前注册变量 add_action('init', array($this, 'category_rewrite_rule'), 10); } function register_custom_query_var() { add_rewrite_tag('%category%', '([^/]*)'); } function category_rewrite_rule() { add_rewrite_rule( '^products/([^/]*)/?', 'index.php?category=$matches[1]', 'top' ); }
添加完记得去WP后台→设置→固定链接页面,直接点保存刷新规则。
2. 调整Nginx配置(核心解决步骤)
针对Laravel Valet环境
Valet默认的WordPress配置可能没正确处理所有动态请求,你需要修改站点配置:
- 找到Valet的站点配置目录,一般是
~/.config/valet/Nginx/ - 找到对应你站点的
.conf文件,打开后找到location /块,确保它包含:
location / { try_files $uri $uri/ /index.php?$query_string; }
如果原来的配置里有拦截/products/的规则,直接删掉或者调整优先级。修改完重启Valet:
valet restart
针对Laravel Forge环境
Forge的WordPress默认配置也需要微调:
- 登录Forge面板,进入你的站点→Nginx配置页面
- 在
server块里,确保location /部分的规则是:
location / { try_files $uri $uri/ /index.php?$query_string; }
同时检查有没有其他针对/products/的location规则,这些规则会优先匹配,导致WordPress的rewrite规则失效,需要删除或调整。保存配置后重启Nginx:
sudo service nginx restart
3. 验证规则是否生效
你可以用flush_rewrite_rules()函数强制刷新规则,或者直接去数据库wp_options表找rewrite_rules选项,确认你的^products/([^/]*)/?规则已经存在。另外也可以加个过滤器检查变量是否传递成功:
add_filter('query_vars', function($vars) { error_log(print_r($vars, true)); // 查看服务器日志确认category变量是否存在 return $vars; });
为什么LAMP环境正常?因为Apache的.htaccess默认会把所有非静态请求转发给index.php,WordPress的rewrite规则能正常解析;而Nginx默认不会这么做,必须明确配置try_files规则,不然请求会被当成静态资源处理,找不到就返回首页。
内容的提问来源于stack exchange,提问作者the_peacock

