alpipego / awp-router
WP 路由抽象
Requires
- php: ^7.2
README
受 Themosis 路由 启发,而 Themosis 路由又使用 Laravel 的路由,这个 WP 路由抽象增加了在 WordPress 路由中添加自定义路由和回调的支持,同时使用 WordPress 函数(add_rewrite_rule
,add_rewrite_tag
)并且不需要添加第三方路由器。
与 @tatundkraft 合作开发。
安装
通过 composer 安装此包
php composer.phar require alpipego/awp-router
初始化分发器
$dispatcher = new \Alpipego\AWP\Router\Dispatcher();
分发器接受一个 CustomRouterInterface
、一个 TemplateRouterInterface
和一个 AjaxRouterInterface
作为可选参数,如果没有提供任何参数,则初始化默认路由器。
自定义路由
$dispatcher->custom->get('/my-custom-route', function(WP_Query $query) { // do something with your query });
上一个示例添加了一个自定义路由 my-custom-route
,它只响应 GET
(和 HEAD
)请求,并将一个 WP_Query
对象传递回回调。
方法
目前实现了 GET
、POST
和 HEAD
方法;可以通过以下方法添加自定义路由
head
(匹配HEAD
请求):head(string $route, callable $callable)
get
(匹配GET
和HEAD
请求):get(string $route, callable $callable)
post
(匹配POST
请求):post(string $route, callable $callable)
any
(匹配GET
、POST
和HEAD
请求):any(string $route, callable $callable)
match
方法作为第一个参数传递:match(array $methods, string $route, callable $callable)
和 match
,它接受可能的方法作为第一个参数
// match(array $methods, string $route, callable $callable) $dispatcher->custom->match(['GET', 'POST'], '/true-get', function(WP_Query $query) { // ... });
变量
变量可以是匹配的,因此可以作为 query_vars
使用,或者是不匹配的,只作为验证路由的方式。
变量以以下形式添加:{VARNAME:REGEX}
,你可以省略 VARNAME
或 REGEX
。
在以下示例中,form_id
和 input_name
作为 query_vars
传递回 $query
对象。最后一个正则表达式简单地匹配任意三个字符,例如 abc
但不是 abcd
(并且不添加查询变量)
$dispatcher->custom->post('/forms/{form_id:\d+}/input/{input_name}/{[a-z]{3}}', function(WP_Query $query) { // ... });
注意:
- 这些变量是“私有的”,因此不能在 URL 查询字符串中使用;参阅 公共与私有查询变量
重写标签
已注册的查询变量(无论是内置的公共变量还是通过插件等注册的)可以在路由中使用,并且以开头和结尾的 %
注册,即 {%QUERYVAR%:REGEX}
$dispatcher->custom->post('/pages/{%page_id%}/fields/{%field_id%:\d+}', function(WP_Query $query) { // ... });
这将匹配内置的 page_id
查询变量,并将自定义的 field_id
查询变量添加到 WP_Query
。
注意:
- 所有重写标签都是“公共查询变量”并且可以用作URL查询字符串中;参见 公共与私有查询变量
- 在已经定义的重写标签中添加正则表达式时请小心,因为这会覆盖之前的正则表达式。
重定向
RouterInterface
有一个添加重定向的方法
// redirect(string $route, string $target, array $methods = ['GET', 'HEAD'], int $status = 308) $dispatcher->custom->redirect('/twitter/{twitter_user}', 'https://twitter.com/{twitter_user}');
此路由将重定向 https://YOURSITE.com/twitter/alpipego
到 https://twitter.com/alpipego
当然,重定向也可以在路由中使用正则表达式和重写标签。
$dispatcher->custom->redirect('/attachment/{%attachment_id%}', 'https://external-attachment-handler.com/{attachment_id}');
注意:
- 默认情况下,只有
GET
和HEAD
请求会被重定向 - 默认的重定向代码是
308
,确保HTTP方法得到正确的重定向
回调函数
你可以传递任何 callable
作为回调函数。
回调函数将接收当前的 WP_Query
对象作为第一个参数,以下返回类型可以被处理
- 如果回调函数返回
false
,则传播停止,请求结束(即,不渲染任何模板)。 - 回调函数可能返回一个有效模板文件的完整路径(基本上是任何PHP文件),然后被引入。
- 如果回调函数没有返回值,WordPress的默认 模板加载和层次结构 会被启动。
模板路由
条件
condition
方法将返回布尔值的可调用对象作为其第一个参数,以及当条件为真时将在渲染模板之前执行的回调函数作为其第二个参数。这两个回调函数都接收当前的 WP_Query
以进行操作,可调用对象还接收模板文件的完整路径。有关它们的处理方式,请参阅 回调函数部分。
// public function condition(callable $condition, callable $callable); $dispatcher->template->condition(function(WP_Query $query) { // if this is true return $query->is_page; }, function(WP_Query $query, string $template) { // then execute this return $template; });
文章类型模板
在不限制WordPress实现的情况下注册 文章类型模板。该 template
方法将模板文件路径作为第一个参数(相对于当前(子)主题),模板名称(用于wp-admin侧边栏选择框)作为第二个参数,此模板应可用的文章类型作为第三个参数,以及回调函数作为最后一个参数。有关它们的处理方式,请参阅 回调函数部分。除了当前的 WP_Query
对象外,回调函数还接收模板的完整路径作为第二个参数。
// public function template(string $template, string $name, array $postTypes, callable $callable); $dispatcher->template->template('my-page-template.php', __('Page Template Name', 'textdomain'), ['page', 'post'], function(WP_Query $query, string $template) { // ... });
Ajax路由
AJAX请求可以是 GET
或 POST
请求(或两者都是),并且仅适用于已登录用户或所有用户。你可以在以下格式中为AJAX请求定义自定义路由
// public function get(string $route, callable $callback, bool $private = false); $dispatcher->ajax->get('/ajax/user/{user_id:\d+}', function () { $userId = (int)$_GET['query']['user_id']; $user = new WP_User($userId); if ($user->ID === 0) { wp_send_json_error(sprintf('User #%d does not exist', $userId)); } wp_send_json_success($user); }, true);
注意:
- 与其他路由器相比,回调函数不会接收到
WP_Query
对象;查询变量包含在$_REQUEST
超全局变量中。 - 与WordPress的AJAX操作相比,未标记为私有的请求适用于已登录和未登录用户(
priv
与nopriv
)。