Routes
Forme simplifies adding custom, ajax and rest routes, via the Router
class and the routes/routes.php
file.
You can use the Router::map
static method, which has the following signature:
Router::map(string $route, callable $handler, string $type = "custom", string $method = null);
The handler is a callable, therefore can be a closure, a function name, a controller class name which should implement __invoke
, or an array in the form ['class', 'method']
. This will receive a request object, a PSR 7 Request in the form of a Forme\Framework\Http\ServerRequest
.
You can also use convenience methods for the different http methods.
Router::get(string $route, callable $handler, string $type = "custom");
Router::post(string $route, callable $handler, string $type = "custom");
Router::put(string $route, callable $handler, string $type = "custom");
Router::patch(string $route, callable $handler, string $type = "custom");
Router::delete(string $route, callable $handler, string $type = "custom");
Custom Routes
For custom routes, the syntax is identical to upstatement/routes which is the library that Timber uses.
The route parameter sets a pattern for routes to match on, by default everything is handled as a string. Any segment that begins with a :
is handled as an argument and passed into the handler via the request.
The request object is a Forme\Framework\Http\ServerRequest
with the url params added to its query params. For convenience, these url params can be accessed via array syntax along with any query or body params.
// routes/routes.php
use Forme\Framework\Core\Router;
use Forme\Framework\Http\ServerRequest;
// Closure
Router::get('foo/:bar', function(ServerRequest $request){
echo "Value of bar is " . esc_html($request['bar']);
});
// Named function, args will be passed into it
Router::get('foo/:bar', 'myFunction');
// Ad hoc class, args will be passed into the specified method
Router::get('foo/:bar', ['NameSpace\\YourApp\\MyService', 'myMethod']);
Closures are useful for testing and debugging but most commonly, you'll want to point your route to a controller.
// routes/routes.php
use \Forme\Framework\Core\Router;
// Controller, `Forme\Framework\Http\ServerRequest` will be injected into its __invoke method
Router::post('foo/:bar', 'NameSpace\\YourApp\\FooController');
TIP
You can leave out the type, unless you're using map
with an HTTP method other than GET
Ajax Routes
For ajax routes, everything behaves as per the custom route, except:
- the route parameter here should be a string representing the snake cased method name.
- you need to add "ajax-public" or "ajax-private" as the type parameter.
- the request object will not hoist any url params into the query params.
// routes/routes.php
use \Forme\Framework\Core\Router;
Router::post('my_ajax_method', ['NameSpace\\YourApp\\AjaxMethodController'], 'ajax-private');
TIP
WordPress ajax routes are always POST. Any other method will throw an exception.
TIP
As per standard WordPress, you'll need to take care of passing ajaxurl
into the frontend for public ajax endpoints yourself.
WARNING
WordPress counterintuitive oddness: public ajax routes will not work at all for logged in users!
REST Routes
For REST routes, everything behaves as per the custom routes, except:
- The route parameter represents the namespace string plus the route regex string you would normally pass to
register_rest_route
in standard WordPress. - you need to add "rest" as the type parameter
// routes/routes.php
use \Forme\Framework\Core\Router;
Router::put('namespace/foo/(?P<bar>\d+)', 'NameSpace\\YourApp\\RestController', 'rest');
The request object will be a PSR-7 compatible request based on the underlying WP_REST_Request
object
Limitations
- The Router will assume that the first segment of your route parameter path is the namespace. This means it can't handle anything more complicated e.g. versioning.
Authentication and Middleware
In order to protect your endpoints or to perform other route level tasks, you'll need to use PSR 15 middleware. You can also check Forme's Api Token implementation.