WordPress中的自定义插件路线

时间:2012-07-10 作者:Fran

好吧,我的问题很简单。我需要为我的插件实现一些自定义路由规则。这些路线只需要一个参数(所以不复杂),看起来像:http://www.example.org/myroute/myargument

理想情况下,这将调用一个自定义类,并显示一个自定义模板(可以直接访问该类)。

最好的方法是什么?干杯

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

您需要做三件重要的事情:

创建自定义重写规则,将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.

添加查询变量myroutemyargument 进入白名单只会让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 不是分类法、术语或父页?

希望这有帮助。

SO网友:Matt Keys

进一步阐述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\' ) );

结束

相关推荐

Paginated HTML Sitemap

我已经到了需要将HTML站点地图分解为几个页面的地步。它包含2000多个链接。大版面是在一页上显示类别名称下的所有帖子标题。我决定使用WP\\u查询按字母顺序对其进行分解(分页),这样每个页面将包含大约60个帖子标题(链接)。此外,在帖子标题旁边的每一页上,都会显示相应的类别链接,以及另一个自定义分类法。我做到了,我想一切都会好起来的,无论是谷歌还是用户。然而不久之后,我收到了大量电子邮件。用户不喜欢HTML网站地图的新分页/字母顺序外观。他们希望从一个页面(或尽可能少的页面)快速访问所有帖子。我转过身来