Last active
March 11, 2017 01:23
-
-
Save zacscott/ec58555e5f3dc9ab651260a07e12b938 to your computer and use it in GitHub Desktop.
Simple one file router for WordPress (can be used as a mu-plugin)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Plugin Name: Routes for WordPress | |
* Description: Routes class provider plugin | |
* Version: 2.0 | |
* Author: Zachary Scott | |
*/ | |
namespace zacscott; | |
/** | |
* Utility to build custom routes within WordPress. Routes are defined as | |
* regular expressions and pass defined arguments to the callback function. | |
* | |
* Example of setting up a route: | |
* | |
* Routes::add( array( | |
* 'regex' => '^myroute/([0-9]+)/?$', | |
* 'callback' => array( $this, 'my_route_callback' ) | |
* ) ); | |
* | |
* The callback would then look like the following: | |
* | |
* function my_route_callback( $id ) { | |
* // Do things here | |
* } | |
* | |
* @version 2.0 | |
* @author Zachary Scott <[email protected]> | |
*/ | |
class Routes { | |
// the registered routes | |
private static $routes = array( ); | |
// whether the setup() method has been called yet | |
private static $is_setup = false; | |
/** | |
* Registers a new route. | |
* | |
* @param $regex string The regular expression to match the route path. Can contain groups which are passed as | |
* params to the callback. | |
* @param $callback function Callback for when the route is triggered | |
*/ | |
public static function add( $args ) { | |
assert( ! empty( $args ) ); | |
self::setup(); | |
// Set defaults so stuff does not break | |
$args = array_merge( array( | |
'regex' => '', | |
'callback' => array(), | |
'title' => '', | |
), $args ); | |
// Add to the list of routes | |
if ( ! empty( $args['regex'] ) && ! empty( $args[ 'callback' ] ) ) { | |
self::$routes[] = $args; | |
} | |
} | |
// Sets up the routing system | |
static function setup() { | |
// Only setup once | |
if ( self::$is_setup ) { | |
return; | |
} | |
// Register the setup class | |
add_filter( 'do_parse_request', array( __CLASS__, 'handle_routes' ), 1, 3 ); | |
} | |
// Handles routing on 'do_parse_request' | |
static function handle_routes( $continue, $wp, $extra_query_vars ) { | |
// Get the request path / URI | |
$request_path = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : ''; | |
$request_path = trim( $request_path, '/' ); | |
$request_path = strtok( $request_path, '?' ); | |
// Regsiter each of the routes | |
foreach ( self::$routes as $route ) { | |
$regex = $route['regex']; | |
$callback = $route['callback']; | |
// Regex the request path | |
$matches = array(); | |
$match = preg_match( '{' . $regex .'}', $request_path, $matches ); | |
// Dispatch route if a hit | |
if ( ! empty( $matches ) ) { | |
// Set title if one was provided | |
$route_title = $route['title']; | |
add_filter( 'wp_title', function( $title, $sep, $seplocation ) use ( $route_title ) { | |
$title = $route_title; | |
$site_title = get_bloginfo( 'name' ); | |
// Grab the separate from Yoast if defined | |
if ( function_exists( 'wpseo_replace_vars' ) ) { | |
$sep = wpseo_replace_vars( '%%sep%%', array() ); | |
} | |
// Build the title string, basedo nthe separator | |
if ( $seplocation == 'right' ) { | |
$title = "{$title} {$sep} {$site_title}"; | |
} else { | |
$title = "{$site_title} {$sep} {$title}"; | |
} | |
return $title; | |
}, 10, 3 ); | |
array_shift( $matches ); | |
call_user_func_array( $callback, $matches ); | |
exit; | |
} | |
} | |
// No matching route found, fallback to WordPress | |
return $continue; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment