在您答案的标签中有<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.
*/
}