{"id":19450889,"url":"https://github.com/morning-train/wp-route","last_synced_at":"2025-04-25T03:32:10.614Z","repository":{"id":41299224,"uuid":"509078307","full_name":"Morning-Train/wp-route","owner":"Morning-Train","description":"A simple route service for WordPress","archived":false,"fork":false,"pushed_at":"2023-03-28T10:23:08.000Z","size":133,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T19:05:30.383Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Morning-Train.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-30T12:49:49.000Z","updated_at":"2023-12-04T12:31:40.000Z","dependencies_parsed_at":"2024-11-10T16:40:51.585Z","dependency_job_id":"b4a016a5-9cf6-458d-95b6-c47eff8add23","html_url":"https://github.com/Morning-Train/wp-route","commit_stats":{"total_commits":73,"total_committers":2,"mean_commits":36.5,"dds":0.1643835616438356,"last_synced_commit":"f583cb238344103efb5d5a73f99e90946d2aa25d"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morning-Train%2Fwp-route","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morning-Train%2Fwp-route/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morning-Train%2Fwp-route/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morning-Train%2Fwp-route/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Morning-Train","download_url":"https://codeload.github.com/Morning-Train/wp-route/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250748107,"owners_count":21480778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T16:39:21.862Z","updated_at":"2025-04-25T03:32:10.274Z","avatar_url":"https://github.com/Morning-Train.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WP Route\n\nA Route Service for WordPress that uses the WordPress rewrite engine and adds Laravel syntax to it.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Getting Started](#getting-started)\n    - [Installation](#installation)\n- [Dependencies](#dependencies)\n    - [morningtrain/php-loader](#morningtrainphp-loader)\n    - [illuminate/pipeline](#illuminatepipeline)\n    - [Symfony HTTP Foundation](#symfony-http-foundation)\n- [Usage](#usage)\n    - [Setup](#setup)\n    - [Adding a route](#adding-a-route)\n    - [A route with arguments](#a-route-with-arguments)\n    - [Using named routes](#using-named-routes)\n    - [Grouping Routes](#grouping-routes)\n    - [Accessing WP Query Vars](#accessing-wp-query-vars)\n- [Middleware](#middleware)\n    - [A quick example](#a-quick-example)\n- [REST](#rest)\n    - [Options](#options)\n    - [Public](#public)\n    - [Expose](#expose)\n    - [Changing the namespace](#changing-the-namespace)\n- [Credits](#credits)\n- [Testing](#testing)\n- [License](#license)\n\n## Introduction\n\nA Route is an address or endpoint in the application. Routes are defined in the `/routes` directory of your project,\nunless otherwise specified.\n\nAll files in this directory are loaded by the framework while it is booting up.\n\nNote that the Route API imitates [Laravel Route](https://laravel.com/docs/routing)\n\nRoutes MUST call a Controller as callback!\n\n## Getting Started\n\nTo get started install the package as described below in [Installation](#installation).\n\nTo use the tool have a look at [Usage](#usage)\n\n### Installation\n\nInstall with composer\n\n```bash\ncomposer require morningtrain/wp-route\n```\n\n## Dependencies\n\n### morningtrain/php-loader\n\n[PHP Loader](https://github.com/Morning-Train/php-loader) is used to load and initialize all Hooks\n\n### illuminate/pipeline\n\n[Illuminate Pipeline](https://packagist.org/packages/illuminate/pipeline)\n\n### Symfony HTTP Foundation\n\n[Symfony Http Foundation](https://symfony.com/doc/current/components/http_foundation.html)\n\n## Usage\n\n### Setup\n\nInitialize the package with `Route::setup($path)` or, if the package is already initialized, load a directory of routes\nwith `Route::loadDir($path)`\n\n```php\nuse Morningtrain\\WP\\Route\\Route;\n\nRoute::setup(__DIR__ . '/routes');\n```\n\n### Adding a route\n\n```php\n// /routes/myroute.php\nuse \\Morningtrain\\WP\\Facades\\Route;\n\n// Set up a route on the /myroute URL and call MyrouteController::myRoute as callback\nRoute::get('/myroute','MyrouteController::myRoute');\n\n// /Controllers/MyrouteController.php\nclass MyrouteController extends \\Morningtrain\\WP\\Route\\Abstracts\\AbstractController{\n    public static function myRoute(){\n        // Validate request \u0026 send http status code\n        // Fetch data\n        // Render view\n    }\n}\n```\n\n### A route with arguments\n\n```php\n// /routes/kittens.php\nuse \\Morningtrain\\WP\\Facades\\Route;\n\n// Set up a route on the /kitten/1 URL and call KittenController::kittenById as callback\nRoute::get('/kitten/{kitten_id}','KittenController::kittenById');\n\n// /Controllers/KittenController.php\nclass KittenController extends \\Morningtrain\\WP\\Route\\Abstracts\\AbstractController{\n    public static function kittenById(\\Symfony\\Component\\HttpFoundation\\Request $request){\n        // Validate request \u0026 send http status code\n        // Fetch data\n        $kitten_id = $request-\u003equery-\u003eget('kitten_id');\n        // Render view\n    }\n}\n```\n\n### Using named routes\n\n```php\n// /routes/kittens.php\nuse \\Morningtrain\\WP\\Facades\\Route;\n\n// Set up a route on the /kitten/1 URL and call KittenController::kitten as callback\nRoute::get('/kitten/{kitten_id}','KittenController::kitten')-\u003ename('kitten');\n\n// /Controllers/KittenController.php\nclass KittenController extends \\Morningtrain\\WP\\Route\\Abstracts\\AbstractController{\n    public static function kitten(\\Symfony\\Component\\HttpFoundation\\Request $request){\n        // Validate request \u0026 send http status code\n        // Fetch data\n        $kitten_id = $request-\u003equery-\u003eget('kitten_id');\n        // Render view\n    }\n}\n\n// In some template or hook you can now get and check for the named route\n// Get Url for Kittens Route\n$url = Route::route('kittens',['kitten_id' =\u003e 1]); // Would return /kitten/1\n// Check if currently on kitten route\n$bool = Route::current()-\u003egetName() === 'kitten';\n```\n\n### Grouping Routes\n\nYou may group a set of routes to apply a shared prefix to all of them or to apply shared middleware.\n\n#### With prefix\n\n```php\nuse \\Morningtrain\\WP\\Facades\\Route;\nRoute::prefix('my-prefix')-\u003egroup(function(){\n    Route::get('foo',FooController::class); // url will be /my-prefix/foo\n    Route::get('bar',BarController::class); // url will be /my-prefix/bar\n})\n```\n\n#### With middleware\n\n```php\nuse \\Morningtrain\\WP\\Facades\\Route;\n// Users must now be logged in to view these two routes\nRoute::middleware('auth')-\u003egroup(function(){\n    Route::get('foo',FooController::class);\n    Route::get('bar',BarController::class);\n})\n```\n\n#### With both prefix and middleware\n\n```php\nuse \\Morningtrain\\WP\\Facades\\Route;\nRoute::prefix('my-prefix')\n-\u003emiddleware('auth')\n-\u003egroup(function(){\n    Route::get('foo',FooController::class);\n    Route::get('bar',BarController::class);\n})\n```\n\n### Accessing WP Query Vars\n\nWordPress query vars are added to the Request class as query data. So you can access them like so:\n\n```php\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n// Controller\nclass FooController extends \\Morningtrain\\WP\\Route\\Abstracts\\AbstractController{\n    public function __invoke(Request $request){\n        // Do something here\n        $post = $request-\u003equery-\u003eget('post');\n    }\n}\n// Middleware\nfunction(Request $request, $next){\n    if($request-\u003equery-\u003ehas('post')){\n        // Do something here\n        $post = $request-\u003equery-\u003eget('post');\n    }\n    return $next($request);\n}\n```\n\n### Middleware\n\nMiddleware are functions called for a route after it has been matched against a url, but before its callback is called.\n\nMiddleware are useful for validating a group of routes, validating a users permissions or hijacking a request.\n\nRead more about them here: [Laravel Docs - Middleware](https://laravel.com/docs/middleware)\n\n#### A quick example\n\nMiddleware are function that receive a request object and a closure that represents the next middleware in the pipeline.\nIt is important to always `return $next($request);` at the end of a valid middleware.\n\nIn the example below we create a middleware that stops the pipeline if the current user is not logged in and returns a\nresponse with status 404. If the user is logged in the middleware pipeline continues and eventually lets the route call\nits controller.\n\nA middleware is allowed to either continue the pipeline, return a Response or throw an exception. Responses must\nbe `\\Symfony\\Component\\HttpFoundation\\Response` and will be sent automatically. Exceptions are caught and converted into\ncustom `\\Morningtrain\\WP\\Route\\Responses\\WPErrorResponse` that are then displayed using `wp_die()`\n\n```php\nuse Morningtrain\\WP\\Facades\\Route;\nuse \\Symfony\\Component\\HttpFoundation\\Request;\nRoute::middleware([function(Request $request, $next){\n    if(!\\is_user_logged_in()){\n        // Returns a Response object\n        return \\Morningtrain\\WP\\Route\\Classes\\Response::with404();    \n    }\n    // Continues the middleware pipeline\n    return $next($request);\n}])\n-\u003egroup(function(){\n    Route::get('my-account',MyAccountController::class);\n});\n```\n\n### Rest\n\nYou can also register rest endpoints using the same syntax! Behind the scenes all Rest routes are registered\nusing [register_rest_route](https://developer.wordpress.org/reference/functions/register_rest_route/)\n\n```php\nuse Morningtrain\\WP\\Facades\\Rest;\n\nRest::get('products', [ProductRestController::class, 'getAllProducts'])-\u003epublic(); // Will register an endpoint like /wp-json/mtwp/v1/products that accepts GET requests\n\n```\n\n#### Options\n\nYou can use middleware, prefix, groups and names on Rest routes the same way as you can on rewrite routes!!\n\n**Note:** Middleware is applied AFTER WordPress has identified the route and passed through all other verifications such\nas `permission_callback`, but before the controller or supplied callback is called.\n\n##### Public\n\nTo make an endpoint public chain `public()` on either the route or its group. This simply sets the `permission_callback`\nto `__return_true`. This defaults to `__return_false`.\n\n##### Expose\n\nYou can expose the endpoint URL to the DOM by chaining `expose()` onto the route or its group. This outputs the url to a\nJavaScript object similar to the\nway [localize_script](https://developer.wordpress.org/reference/functions/wp_localize_script/) would.\n\nThe exposed url can be accessed like so:\n\n```js\nconst fooEndpointUrl = window.mtwpRestRoutes.foo; // /wp-json/mtwp/v1/foo\n```\n\n**Note:** to expose an endpoint it has to be named.\n\n##### Changing the namespace\n\nYou can set the namespace the same way you would a prefix.\n\n```php\nuse Morningtrain\\WP\\Facades\\Rest;\n\nRest::namespace('foo/v1')-\u003egroup(function(){\n    Rest::get('foo',FooController::class); // /wp-json/foo/v1/foo\n});\n```\n\nThis can be combined with prefixes\n\n```php\nuse Morningtrain\\WP\\Facades\\Rest;\n\nRest::namespace('foo/v1')-\u003eprefix('bar')-\u003egroup(function(){\n    Rest::get('foo',FooController::class); // /wp-json/foo/bar/v1/foo\n});\n\n// -- or --\n\nRest::namespace('foo/v1')-\u003egroup(function(){\n    Rest::prefix('bar')-\u003egroup(function(){\n        Rest::get('foo',FooController::class); // /wp-json/foo/bar/v1/foo\n        Rest::get('baz',FooController::class); // /wp-json/foo/bar/v1/baz\n    });\n});\n```\n\n## Credits\n\n- [Mathias Munk](https://github.com/mrmoeg)\n- [All Contributors](../../contributors)\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorning-train%2Fwp-route","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorning-train%2Fwp-route","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorning-train%2Fwp-route/lists"}