Routing
Basic Routing
The most basic WpMVC routes accept a URI and a closure, providing a very simple and expressive method of defining routes and behavior without complicated configuration.
<?php
namespace MyPluginNamespace\App;
defined( "ABSPATH" ) || exit;
use MyPluginNamespace\WpMVC\Routing\Route;
use MyPluginNamespace\WpMVC\Routing\Response;
Route::get( 'greeting', function () {
return Response::send( [ 'message' => 'Hello World' ] );
} );The Default Route Files
All WpMVC routes are defined in your route files, which are located in the routes directory of your plugin. These files are automatically loaded by the framework.
REST Routes
The routes/rest/api.php file defines routes that are for your REST API interface. These routes are integrated with the WordPress REST API system and are assigned the rest namespace.
<?php
namespace MyPluginNamespace\App;
defined( "ABSPATH" ) || exit;
use MyPluginNamespace\WpMVC\Routing\Route;
use MyPluginNamespace\App\Http\Controllers\UserController;
Route::get( 'user', [ UserController::class, 'index' ] );AJAX Routes
The routes/ajax/api.php file defines routes for AJAX requests. This is WpMVC’s custom route system, useful when third-party plugins might interfere with standard REST routes.
<?php
namespace MyPluginNamespace\App;
defined( "ABSPATH" ) || exit;
use MyPluginNamespace\WpMVC\Routing\Ajax;
use MyPluginNamespace\WpMVC\Routing\Response;
Ajax::get( 'user', function () {
return Response::send( [ 'ID' => 1, 'name' => 'john' ] );
} );Available Router Methods
The router allows you to register routes that respond to any HTTP verb:
Route::get( $uri, $callback );
Route::post( $uri, $callback );
Route::put( $uri, $callback );
Route::patch( $uri, $callback );
Route::delete( $uri, $callback );
Route::options( $uri, $callback );Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method. Or, you may even register a route that responds to all HTTP verbs using the any method:
Route::match( [ 'get', 'post' ], '/', function () {
// ...
} );
Route::any( '/', function () {
// ...
} );Dependency Injection
You may type-hint any dependencies required by your route in your route’s callback signature. The declared dependencies will automatically be resolved and injected into the callback by the WpMVC service container. For example, you may type-hint the MyPluginNamespace\WpMVC\RequestValidator\Request class to have the current HTTP request automatically injected into your route callback:
<?php
namespace MyPluginNamespace\App;
defined( "ABSPATH" ) || exit;
use MyPluginNamespace\WpMVC\Routing\Route;
use MyPluginNamespace\WpMVC\RequestValidator\Request;
Route::get( 'users', function ( Request $request ) {
// ...
} );Route Parameters
Required Parameters
Sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user’s ID from the URL. You may do so by defining route parameters:
Route::get( 'user/{id}', function ( $id ) {
return Response::send( [ 'user_id' => $id ] );
} );You may define as many route parameters as required by your route:
Route::get( 'posts/{post}/comments/{comment}', function ( $post_id, $comment_id ) {
// ...
} );Optional Parameters
Occasionally you may need to specify a route parameter that may not always be present in the URI. You may do so by placing a ? mark after the parameter name. Make sure to give the route’s corresponding variable a default value:
Route::get( 'user/{name?}', function ( $name = null ) {
return Response::send( [ 'name' => $name ] );
} );Regular Expression Constraints
You may constrain the format of your route parameters using the where method on a route instance. The where method accepts the name of the parameter and a regular expression defining how the parameter should be constrained:
Route::get( 'user/{name}', function ( $name ) {
// ...
} )->where( 'name', '[A-Za-z]+' );
Route::get( 'user/{id}', function ( $id ) {
// ...
} )->where( 'id', '[0-9]+' );For convenience, you can constrain multiple parameters at once by passing an array to the wheres method:
Route::get( 'user/{id}/{name}', function ( $id, $name ) {
// ...
} )->wheres( [
'id' => '[0-9]+',
'name' => '[a-z]+'
] );Named Routes
Named routes allow the convenient generation of URLs or redirects for specific routes. You may specify a name for a route by chaining the name method onto the route definition:
Route::get( 'user/profile', [ UserController::class, 'show' ] )->name( 'profile' );Generating URLs to Named Routes
Once you have assigned a name to a given route, you may use the route’s name when generating URLs via WpMVC’s Router::url method:
use MyPluginNamespace\WpMVC\Routing\Router;
// Generating URLs...
$url = Router::url( 'profile' );
$url = Router::url( 'profile', [ 'id' => 1 ] );Router::url() only functions within route callbacks. For generating URLs outside of these contexts, use native WordPress functions like get_rest_url().
$site_id = get_current_blog_id();
$namespace = 'my-plugin/v1';
$base_url = get_rest_url( $site_id, $namespace );
$user_url = $base_url . '/user';Route Groups
Route groups allow you to share route attributes, such as middleware, across a large number of routes without needing to define those attributes on each individual route.
Middleware
To assign middleware to all routes within a group, you may use the middleware method before defining the group. Middleware are executed in the order they are listed in the array:
Route::middleware( [ 'first', 'second' ] )->group( function () {
Route::get( '/', function () {
// Uses first & second middleware...
} );
Route::get( '/user/profile', function () {
// Uses first & second middleware...
} );
} );Route Prefixes
The prefix method may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:
Route::prefix( 'admin' )->group( function () {
Route::get( 'users', function () {
// Matches The "/admin/users" URL
} );
} );Route Name Prefixes
The name method may be used to prefix each route name in the group with a given string. For example, you may want to prefix the names of all of the routes in the group with admin. The given string is prefixed to the route name exactly as it is specified, so we will be sure to provide the trailing . character in the prefix:
Route::name( 'admin.' )->group( function () {
Route::get( 'users', function () {
// Route assigned name "admin.users"...
} )->name( 'users' );
} );Route Macros
The Route class is “macroable”, allowing you to define custom methods:
use MyPluginNamespace\WpMVC\Routing\Route;
use MyPluginNamespace\WpMVC\Routing\Response;
Route::macro( 'status', function ( $uri ) {
return Route::get( $uri, function () {
return Response::send( [ 'status' => 'OK' ] );
} );
} );
// Usage
Route::status( 'system/status' );Standalone Usage
If you are using the full WpMVC framework, these configurations are handled automatically. These instructions are for integrating wpmvc/routing independently.
Requirement
WpMVC routing requires a DI container with get and set methods. We recommend wpmvc/container .
Configuration
In your RouteServiceProvider, configure your namespaces and directory:
<?php
namespace MyPluginNamespace\Providers;
defined( "ABSPATH" ) || exit;
use MyPluginNamespace\WpMVC\Container\Container;
use MyPluginNamespace\WpMVC\Routing\Providers\RouteServiceProvider as BaseProvider;
class RouteServiceProvider extends BaseProvider
{
public function boot() {
static::set_container( new Container );
static::set_properties( [
'rest' => [
'namespace' => 'my-plugin',
'versions' => [ 'v1' ]
],
'ajax' => [
'namespace' => 'my-plugin',
'versions' => []
],
'routes-dir' => ABSPATH . 'wp-content/plugins/my-plugin/routes'
] );
parent::boot();
}
}