Usage

Core patterns and workflows for WPZylos Routing.

Frontend Routes

Basic Routes

// routes/web.php
return function (\WPZylos\Framework\Routing\Router $router) {
    $router->get('/products', [ProductController::class, 'index']);
    $router->post('/contact', [ContactController::class, 'submit']);
    $router->put('/users/{id}', [UserController::class, 'update']);
    $router->delete('/users/{id}', [UserController::class, 'destroy']);
};

Route Parameters

// Basic parameter
$router->get('/users/{id}', fn($id) => "User: {$id}");

// With regex constraint
$router->get('/posts/{slug}', [PostController::class, 'show'])
    ->where('slug', '[a-z0-9-]+');

Route Groups

$router->group(['prefix' => '/admin', 'middleware' => ['auth']], function ($router) {
    $router->get('/dashboard', [AdminController::class, 'dashboard']);
    $router->get('/settings', [AdminController::class, 'settings']);
});

Named Routes

$router->get('/users/{id}', [UserController::class, 'show'])
    ->name('user.show');

// Generate URL
$url = $router->url('user.show', ['id' => 42]);

REST API Routes

Basic Endpoints

// routes/api.php
return function (\WPZylos\Framework\Routing\RestRouter $rest) {
    $rest->get('/users', [UserController::class, 'index']);
    $rest->post('/users', [UserController::class, 'store']);
    $rest->get('/users/{id}', [UserController::class, 'show']);
};

Permissions

$rest->get('/admin/stats', [AdminController::class, 'stats'])
    ->permission('manage_options');

$rest->delete('/posts/{id}', [PostController::class, 'destroy'])
    ->setPermissionCallback(fn($req) => current_user_can('delete_post', $req['id']));

Resource Routes

// Creates: index, store, show, update, destroy
$rest->resource('posts', PostController::class);

// Limit actions
$rest->resource('comments', CommentController::class, ['index', 'store']);

AJAX Routes

Basic Actions

// routes/ajax.php
return function (\WPZylos\Framework\Routing\AjaxRouter $ajax) {
    // Private: requires login
    $ajax->private('save_settings', [SettingsController::class, 'save']);

    // Public: no login required
    $ajax->public('search', [SearchController::class, 'handle']);
};

Nonce Handling

// Automatic verification (default)
$ajax->private('update_profile', [ProfileController::class, 'update']);

// Disable verification
$ajax->public('public_search', [SearchController::class, 'search'])
    ->withoutNonce();

Frontend Integration

wp_localize_script('my-script', 'myPluginData', [
    'ajaxUrl' => admin_url('admin-ajax.php'),
    'nonce' => $ajax->nonce('save_settings'),
]);
jQuery.ajax({
  url: myPluginData.ajaxUrl,
  method: "POST",
  data: {
    action: "myplugin_save_settings",
    _wpnonce: myPluginData.nonce,
    setting: "value",
  },
});

Middleware

Creating Middleware

class AuthMiddleware
{
    public function handle($request, callable $next): mixed
    {
        if (!is_user_logged_in()) {
            return new \WP_Error('unauthorized', 'Login required', ['status' => 401]);
        }
        return $next($request);
    }
}

Applying Middleware

// Single route
$router->get('/dashboard', [DashboardController::class, 'index'])
    ->middleware(AuthMiddleware::class);

// Multiple middleware
$router->get('/admin', [AdminController::class, 'index'])
    ->middleware([AuthMiddleware::class, LoggingMiddleware::class]);

// Route group
$router->group(['middleware' => [AuthMiddleware::class]], function ($router) {
    $router->get('/profile', [ProfileController::class, 'show']);
});

Container Access

// Frontend router
$router = $app->make(Router::class);
$router = $app->make('router');

// REST API router
$rest = $app->make(RestRouter::class);
$rest = $app->make('rest');

// AJAX router
$ajax = $app->make(AjaxRouter::class);
$ajax = $app->make('ajax');