好吧,我的问题很简单。我需要为我的插件实现一些自定义路由规则。这些路线只需要一个参数(所以不复杂),看起来像:http://www.example.org/myroute/myargument
理想情况下,这将调用一个自定义类,并显示一个自定义模板(可以直接访问该类)。
最好的方法是什么?干杯
好吧,我的问题很简单。我需要为我的插件实现一些自定义路由规则。这些路线只需要一个参数(所以不复杂),看起来像:http://www.example.org/myroute/myargument
理想情况下,这将调用一个自定义类,并显示一个自定义模板(可以直接访问该类)。
最好的方法是什么?干杯
您需要做三件重要的事情:
创建自定义重写规则,将URI的一部分转换为传递给的值index.php
.myroute 和myargument
到WordPress的查询变量白名单,这样WordPress就不会在查询字符串中出现时忽略它们http://www.example.org/myroute/myargument, 您决定使用某种特殊的前缀或后缀来表示何时应该将URI视为这些特殊“路由”之一。为了这个例子,我选择了前缀api
, 这样就可以http://www.example.org/api/myroute/myargument
. 我选择了api
因为当我做了一些RESTful的事情时,就像你正在做的一样,它是针对API的。
The Code
add_filter( \'rewrite_rules_array\', \'my_insert_rewrite_rules\' );
add_filter( \'query_vars\', \'my_insert_query_vars\' );
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( $rules[\'api/(.*?)/(.+?)\'] ) ) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
// Adding a new rule
function my_insert_rewrite_rules( $rules ) {
$newrules = array();
$newrules[\'api/(.*?)/(.+?)\'] = \'index.php?myroute=$matches[1]&myargument=$matches[2]\';
return $newrules + $rules;
}
// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars ) {
array_push( $vars, \'myroute\', \'myargument\' );
return $vars;
}
Quick Breakdown
一切都很简单。正则表达式模式被添加到WordPress中所有重写规则的列表中,您的自定义模式位于列表的顶部。当模式匹配时,WordPress将停止查看重写规则列表,并使用正则表达式捕获的值代替引用($matches[1]
和$matches[2]
) 在传递给的查询字符串中index.php
.添加查询变量myroute
和myargument
进入白名单只会让WordPress关注它们,而不是丢弃它们。
Alternative way of \'namespacing\' your custom route
如果您想避免使用/api/
可以使用查询字符串变量/字段作为前缀。要这样做,您可以将正则表达式更改为(.*?)/(.+?)\\\\?api=1
然后添加api
作为array_push()
在中拨打的电话my_insert_query_vars()
.这将更改自定义路由,以便它随时触发api=1
是查询字符串的第一个元素,例如,它将触发http://example.com/anytext/anytext?api=1
.
忽略“名称空间”一词的使用——只是为了简洁起见。
如果您不使用前缀或后缀“namespace”,那么最终会出现URI模式冲突。这是因为WordPress无法将您的自定义模式与打算作为帖子或页面的模式区分开来。WordPress怎么会知道myroute
不是分类法、术语或父页?
希望这有帮助。
进一步阐述eddiemoya在上述方面所做的工作:
像这个问题的原始海报一样,我想创建一个自定义重写,并为该重写页面提供一个自定义模板。edditmoya的代码让我朝着正确的方向开始,我添加了一个额外的函数,在访问页面时提供我的自定义模板。
自定义模板可以位于任何地方,在我的情况下,它存储在插件目录中。
我还只想检查在插件激活期间是否需要刷新重写规则,所以我将其放在register\\u activation\\u挂钩上
下面是我所做工作的完整示例:
UPDATED 根据米洛的建议简化
class Your_Class
{
public function init()
{
add_filter( \'template_include\', array( $this, \'include_template\' ) );
add_filter( \'init\', array( $this, \'rewrite_rules\' ) );
}
public function include_template( $template )
{
//try and get the query var we registered in our query_vars() function
$account_page = get_query_var( \'account_page\' );
//if the query var has data, we must be on the right page, load our custom template
if ( $account_page ) {
return PATH_TO_PLUGIN_TEMPLATES_DIR . \'register.php\';
}
return $template;
}
public function flush_rules()
{
$this->rewrite_rules();
flush_rewrite_rules();
}
public function rewrite_rules()
{
add_rewrite_rule( \'account/(.+?)/?$\', \'index.php?account_page=$matches[1]\', \'top\');
add_rewrite_tag( \'%account_page%\', \'([^&]+)\' );
}
}
add_action( \'plugins_loaded\', array( new Your_Class, \'init\' ) );
// One time activation functions
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, \'flush_rules\' ) );
我已经到了需要将HTML站点地图分解为几个页面的地步。它包含2000多个链接。大版面是在一页上显示类别名称下的所有帖子标题。我决定使用WP\\u查询按字母顺序对其进行分解(分页),这样每个页面将包含大约60个帖子标题(链接)。此外,在帖子标题旁边的每一页上,都会显示相应的类别链接,以及另一个自定义分类法。我做到了,我想一切都会好起来的,无论是谷歌还是用户。然而不久之后,我收到了大量电子邮件。用户不喜欢HTML网站地图的新分页/字母顺序外观。他们希望从一个页面(或尽可能少的页面)快速访问所有帖子。我转过身来