underpin / route-loader
Underpin 的自定义路由加载器
1.0.0
2022-02-20 18:45 UTC
Requires
- underpin/underpin: ^2.0
README
辅助添加自定义路由到 WordPress 网站的加载器。
安装
使用 Composer
composer require underpin/route-loader
手动
此插件使用内置的自动加载器,所以只要在 Underpin 之前引入它,就应该按预期工作。
require_once(__DIR__ . '/route-loader/bootstrap.php');
设置
- 安装 Underpin。请参阅 Underpin 文档
- 根据需要注册新路由。
示例
一个非常基本的示例可能看起来像这样。
plugin_name()->routes()->add( 'dashboard-home', [ 'name' => 'Dashboard', 'description' => "Route for dashboard screen", 'id_callback' => function () { // Callback function to set the route ID. This should be unique. $pieces = [ 'account' ]; $account_screen = get_query_var( 'account_screen', false ); $account_child_screen = get_query_var( 'account_child_screen', false ); if ( $account_screen ) { $pieces[] = $account_screen; } if ( $account_child_screen ) { $pieces[] = $account_child_screen; } return implode( '_', $pieces ); }, 'priority' => 'top', // Optional. sets the priority of add_rewrite_rule. Defaults to bottom. Can be "bottom" or "top" 'route' => '^account/?([A-Za-z0-9-]+)?/?([A-Za-z0-9-]+)?/?$', // Regex for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ 'query_vars' => [ 'account_screen' => '$matches[1]', 'account_child_screen' => '$matches[2]' ], // Query vars for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ ] );
或者,您可以扩展 Route
并直接引用扩展的类。这将允许您使用 Underpin 的模板加载器特质以及其他更高级的基于类的实用工具。
plugin_name()->routes()->add('key','Namespace\To\Class');
中间件
由于路由可以使用多种方式,此加载器只是 注册 路由以使用它,确保任何自定义查询参数都被列入白名单,并确保它们按顺序排列以最大限度地减少与路由的冲突。为了 执行 路由中的某些操作,您需要注册额外的动作。为了方便执行常见动作,此加载器提供了可以扩展路由行为的中间件。
模板中间件
Use_Template
中间件允许您在路由被使用时渲染自定义模板。
plugin_name()->routes()->add( 'dashboard-home', [ 'name' => 'Dashboard', 'description' => "Route for dashboard screen", 'route' => '^account/?([A-Za-z0-9-]+)?/?([A-Za-z0-9-]+)?/?$', // Regex for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ 'query_vars' => [ 'account_screen' => '$matches[1]', 'account_child_screen' => '$matches[2]' ], // Query vars for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ 'id_callback' => function () { // Callback function to set the route ID. This should be unique. $pieces = [ 'account' ]; $account_screen = get_query_var( 'account_screen', false ); $account_child_screen = get_query_var( 'account_child_screen', false ); if ( $account_screen ) { $pieces[] = $account_screen; } if ( $account_child_screen ) { $pieces[] = $account_child_screen; } return implode( '_', $pieces ); }, 'middlewares' => [ new \Underpin\Routes\Middlewares\Use_Template('/path/to/template/file.php') ] ] );
阻止查询中间件
默认情况下,WordPress 在每次页面加载时都会调用数据库调用以在查询中加载一个帖子对象。然而,有时在自定义路由上这不是必要的。但是,即使您没有指定帖子,WordPress 也会加载一个默认帖子。这会导致额外的查询,并可能引起其他不受欢迎的行为。
为了解决这个问题,请使用 Prevent_Main_Query
中间件,如下所示
plugin_name()->routes()->add( 'dashboard-home', [ 'name' => 'Dashboard', 'description' => "Route for dashboard screen", 'route' => '^account/?([A-Za-z0-9-]+)?/?([A-Za-z0-9-]+)?/?$', // Regex for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ 'query_vars' => [ 'account_screen' => '$matches[1]', 'account_child_screen' => '$matches[2]' ], // Query vars for route. See https://developer.wordpress.org/reference/functions/add_rewrite_rule/ 'id_callback' => function () { // Callback function to set the route ID. This should be unique. $pieces = [ 'account' ]; $account_screen = get_query_var( 'account_screen', false ); $account_child_screen = get_query_var( 'account_child_screen', false ); if ( $account_screen ) { $pieces[] = $account_screen; } if ( $account_child_screen ) { $pieces[] = $account_child_screen; } return implode( '_', $pieces ); }, 'middlewares' => [ new \Underpin\Routes\Middlewares\Prevent_Main_Query ] ] );
此中间件将阻止主查询运行,同时保持全局 WP_Query 保持完整。
与路由一起工作
测试当前路由
通常您需要执行某种动态逻辑来确定某些行为,这些行为仅在当前页面与您的路由匹配时运行。此加载器通过 is_current_route()
来帮助实现这一点,可以像这样使用
if( plugin_name()->routes()->is_current_route( 'route-id' ) ){ // Do something specific to this route. }
如果您直接有 Route
对象,您可以像这样访问它
if( $route->is_current_route ){ // Do something specific to this route. }