WordPress重写规则不起作用

时间:2013-08-15 作者:Umesh Awasthi

我正在尝试为我的一个自定义页面创建重写规则,下面是重写规则

function add_my_rule() {
    global $wp;
    $wp->add_query_var(\'name_state\');
    $wp->add_query_var(\'arg_second\');
    add_rewrite_rule(\'state/([^/]+)/([^/]+)/page/([^/]+)\',\'index.php?pagename=places-to-visit&name_state=$matches[1]&arg_second=$matches[2]&paged=$matches[3]\',\'top\');
    add_rewrite_rule(\'state/([^/]+)/([^/]+)\',\'index.php?pagename=places-to-visit&name_state=$matches[1]&arg_second=$matches[2]\',\'top\');

    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

add_action(\'init\', \'add_my_rule\');
这就是我要做的。我有以下URL

www.mydomain.com/state/state-name/places-to-visit
我已经创建了一个名为places-to-visit.php.我的目的是将所有此类URL重定向到此自定义页面,并希望从URL中获得以下信息作为查询变量

2 个回复
最合适的回答,由SO网友:Umesh Awasthi 整理而成

我能解决这个问题。老实说,到目前为止,我还不能完全理解WordPress重写规则是如何工作的,以及WordPress是如何选择我的自定义页面的。

除了一件事之外,我做的一切都是对的,我没有将我的自定义模板与任何slug关联。在我从WordPress仪表板分配的那一刻,我就能够解决我的问题了

感谢大家的宝贵意见。

SO网友:gmazzap

在您答案的标签中有<plugins>

在您的问题中,您谈到了页面模板(通常)与主题相关的问题。当然,您可以从插件创建重写规则,并将其用于主题中定义的页面模板,但这可能不是一个好主意:您的插件功能将取决于主题。

此外,如果您创建的页面模板比您必须创建的页面多,请分配页面模板并使用定义的slug,否则插件重写规则将无法工作。因此,您的插件也依赖于内容,这同样不是一个好主意。

那么,如何使您的插件功能独立于主题中的页面模板和内容,但又保持wordpress标准和功能呢?

一种方法是在插件文件夹中创建一个文件,并将重写规则重定向到此文件的url,而不是索引。php。这样做,如果您需要wordpress环境,您需要手动要求文件wp_load.php 位于worpress安装根目录上的。但此路径必须硬编码,很多时候这不是一个好主意,在迁移服务器时可能会带来问题。此外,如果您计划分发插件,这是一个非常糟糕的主意。

还有其他解决方案吗?

对于我开发的插件,我使用了一种“虚拟页面”,用于重定向请求。

首先in the main plugin file, 我们为页面定义虚拟slug。为插件创建一个可以更改此段代码的设置页是个好主意,但对于semplicity,我会将其设置为常量:

define(\'MY_VIRTUAL_PAGENAME\', \'a-strange-slug-for-places-to-visit-fake-page\');
之后,在同一个文件中,我们定义自定义重写规则并注册自定义查询变量:

add_action(\'init\', \'add_my_rules\');

function add_my_rules() {
  add_rewrite_rule(\'state/([^/]+)/([^/]+)/page/([^/]+)\', \'index.php?pagename=\' . MY_VIRTUAL_PAGENAME . \'&name_state=$matches[1]&arg_second=$matches[2]&paged=$matches[3]\', \'top\');
  add_rewrite_rule(\'state/([^/]+)/([^/]+)\', \'index.php?pagename=\' . MY_VIRTUAL_PAGENAME . \'&name_state=$matches[1]&arg_second=$matches[2]\', \'top\');
}

add_filter( \'query_vars\', \'add_my_vars\' );

function add_my_vars( $vars ) {
  $vars[] = \'name_state\';
  $vars[] = \'arg_second\';
  return $vars;
}
现在我们必须刷新重写规则。在您的代码中,您是在init上执行此操作的,因此每个页面请求都会刷新规则:这绝对不是一个好主意。我们只使用注册挂钩运行一次:

register_activation_hook( __FILE__, \'my_flush_rewrite_rules\' );

function my_flush_rewrite_rules() {
  add_my_rules();
  flush_rewrite_rules();
}
此时,当需要一个特定的url时,我们告诉wordpress加载一个包含我们保存在常量上的slug的页面MY_VIRTUAL_PAGENAME, 但此页面不存在。

所以现在我们欺骗wordpress,让它显示我们的虚拟页面。

add_action( \'pre_get_posts\', \'show_places_to_visit\', 1 );

function show_places_to_visit( $wp_query ) {
  $pagename = isset($wp_query->query[\'pagename\']) ? $wp_query->query[\'pagename\'] : NULL;
  if ( ! is_admin() && is_main_query() && $pagename == MY_VIRTUAL_PAGENAME ) {

    // get our custom vars
    $name_state = $wp_query->get(\'name_state\');
    $arg_second = $wp_query->get(\'arg_second\');
    $paged = $wp_query->get(\'paged\') ? : 1;

    // now I require the file that contain our business logic
    require( plugin_dir_path(__FILE__) . \'places-to-visit.php\' );

    exit(); // stop default wordpress behavior
  }
}
使用上述代码,我们在启动wp主查询之前运行一个函数。在这个函数中,我们检查请求的页面名(如果存在)是否是我们保存在常量中的页面名,如果是,我们需要一个名为places-to-visit.php 位于主插件文件的同一文件夹中。

现在我们只需创建文件places-to-visit.php 在那里,我们有所有的wordpress环境,我们可以随意使用。

如果您计划在此文件中运行WP\\u查询,这可能是最好利用query_posts 而不是使用WP_Query 实例:通过这种方式,您将替换原来的主查询,因为它只是一个伪查询,因此没有任何用处。

下面只是一个参观的地方的例子。php文件,我打赌您可以在其中做一些更有用的事情:

/**
* in places-to-visit.php file I can simply use the variables defined in
* show_places_to_visit() function in main plugin file
*/
$args = array(
  \'post_type\' => \'places\',
  \'posts_per_page\' => $arg_second,
  \'category_name\' => $name_state,
  \'paged\' => $paged
);
query_posts($args);

/**
* If in your theme is present a file called places-to-visit.php or a file called 
* archive-places it will be used to handle the query.
* If not you have to output the page content from plugin.
*/

if ( locate_template( array(\'places-to-visit.php\',\'archive-places.php\'), true ) == \'\' ) {

  /**
  * Code that generate page content goes here.
  * If you want, you can use template functions like
  * get_header(); get_footer(); get_template_part(); and so on.
  */

}

结束

相关推荐