Routing
The PageBlocks component now includes routing support, allowing you to create routes, handle requests, and return data in various formats. This makes building API interfaces for MODX simpler and more intuitive.
Upon installation, a new App
directory is created in the core
folder, designed for configuring and managing different aspects of the component:
- Routes:
App/routes
- Controllers:
App/Http/Controllers
- Middleware:
App/Http/Middleware
- Fenom templates:
App/elements
- Fenom modifiers:
App/Helpers/modifiers.php
Example Routes
- Using a function that returns text:
Route::get('/hello', function () {
return 'Hello World';
});
- Using a controller:
Route::get('/resource', [ResourceController::class, 'index']);
Route::get('/resource/{id}', 'ResourceController@show');
Example Controller
namespace PageBlocks\App\Http\Controllers;
class ResourceController extends Controller
{
public $classKey = \modResource::class;
public function index(string $key, array $request)
{
$resources = $this->modx->getIterator($this->classKey, [
'context_key' => $key,
'published' => 1,
]);
return $resources;
}
public function show($key, $id, array $request)
{
return $this->modx->getObject($this->classKey, $id);
}
}
Objects are automatically converted to JSON.
Response Class
Controllers can return not only text or arrays but also Response objects, allowing flexible management of output.
Available Response Methods:
- Text Response
text($text, int $status = 200, array $headers = [])
- $text — response text.
- $status — HTTP status (default is 200).
- $headers — additional headers.
Example:
return response()->text('Hello World', 200, ['Content-Type' => 'text/plain']);
// Or simply:
return response()->text('Hello World');
- JSON Response
json(array $data, int $status = 200, array $headers = [])
- $data — array of data to be converted.
- $status — HTTP status (default is 200).
- $headers — additional headers.
Example:
return response()->json(['message' => 'Success']);
- Render a Template
view(string $template, array $data = [])
- $template — path to the template, which should be located in the App/elements folder.
- $data — array of data to be passed to the template.
Example:
return response()->view('templates/resource', ['title' => 'My Resource']);
- Redirect
redirect(string $url, int $status = 302, array $headers = [])
- $url — URL for the redirect.
- $status — HTTP status (default is 302).
- $headers — additional headers.
Example:
return response()->redirect('/new-url', 301);
- File Download
download(string $file, string $name = null, array $headers = [])
- $file — path to the file, relative to the root of the site.
- $name — name of the file for download (optional).
- $headers — additional headers.
Example:
return response()->download('path/to/file.zip', 'myfile.zip');
Without a Controller
Redirects and templates can be defined directly in routes:
Redirect:
Route::redirect('/here', '/there');
Template Rendering:
Route::view('/', 'templates/welcome');
Named Route Redirect:
Route::get('/', function () {
return view('templates/welcome');
})->name('welcome');
Route::get('/wel_come', function () {
return redirect()->route('welcome');
});
Advanced Routing: Prefixes, Groups, and Middleware
Example:
use Boshnik\PageBlocks\Routing\Route;
use PageBlocks\App\Http\Controllers\ConfigController;
use PageBlocks\App\Http\Controllers\ContextController;
use PageBlocks\App\Http\Controllers\ResourceController;
Route::prefix('api')->middleware(['Authenticate'])->group(function () {
Route::get('/context/', [ContextController::class, 'index']);
Route::get('/config/', [ConfigController::class, 'index']);
Route::prefix('{key}')->group(function () {
Route::get('/menu', [ResourceController::class, 'menu']);
Route::get('/resource', [ResourceController::class, 'index']);
Route::get('/resource/{id}', [ResourceController::class, 'show']);
});
});
This routing structure generates the following API links:
/api/context/
/api/config/
/api/{key}/menu
/api/{key}/resource
/api/{key}/resource/{id}
The Authenticate
middleware ensures that unauthorized users receive a 401 Unauthorized error.
List All Routes
Route::get('/route/list', function () {
return Route::getRoutes();
});
Laravel-Inspired Integration
The routing system in PageBlocks is heavily inspired by Laravel, making it easy to adapt Laravel examples for use in MODX. While the core features are implemented, the functionality will continue to expand.