WordPress 永久链接和重定向

Wordpress permalinks and redirection

我每天都使用 wordpress,之前从未遇到过这个问题。也许 SO 社区有一些见解。

我有一个标准的 wordpress 安装 v4.3,这是当前版本。我没有活动的重写模块。没有设置基本类别或标签。对于干净的 URL,永久链接设置为 "Post name",这适用于整个站点,除了 /blog

下的所有内容

我尝试将 /blog/* 重写为 index.php?page_id=xxx 并编写了一个自定义解析器来处理 URI 段,这似乎在本地工作。然而,在服务器上,所有 /blog/xxx 都只是重定向到 /blog/ 即使我没有特别告诉它这样做。

我试过在 .htaccess 中设置这个:

RewriteRule blog/(category|tag|page|search)/(.+)/?$ index.php?page_id=123

即使正则表达式检查并且我为自定义 post 类型设置的所有其他重写规则都有效,但它没有用。

失败后,我尝试编写重写规则挂钩:

// pathetic hack to fix wp permalink horror for blogs
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_action( 'wp_loaded','my_flush_rules' );

// flush_rules() if our rules are not yet included
function my_flush_rules(){
    $rules = get_option( 'rewrite_rules' );

    if(isset($_GET['rules']))
    {
        echo '<pre>';
        print_r($rules);
        echo '</pre>';
    }

    if ( ! isset( $rules['blog/(category|tag|page|search)/(.+)/?$'] ) ) {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }
}

// Adding a new rule
function my_insert_rewrite_rules( $rules )
{
    $newrules = array();
    $newrules['blog/(category|tag|page|search)/(.+)/?$'] = 'index.php?page_id=123';
    return $newrules + $rules;
}

其中,如果您 运行 ?rules 在浏览器中显示当前重写数组,并且确实将其添加到数组中。然而出于某种原因,WP 正在采取的行动是 redirect 到 index.php?page_id=123 而不是加载它并让我自己解析 URI。就像 "blog" 这个词在某种程度上是保留的。

有没有其他人见过这样的事情?我能想象的唯一相关插件可能会破坏事物,但博客不是自定义内容类型。 /blog 只是一个普通页面,就像其他任何页面一样,根据 URI 段获取 posts。

我建议尝试为这些页面使用标准的 WP 架构,但客户坚持认为一切都在 /blog/category/category_name/page/x 下。他们不想就此让步,我理解,因为它在本地按预期工作。是的,服务器设置略有不同,但共同的核心元素是相同的 - htaccess 已启用,wp 是根目录且未安装在目录中,等等。

我试过禁用所有插件、切换到 2015 主题、刷新永久链接、清除缓存等。很奇怪。

任何输入或类似的故事都可能导致解决方案,所以我欢迎您提供的信息。

我正在回答我自己的问题,因为看起来很多其他人也有类似的问题,而且公认的答案很少。所以对于我的特殊情况,这就是答案:

首先,在 huksley's answer 之后,我在 Web 根目录中编写了备用 index_pass.php 文件。该文件仅包含以下内容:

<?php $_SERVER["REQUEST_URI"] = $_SERVER["REDIRECT_URI"]; include("index.php");

接下来我在 wordpress 默认值之前添加 htaccess 规则。 E=URI: 部分是这里的关键:

RewriteEngine On
RewriteBase /

RewriteRule ^blog/(category|tag|page|search)/(.+)/?$ index_pass.php?page_id=123 [NC,L,E=URI:somedomain.com/blog////]

#wordpress defaults below

然后在 functions.php 主题中我添加这个以防止新的 hacky trash 解决方案抛出 404:

add_filter('template_redirect', 'my_404_override' );
function my_404_override() {
    global $wp_query;

    if (strpos($_SERVER['REQUEST_URI'], "blog/category") > -1 || strpos($_SERVER['REQUEST_URI'], "blog/tag") > -1 || strpos($_SERVER['REQUEST_URI'], "blog/search") > -1) {
        status_header( 200 );
        $wp_query->is_404=false;
        $bypass = true;
        include('page-blog-index.php');
        exit;
    }
}

那里的流氓 $bypass 只是告诉我在 page-blog-index.php

中填补由这个​​糟糕的解决方案造成的空白

好了。有用。我不完全肯定为什么,我对此有点不舒服,但最终我不在乎,只要它有效。我更希望有一个实际的解决方案,它不会违反任何理智的程序员头脑中的每一个逻辑碎片,并且很好地在多个 PhD 派生 CMS 的实际框架内,但是嘿,我们不能一直赢,对吧?

希望对其他人有所帮助。