-
-
Save samhernandez/8062848 to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * NOTE: This gist is very old. You might want to check out recent forks | |
| * like this one: https://github.com/Alexlytle/Wordpress_custom_route/blob/main/Wordpress_Custom_route.php | |
| * (thanks @Alexlytle) If you have an improvement to this gist, please | |
| * post a link in a comment for others who might benefit. Thanks! | |
| * | |
| * A class to create simple custom routes. | |
| * | |
| * Example usage: | |
| * | |
| * $theme_routes = new CustomRoutes(); | |
| * $theme_routes->addRoute( | |
| * | |
| * // required, regex to match the route | |
| * '^api/([^/]*)/([^/]*)/?', | |
| * | |
| * // required, a callback function name or | |
| * // callable array like `array($object, 'method')` | |
| * 'api_callback', | |
| * | |
| * // optional template path or array of template path candidates | |
| * get_template_directory() . '/api-template.php', | |
| * | |
| * // query vars based on regex matches | |
| * // will be passed to the callback function in the same order | |
| * array($param1 => 1, $param2 => 2), | |
| * ); | |
| * | |
| * function api_callback($param1, $param2) { | |
| * // called before the optional template is invoked | |
| * } | |
| * | |
| * Also: | |
| * | |
| * // Force flush rewrite rules. | |
| * $theme_routes->forceFlush(); | |
| * | |
| * @author Sam Hernandez ([email protected]) | |
| */ | |
| class CustomRoutes { | |
| /** | |
| * An array of route data indexed by regex. | |
| * | |
| * Example value: | |
| * | |
| * $routes['^widgets/([^/]*)/([^/]*)/?'] = array( | |
| * 'callback' => 'some_function', // or array($object, 'someMethod') | |
| * 'template' => '/template/path/to/file.php', | |
| * 'query_vars' => array('param1' => 1, 'param2' => 2) | |
| * ); | |
| * | |
| * @var array | |
| */ | |
| protected $routes = array(); | |
| /** | |
| * Flag to force flushing existing rewrite rules. | |
| * @var boolean | |
| */ | |
| protected $force_flush = false; | |
| /** | |
| * Constructor | |
| */ | |
| public function __construct() | |
| { | |
| add_action('parse_request', array($this, 'parseRequestAction')); | |
| add_filter('query_vars', array($this, 'queryVarsFilter')); | |
| add_filter('rewrite_rules_array', array($this, 'rewriteRulesArrayFilter')); | |
| add_action('wp_loaded', array($this, 'wpLoadedAction')); | |
| } | |
| /* | |
| * | |
| * Public methods | |
| * | |
| */ | |
| /** | |
| * Force flush existing rewrite rules. | |
| */ | |
| public function forceFlush() { | |
| $this->force_flush = true; | |
| } | |
| /** | |
| * Action callback for 'parse_request'. Handles the execution | |
| * of custom routes by invoking the optional callback and optional | |
| * template file if they are given for the matched route. | |
| * | |
| * @param WP $query | |
| */ | |
| public function parseRequestAction($query) | |
| { | |
| if ($query->matched_rule and isset($this->routes[$query->matched_rule])) | |
| { | |
| $route = $this->routes[$query->matched_rule]; | |
| $this->doCallback($route, $query); | |
| if ($route['template']) { | |
| $html = $this->doTemplate($route); | |
| } | |
| exit; | |
| } | |
| } | |
| /** | |
| * Add a route with params. | |
| * | |
| * @param string $match A regular expression for the url match | |
| * @param string $callback Callback; function name or callable array such as `array($object, 'method')` | |
| * @param string $template Optional template path | |
| * @param array $query_vars An array of url query vars indexed by the var name, value being the regex match number. | |
| */ | |
| public function addRoute($match, $callback, $template = null, $query_vars = array()) | |
| { | |
| $this->routes[$match] = compact('callback', 'template', 'query_vars'); | |
| } | |
| /* | |
| * | |
| * Action and filter callbacks | |
| * | |
| */ | |
| /** | |
| * Action callback for 'wp_loaded'. | |
| * Flushes the current rewrite rules if a newly defined rule | |
| * is missing or if the `$force_flush` flag is raised. | |
| */ | |
| public function wpLoadedAction() | |
| { | |
| $rules = get_option('rewrite_rules'); | |
| $missing_routes = false; | |
| foreach ($this->routes as $key => $value) { | |
| $missing_routes += !isset($rules[$key]); | |
| } | |
| if ($missing_routes || $this->force_flush) { | |
| global $wp_rewrite; | |
| $wp_rewrite->flush_rules(); | |
| } | |
| } | |
| /** | |
| * Filter callback for 'rewrite_rules_array'. | |
| * Adds new rules for newly defined routes. | |
| * | |
| * @param array $rules | |
| * @return array | |
| */ | |
| public function rewriteRulesArrayFilter($rules) | |
| { | |
| $newrules = array(); | |
| foreach ($this->routes as $match => $route) { | |
| $newrules[$match] = $this->makeRuleUrl($route); | |
| } | |
| return $newrules + $rules; | |
| } | |
| /** | |
| * Filter callback for 'query_vars'. | |
| * @param array $vars | |
| * @return array | |
| */ | |
| public function queryVarsFilter($vars) | |
| { | |
| foreach($this->routes as $route) | |
| { | |
| foreach($route['query_vars'] as $key => $value) { | |
| $vars[] = $key; | |
| } | |
| } | |
| return $vars; | |
| } | |
| /* | |
| * | |
| * Protected methods | |
| * | |
| */ | |
| /** | |
| * Invoke the callback for a given route. | |
| * | |
| * @param array $route An item from $this->routes | |
| * @param WP $query | |
| */ | |
| protected function doCallback($route, $query) | |
| { | |
| $params = array(); | |
| // params are in the same order as given in the array | |
| foreach($route['query_vars'] as $name => $match) { | |
| $params[] = $query->query_vars[$name]; | |
| } | |
| call_user_func_array($route['callback'], $params); | |
| } | |
| /** | |
| * Includes a template for a given route if one is found. | |
| * @param array $route An item from $this->routes | |
| */ | |
| protected function doTemplate($route) | |
| { | |
| $candidates = (array) $route['template']; | |
| foreach($candidates as $candidate) | |
| { | |
| if (file_exists($candidate)) | |
| { | |
| include $candidate; | |
| break; | |
| } | |
| } | |
| } | |
| /** | |
| * Returns a url with query string key/value pairs as | |
| * needed for rewrite rules. | |
| * | |
| * @param array $route An item from $this->routes | |
| * @return string | |
| */ | |
| protected function makeRuleUrl($route) | |
| { | |
| $q_vars = array(); | |
| foreach($route['query_vars'] as $name => $match) { | |
| $q_vars[] = $name . '=$matches[' . $match . ']'; | |
| } | |
| return 'index.php?' . implode('&', $q_vars); | |
| } | |
| } |
Worked it out. Needed to set them in my api_callback()
set_query_var('param1', $param1);
Hi! Thanks for this very nice class for custom GET routes, I used it many times!
To create API endpoints with the other REST methods, it's possible to combine the rest_url_prefix hook filter and the WP_REST_Server::register_route method.
First, customize the REST API prefix to match what you want, /api for example :
add_filter('rest_url_prefix', 'loomis_rest_url_prefix');
function loomis_rest_url_prefix( $slug ) {
return 'api';
}
And finally add your routes without namespace by passing them directly to the WP_REST_Server instance :
add_action('rest_api_init', function($server){
$server->register_route('myendpoint', '/myendpoint', [
'methods' => 'POST',
'callback' => 'my_callback_action',
]);
});
This will add /api/myendpoint POST route to native REST API.
Thank you so much this will completely change my work flow
How can I view the query_vars in the template:
My code:
// new route $theme_routes = new CustomRoutes(); $theme_routes->addRoute( "^parent/([^/]*)/?", [$this, 'api_callback'], get_stylesheet_directory() . '/parent-template.blade.php', array('param1' => 1, 'param2' => 2,) );in my parent-template.blade.php I get null from
global $wp_query; var_dump($wp_query->query_vars);Bit stumped - any ideas? Thanks for useful class!
Worked it out. Needed to set them in my api_callback()
set_query_var('param1', $param1);
Thank you for the api call back of setting a query he should of put this in the example comment
They only problem with this is that it hides the admin on the routes being used
@Alexlytle I am so sorry, I wish I could help, but I haven't done any WordPress work since I published this gist 8 years ago and I'm not familiar with it any more. If you have any improvements, I'm happy to publish them here or to link to a gist that you publish.
@samhernandez samhernandez
Oh wow no problem. I didn't realize it was so long ago
Here is a link to my GitHub of a updated version of this class!
https://github.com/Alexlytle/Wordpress_custom_route/blob/main/Wordpress_Custom_route.php
@Alexlytle thanks for the link! I updated the gist with a comment at the top.
If anyone else has an improvement please post a link to your work.
How can I view the query_vars in the template:
My code:
in my parent-template.blade.php I get null from
Bit stumped - any ideas? Thanks for useful class!