{"id":37236651,"url":"https://github.com/web-love/wp-router","last_synced_at":"2026-01-16T04:53:42.025Z","repository":{"id":57079011,"uuid":"253301187","full_name":"web-love/wp-router","owner":"web-love","description":"A Worpress REST api router inspired from ExpressJs.","archived":false,"fork":false,"pushed_at":"2020-05-24T20:44:12.000Z","size":53,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-02T19:23:21.877Z","etag":null,"topics":["easy","express","expressjs","middleware","php","router","simple","wordpress"],"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/web-love.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-05T18:13:51.000Z","updated_at":"2024-05-30T00:43:38.000Z","dependencies_parsed_at":"2022-08-24T13:10:50.368Z","dependency_job_id":null,"html_url":"https://github.com/web-love/wp-router","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/web-love/wp-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web-love%2Fwp-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web-love%2Fwp-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web-love%2Fwp-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web-love%2Fwp-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/web-love","download_url":"https://codeload.github.com/web-love/wp-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/web-love%2Fwp-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420814,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["easy","express","expressjs","middleware","php","router","simple","wordpress"],"created_at":"2026-01-15T04:16:03.369Z","updated_at":"2026-01-15T04:16:04.280Z","avatar_url":"https://github.com/web-love.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Wordpress router logo](https://i.ibb.co/nsRzTxx/wp-router-3.png)\n\n# Wordpress REST API router library \n![MIT license](https://img.shields.io/packagist/l/weblove/wp-router)\n![size](https://img.shields.io/github/languages/code-size/web-love/wp-router)\n![version](https://img.shields.io/github/v/release/web-love/wp-router)\n![open issues](https://img.shields.io/github/issues/web-love/wp-router)\n\nEasily write modern and reusable route middlewares for your Wordpress projects and plugins. WPRouter is inspired from the excellent [expressJs](https://expressjs.com/fr/) javascript framework. Working with Wordpress REST API will now bring you joy - instead of pain.\n\n* Hook on already existing Wordpress REST endpoints.\n* Creating your own endpoints is a breeze.\n* Works with custom post types.\n* Simplifies the Wordpress route regex notation for simpler `/ressource/:ressource_slug` urls.\n* No dependencies, less than 400locs that simply abstract Wordpress core. \n\n**See on:**\n* [Packagist](https://packagist.org/packages/weblove/wp-router)\n* [Github](https://github.com/sudomaxime/wp-router)\n\n## Getting started\nYou need to have [Composer](https://getcomposer.org/) installed on your machine, [follow this link](https://getcomposer.org/doc/00-intro.md) for instructions on how to install Composer.\n\n### Prerequisites\n* You need to have PHP \u003e= 7.0\n* Wordpress \u003e= 4.7.1\n\n### Installing\nThe best way to install this library is with composer:\n```bash\n$ composer require weblove/wp-router\n```\n\n### Basic example\n```php\n$router = new Weblove\\WPRouter\\Router;\n\n$router-\u003eget(\"/meme/:id\", function ($request, $response) { \n  $params = $request-\u003eget_url_params();\n  $the_meme = get_meme_by_id($params[\"id\"]);\n  $response[\"body\"] = $the_meme;\n  return $response;\n});\n```\n\nThe `$request` function param implements Wordpress [WP_REST_Request](https://developer.wordpress.org/reference/classes/wp_rest_request/) class. The `$response` param is an empty variable that can be used to pass data to the next middleware down the chain, or to send back data on your endpoint.\n\n### Creating your first middleware\nCreating a middleware is a breeze. Create an anonymous function with `$request` and `$response` as parameters. A middleware custom middleware can return any type of data that is JSON serializable or an instance of [WP_REST_Request](https://developer.wordpress.org/reference/classes/wp_rest_request/)\n\n```php\n$myCustomMiddleware = function ($req, $res) {\n  $potato_id = $req-\u003eget_param(\"id\");\n  $res[\"potato\"] = get_potato($potato_id);\n\n  return $res;\n};\n```\n\n### Returning early\nIf you want to break your request early, you can return an instance of [WP_REST_Request](https://developer.wordpress.org/reference/classes/wp_rest_request/) as a response and the router will block executing subsequent middlewares and return that response. This can be very useful to send back errors to the API:\n\n```php\n$myCustomAuthMiddleware = function ($req, $res) {\n  $can_touch_this = user_can_touch_this();\n  \n  if (!$can_touch_this) {\n    return new WP_REST_Response(\"Can't touch this\", 403);\n  }\n\n  return $res;\n};\n```\n\n### Chaining middlewares\nJust like expressJS, you can chain middlewares one after the other. The Router methods can take many functions as parameters. The `$response` body is simply passed to the next middleware down the chain. You can use this pattern to isolate logic in small and easy to test functions that have a single purpose:\n\n```php\n$router-\u003eget(\"/meme/:id/category\", \n  function ($req, $res) \n  { \n    $params = $req-\u003eget_url_params();\n    $the_meme = get_meme_by_id($params[\"id\"]);\n    $res[\"body\"] = $the_meme;\n    return $res;\n  },\n  function ($req, $res)\n  {\n    $meme_category_id = $res[\"body\"][\"category\"][\"id\"];\n    $meme_category_infos = get_meme_cat_infos($meme_category_id);\n    $res[\"body\"] = $meme_category_infos;\n    return $res;\n  }\n);\n```\n\n### Hook on an existing wordpress REST endpoint\nYou can also modify the response body of an existing wordpress endpoint with the `public hook()` method. Middlewares added to the `hook` handler will have a pre-filled `$response` parameter with the array that Wordpress would normally return to the client. You can easily modify the response before returning. \n\nA hook request **MUST** end with a [WP_REST_Response](https://developer.wordpress.org/reference/classes/wp_rest_response/) class, it is possible to pass custom `$request` objects from middleware to middleware, however your last middleware (or your early breaks) must always be an instance of `WP_REST_Request`. This way you make certain that other plugins that interops with the REST API will keep working properly.\n\nnote: *You do not need to put /wp-json in your endpoint address.*\n\n```php\n$router-\u003ehook('GET', '/wp/v2/posts/:id', \n  $authMiddleware,\n  $responseMiddleware // this function ends by returning an instance of WP_REST_Response\n);\n```\n\n### Customize the default directory\nBy default your routes get added under the `/wp-json/api` directory. You can change the default behavior by providing a router parameter to the `Router` class:\n\n```php\n$router = new Weblove\\WPRouter\\Router; // defaults to /wp-json/api\n$router = new Weblove\\WPRouter\\Router(\"custom\"); // now set to /wp-json/custom\n```\n\n### Public methods\n* `get(string $endpoint, middleware ...$middleware)`\n* `post(string $endpoint, middleware ...$middleware)`\n* `put(string $endpoint, middleware ...$middleware)`\n* `delete(string $endpoint, middleware ...$middleware)`\n* `patch(string $endpoint, middleware ...$middleware)`\n* `hook(string $method_verb, string $endpoint, middleware ...$middleware)`  - Use an already existing Wordpress endpoint.\n* **In development** `use(string $endpoint, middleware ...$middleware)` - Use middlewares on all verbs of that endpoint.\n\n### Troubleshooting and frequent errors\n* My endpoint is returning an error `Uncaught Error: Call to a member function get_matched_route()` - This means you have a hook that doesn't return an instance of WP_REST_Response after all the middlewares have been executed. See this guide section on how to properly hook on existing wordpress endpoints.\n\n## Authors\n* Maxime Nadeau - *initial work* - [Weblove](http://weblove.ca)\n\n## License\nThis project is licensed under the MIT License - see the license.md file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweb-love%2Fwp-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fweb-love%2Fwp-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fweb-love%2Fwp-router/lists"}