ssnepenthe/simple-wp-routing

在 WP_Rewrite API 之上的语法糖,这样我们可以假装 WordPress 有一个现代的路由器。

0.1.1 2024-01-05 17:17 UTC

README

WP_Rewrite API 之上的语法糖,这样我们可以假装 WordPress 有一个现代的路由器。

警告

该包目前正在开发中,直到 v1.0 被标记之前,可能会在没有通知的情况下进行破坏性更改。

这是我在一系列 WordPress 玩具 中之一,我一直在努力探索现代化 WordPress 工作方式的方法。

正如标签所暗示的,它应该被视为一个玩具。

安装

composer require ssnepenthe/simple-wp-routing

基本用法

预期的用法是通过 Router 类。

概述

use SimpleWpRouting\Exception\NotFoundHttpException;
use SimpleWpRouting\Responder\JsonResponder;
use SimpleWpRouting\Router;

// Create a router instance.
$router = new Router();

// Optional - configure your router via various available setters.
// At a minimum it is recommended to set a route prefix in order to avoid conflicts with core and other plugins.
$router->setPrefix('pfx_');

// Wire your router up with WordPress.
$router->initialize(

  // The initialize method accepts a callback which is where you should add all of your routes.
  function (Router $router) {

    // Routes are registered via HTTP method shortcuts on the router instance.
    $route = $router->get(

      // Route syntax comes from FastRoute.
      'api/users/{user}',

      // Route handlers are automatically invoked for their corresponding route/HTTP method pair.
      function (array $vars) {

        // Handlers receive an array of matched route variables by default.
        $user = getUserDataById((int) $vars['user']);

        // HTTP exceptions are automatically converted to error responses.
        if (null === $user) {
          throw new NotFoundHttpException();
        }

        // Handlers can optionally return a responder instance.
        return new JsonResponder($user);
      }
    );

    // Routes can optionally be configured with an active callback.
    $route->setIsActiveCallback(function () {

      // Return true to enable this route, false to disable it.
      return isApiUserEndpointEnabled();
    });
  }
);

路由语法

默认路由语法来自 FastRoute。

路由变量用大括号包裹,默认情况下匹配正则表达式模式 [^/]+(例如,users/{user})。可以使用 name:pattern 语法提供自定义正则表达式模式(例如,users/{user:\d+})。自定义模式不允许捕获组。

可选路由段使用方括号定义(例如,users/{user}[/favorites])。也支持嵌套可选段(例如,users[/{user}[/favorites]])。可选段仅支持在路由字符串的末尾。

如果您更喜欢 FastRoute 以外的路由语法,您可以提供自定义路由解析器。您的解析器必须实现 \SimpleWpRouting\Parser\RouteParserInterface。请参阅包含的 tests/Unit/Parser/FastRouteRouteParserTest.php 文件以了解路由解析器要求。

路由处理程序

当相应的路由/方法对与当前请求匹配时,在 'parse_request' 钩子内部自动调用路由处理程序。

处理程序的允许类型由可调用解析器定义。在默认配置下,处理程序必须是一个 PHP 可调用函数。如果您使用 PSR 容器可调用解析器,处理程序也可以是一个解析您容器的可调用函数的字符串标识符,或者是一个可调用数组,其中索引 0 是解析您容器中的对象的字符串标识符,索引 1 是该对象上的可调用方法。

函数签名由配置的调用者定义。默认调用者提供一个数组,其中包含所有匹配的路由变量,键名为变量名。PHP-DI 调用者直接按名称提供匹配的路由变量。

可以使用 HTTP 异常作为从处理程序中方便地退出的逃生舱。

NotFoundHttpException

这是当前唯一的非内部 HTTP 异常,可用于显示 404 页面。

use SimpleWpRouting\NotFoundHttpException;

$router->get('books/{book}', function (array $vars) {
  if (! $book = getBookById($vars['book'])) {
    throw new NotFoundHttpException();
  }

  // ...
});

路由处理程序可以选择返回 SimpleWpRouting\Responder\ResponderInterface 的实例。返回的响应器上的 respond 方法将自动在 WordPress parse_request 动作上调用。

这使得将常见行为轻松包装起来以供重用。

包含以下基本响应器实现

JsonResponder

use SimpleWpRouting\Responder\JsonResponder;

$router->get('api/products', function () {
  return new JsonResponder(['products' => getAllProducts()]);
});

根据状态码,使用 wp_send_json_successwp_send_json_error 发送响应,因此数据将在 response.data 中可用。

QueryResponder

use SimpleWpRouting\Responder\QueryResponder;

$router->get('products/random[/{count}]', function (array $vars) {
  $count = (int) ($vars['count'] ?? 5);

  return new QueryResponder([
    'post_type' => 'pfx_product',
    'orderby' => 'rand',
    'posts_per_page' => clamp($count, 1, 10),
  ]);
});

在运行主查询之前,在 parse_request 钩子上应用查询变量。

RedirectResponder

use SimpleWpRouting\Responder\RedirectResponder;

$router->get('r/{redirect}', function (array $vars) {
  $location = getRedirectLocationById($vars['redirect']);

  return new RedirectResponder($location);
});

默认情况下,重定向是通过 wp_safe_redirect 发送的。您可以将 false 作为第 4 个构造函数参数传递,以使用 wp_redirect 代替

return new RedirectResponder($location, 302, 'WordPress', false);

TemplateResponder

use SimpleWpRouting\Responder\TemplateResponder;

$router->get('thank-you', function () {
  return new TemplateResponder(__DIR__ . '/templates/thank-you.php');
});

模板是通过 template_include 过滤器加载的。

活动回调

活动回调的允许类型也由配置的调用解析器定义。

活动回调应返回一个布尔值 - 当为 true 时,路由将被视为活动状态,当为 false 时,路由将被视为非活动状态。

对于非活动路由的重写规则和查询变量仍然注册在 WordPress 中,但访问该路由将导致 404 响应。

错误模板

基本的 400 和 405 错误模板包含以 twentytwentytwo 404 模板为模板的风格。

这些可以通过在主题中创建 400.php405.php 模板或 400.html405.html 块模板来覆盖。

可能的变化

在整个包中使用的各种 SPL 异常的类型,以及重新审视包异常的一般层次结构。

响应器内部 - 部分概念有些复杂/过度设计。任何更改都不应影响为最终用户使用而设计的顶级响应器。