jbrinley / wp-router Goto Github PK
View Code? Open in Web Editor NEWRoutes paths to callback functions in WordPress
Routes paths to callback functions in WordPress
=== WP Router === Contributors: jbrinley Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A69NZPKWGB6H2 Tags: URL mapping, callback functions Requires at least: 3.0 Tested up to: 5.2.4 Stable tag: trunk Provides a simple API for mapping requests to callback functions. == Description == WordPress's rewrite rules and query variables provide a powerful system for mapping URL strings to collections of posts. Every request is parsed into query variables and turned into a SQL query via `$wp_query->query()`. Sometimes, though, you don't want to display a list of posts. You just want a URL to map to a callback function, with the output displayed in place of posts in whatever theme you happen to be using. That's where WP Router comes in. It handles all the messy bits of registering post types, query variables, rewrite rules, etc., and lets you write code to do what you want it to do. One function call is all it takes to map a URL to your designated callback function and display the return value in the page. Created by [Flightless](http://flightless.us) == Installation == 1. Download and unzip the plugin 1. Upload the `WP-Router` folder to the `/wp-content/plugins/` directory 1. Activate the plugin through the 'Plugins' menu in WordPress 1. You should see the sample page at http://example.org/wp_router/sample/. Apart from that, there is no public UI for this plugin. You will not see any changes unless the plugin's API is called by another active plugin. == Usage == = Creating Routes = * Your plugin should hook into the `wp_router_generate_routes` action. The callback should take one argument, a `WP_Router` object. * Register a route and its callback using `WP_Router::add_route( $id, $args )` * `$id` is a unique string your plugin should use to identify the route * `$args` is an associative array, that sets the following properties for your route. Any omitted argument will use the default value. * `path` (required) - A regular expression to match against the request path. This corresponds to the array key you would use when creating rewrite rules for WordPress. * `query_vars` - An associative array, with the keys being query vars, and the values being explicit strings or integers corresponding to matches in the path regexp. Any query variables included here will be automatically registered. * `title` - The title of the page. * `title_callback` - A callback to use for dynamically generating the title. Defaults to `__()`. If `NULL`, the `title` argument will be used as-is. if `page_callback` or `access_callback` returns `FALSE`, `title_callback` will not be called. `title_callback` can be either a single callback function or an array specifying callback functions for specific HTTP methods (e.g., `GET`, `POST`, `PUT`, `DELETE`, etc.). If the latter, the `default` key will be used if no other keys match the current request method. * `title_arguments` - An array of query variables whose values will be passed as arguments to `title_callback`. Defaults to the value of `title`. If an argument is not a registered query variable, it will be passed as-is. * `page_callback` (required) - A callback to use for dynamically generating the contents of the page. The callback should either echo or return the contents of the page (if both, the returned value will be appended to the echoed value). If `FALSE` is returned, nothing will be output, and control of the page contents will be handed back to WordPress. The callback will be called during the `parse_request` phase of WordPress's page load. If `access_callback` returns `FALSE`, `page_callback` will not be called. `page_callback` can be either a single callback function or an array specifying callback functions for specific HTTP methods (e.g., `GET`, `POST`, `PUT`, `DELETE`, etc.). If the latter, the `default` key will be used if no other keys match the current request method. * `page_arguments` - An array of query variables whose values will be passed as arguments to `page_callback`. If an argument is not a registered query variable, it will be passed as-is. * `access_callback` - A callback to determine if the user has permission to access this page. If `access_arguments` is provided, default is `current_user_can`, otherwise default is `TRUE`. If the callback returns `FALSE`, anonymous users are redirected to the login page, authenticated users get a 403 error. `access_callback` can be either a single callback function or an array specifying callback functions for specific HTTP methods (e.g., `GET`, `POST`, `PUT`, `DELETE`, etc.). If the latter, the `default` key will be used if no other keys match the current request method. * `access_arguments` - An array of query variables whose values will be passed as arguments to `access_callback`. If an argument is not a registered query variable, it will be passed as-is. * `template` - An array of templates that can be used to display the page. If a path is absolute, it will be used as-is; relative paths allow for overrides by the theme. The string `$id` will be replaced with the ID of the route. If no template is found, fallback templates are (in this order): `route-$id.php`, `route.php`, `page-$id.php`, `page.php`, `index.php`. If FALSE is given instead of an array, the page contents will be printed before calling `exit()` (you can also accomplish this by printing your output and exiting directly from your callback function). Example: `$router->add_route('wp-router-sample', array( 'path' => '^wp_router/(.*?)$', 'query_vars' => array( 'sample_argument' => 1, ), 'page_callback' => array(get_class(), 'sample_callback'), 'page_arguments' => array('sample_argument'), 'access_callback' => TRUE, 'title' => 'WP Router Sample Page', 'template' => array('sample-page.php', dirname(__FILE__).DIRECTORY_SEPARATOR.'sample-page.php') ));` In this example, the path `http://example.com/wp_router/my_sample_path/` will call the function `sample_callback` in the calling class. The value of the `sample_argument` query variable, in this case "my_sample_path", will be provided as the first and only argument to the callback function. If the file `sample-page.php` is found in the theme, it will be used as the template, otherwise `sample-page.php` in your plugin directory will be used (if that's not found either, fall back to `route-wp-router-sample.php`, etc.). = Editing Routes = * You can hook into the `wp_router_alter_routes` action to modify routes created by other plugins. The callback should take one argument, a `WP_Router` object. = Public API Functions = Creating or changing routes should always occur in the context of the `wp_router_generate_routes` or `wp_router_alter_routes` actions, using the `WP_Router` object supplied to your callback function. * `WP_Router::edit_route( string $id, array $changes )` - update each property given in `$changes` for the route with the given ID. Any properties not given in `$changes` will be left unaltered. * `WP_Router::remove_route( string $id )` - delete the route with the given ID * `WP_Router::get_route( string $id )` - get the `WP_Route` object for the given ID * `WP_Router::get_url( string $id, array $arguments )` - get the URL to reach the route with the given ID, with the given query variables and their values * `WP_Route::get( string $property )` - get the value of the specified property for the `WP_Route` instance == Changelog == = 0.6 = * Make magic methods public to avoid fatal with PHP 7.3 * Add `composer.json` to ease others' including = 0.5 = * Filter get_permalink on router pages to point to the requested URI * Filter post meta for the placeholder page when on a router page to provide a title to WP SEO * Added `wp_router_placeholder_postmeta` filter for adding additional meta to the placeholder page = 0.4 = * Prevent redirect from route pages with the "page" or "paged" query arg = 0.3.3 = * Prevent redirect from all route pages when %category% is in the permastruct * Redirect placeholder page to the blog front page * Fix usage of translation functions = 0.3.2 = * Make $arguments param optional for WP_Router::get_url() and WP_Router::url() = 0.3.1 = * Added WP_Router::get_url() * Added WP_Route::url() = 0.3 = * Added `FALSE` option to template parameter to indicate immediate `exit()` * Added option to specify different callback functions depending on the HTTP request method * Verified compatibility with WordPress 3.0 * Added WP_Router::get_url() function = 0.2 = * Added the `template` argument = 0.1 = * Initial version
Can you handle XHR requests to a particular resource independently of non-ajax requests?
Does this work with the various caching plugins? E.g., W3 Total Cache, WP Super Cache, etc.
Hi, Nice plugin, working well if I use it with a GET request (like you sample). But when I try to do a POST request it told's page not found, but it use the template for the route-url, so something is working.. I wonder if you have some more samples, one with post request maybe?
I keep getting comment spam on the WP Router Placeholder Page. This is the case even though I disabled comments for the whole site. As a possible work around I've made this page private. Please advise. Thanks
What flavor of regex do the routes support?
I've got some trouble getting auth cookies to save in a WP-Router callback.
I have GET/POST routes registered for ^register/([a-z0-9]{32})$
, where I verify a registration token and then show a registration form. The form (on the GET route) POSTs to the same place.
It's in the POST call that I process the registration and then (attempt to) authenticate the user immediately, so they don't need to sign in immediately after registration, then redirect them to the next step in the registration process (a payment form).
Unfortunately, the WP auth cookies aren't getting set, even though I'm directly calling the functions to do that.
Here's what I've got:
My route registration (in a mu-plugin):
<?php
add_action( 'wp_router_generate_routes', function( \WP_Router $router ) {
$router->add_route( 'register', array(
'title' => 'Register',
'path' => '^register/([a-z0-9]{32})$',
'query_vars' => array(
'fh_token' => 1,
),
'template' => array(
'register.php',
),
'access_callback' => TRUE,
'page_arguments' => array( 'fh_token' ),
'page_callback' => array(
'GET' => array( 'MyApp\RegisterController', 'get' ),
'POST' => array( 'MyApp\RegisterController', 'post' ),
),
) );
$router->add_route( 'payment', array(
'title' => 'Payment',
'path' => '^payment',
'template' => array(
'payment.php',
),
'access_callback' => TRUE,
'page_callback' => array(
'GET' => array( 'MyApp\PaymentController', 'get' ),
'POST' => array( 'MyApp\PaymentController', 'post' ),
),
) );
}, 10, 1 );
My registration controller POST callback, autoloaded via Composer:
<?php
namespace MyApp;
class RegisterController {
public static function post( $fh_token = null )
{
// blah blah blah
// parse the $_POST submission, create the user
// verify the $fh_token
// set the $user variable from the newly-created user,
// $user is an instance of a custom class that nicely
// abstracts WP_User
// Clear existing auth cookies
wp_clear_auth_cookie();
// Log the user in
// Note: $user is a local object, assume it works, 'cuz it does
do_action( 'wp_login', $user->getEmail(), $user->item );
wp_set_current_user( $user->getId() );
wp_set_auth_cookie( $user->getId(), true );
// Redirect to payment page
wp_safe_redirect( '/payment' );
exit();
}
}
When I adjust the registration POST callback so it doesn't redirect, the authentication works—sort of. The WP admin bar shows up, and is_user_logged_in()
calls in the page template return true.
It still doesn't set the wordpress_logged_in
cookie though, which means that on subsequent pageloads the session doesn't persist and the user is logged out. Just for kicks, I also tried a direct setcookie()
call in the callback, and that cookie wasn't added either.
I know it's not my server configuration stripping the cookies, because logins at wp-login.php or through a page with a wp_login_form()
work fine and set the cookies properly.
Any ideas?
Hello,
Is there a way to test what route I'm showing,
example, in my header.php, I'd like to do :
if(is_route('my_custom_routing')) { echo 'menu-active'; }
thanks
If there are any submitted form values that overlap with WP's query vars, they will affect the final query and probably result in a 404. WP_Router_Page should strip out those query vars.
I'm using the following piece of code
$router->add_route('custom_user_route', [
'path' => '^user/(.*?)$',
'query_vars' => [
'id' => 1,
],
'page_callback' => [$this, 'pageCallback'],
'page_arguments' => ['id'],
'access_callback' => TRUE,
'title' => 'User Account',
'template' => 'custom-user.php'
]);
But the document title always shows "WP Router Sample Page"
Hello!
I'd like to use this plugin to create custom routes, assign query vars to wordpress, and then pass the request back to WordPress.
How would I do this?
Thanks!
I can't seem to put a route at /
- is it possible with WP-Router?
I've tried setting my path to ^/$
and ^$
with no luck.
examine we have this : 'path' => 'download/file/([0-9]+)/{name}',
how we can get these parameters in function ?
function create_routes_customs( $router ) {
$router->add_route('download', array(
'path' => 'download/file/([0-9]+)/{name}',
'access_callback' => true,
'page_callback' => 'download'
));
}
function download(){
//get params
}
Hi,
Firstly thanks for a cracking plugin save me hours of coding. On my latest project I started getting the annoying Notice: Undefined property: WP_Query::$post. I always developed with debug to true and this bugged me for a while. In the end I tracked it down to the pre_get_posts call in WP_Router_Page.class.php around line 111. I implemented a simple check to solve my issue
public function edit_query( WP_Query $query ) {
if($query->is_page()) {
if ( isset($query->query_vars[self::QUERY_VAR]) ) {
// make sure we get the right post
$query->query_vars['post_type'] = self::POST_TYPE;
$query->query_vars['p'] = self::get_post_id();
// override any vars WordPress set based on the original query
$query->is_single = TRUE;
$query->is_singular = TRUE;
$query->is_404 = FALSE;
$query->is_home = FALSE;
}
}
}
Might help someone. Again thats for a cracking plugin
Rob
public function set_post_contents( $post ) {
global $pages;
$pages = array($this->contents);
}
This function overwrites the global $pages to only include what is given in the route callback.
I fix this on my end (for the moment) just by doing this :
$pages = array($this->contents . $post->post_content);
To plugin directory, main plugin file, readme, and composer.json
is it possible to pass an array of all regex matches to callback without knowing how many matches there will be beforehand?
After activating the plugin, I tried to go the sample page, but it didn't recognize the rewrite rules, so I installed Rewrite Rules Inspector, and sure enough:
So I tried getting the value of WP_Router::rewrite_rules(), and it's Array ( [^wp_router/(.*?)$] => index.php?sample_argument=$matches[1]&WP_Route=wp-router-sample )
, so I can't figure out what the issue is.
Hi,
This may be a very simple thing to do but can't figure it out.
Q- How does one go about including css files on the page accessible through a route setup via WP-Router ?
Note: The page is being set up via a new plugin I am trying to make.
Note2: linking to a CDN is an option but figuring out what to do if I want my plugin to be self-contained
Do we -
A) Use the action 'wp_enqueue_scripts' or
B) Serve the file from another route(like '/assets/css/mycss') setup using WP-Router using 'file_get_contents' ?
C) Something else.
Let me know if this can be done with this plugin? Thanks !
Hi there, how to add dynamic id before my page path name and after my page path name like this
'path' => '(.?)/travel-stories/(.?)$',
when I remove first dynamic id its redirect to 404 error page. Please help!
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.