I’m wondering if it’s possible to determine WP_Query parameters by only using the given page URL. The reason I’m trying to do this because I’m developing a SPA theme (and ultimately a JSON response) and would need to be able to determine a query without reloading the page.
Thought it’s pretty hacky, I’ve been successful in pairing a post URL with the Permalink structure in order to determine what a single post query should be:
<?php
function api_query_url() {
// Check that the URL is set and is in fact a string
if ( ! isset( $_POST['url'] ) || gettype( $_POST['url'] ) !== 'string' ) {
api_response( false, 400, "'url' is a required parameter!" );
}
// Parse the URL for parameters and path
$query_url = parse_url( $_POST['url'] );
// Pass query-based URL directly to Single API request
if ( isset( $query_url['query'] ) ) {
api_single( $query_url['query'] );
}
// Map Permalink structure tags to WP_Query parameters
$structure_refs = array(
'year' => 'year',
'monthnum' => 'monthnum',
'day' => 'day',
'hour' => 'hour',
'minute' => 'minute',
'second' => 'second',
'post_id' => 'p',
'postname' => 'name',
'category' => 'category_name',
'author' => 'author_name'
);
// Retreive the site's Permalink Structure and break it in to an array
$structure = array_filter( explode( "https://wordpress.stackexchange.com/", get_option( 'permalink_structure' ) ) );
// Break our query parameters in to an array
$query_params = array_filter( explode( "https://wordpress.stackexchange.com/", $query_url['path'] ) );
// Set up an empty query array
$query = array();
// For each query parameter received
foreach ($query_params as $param) {
// Using the parameter value's position, locate its corresponding structure key
$key_position = array_search( $param, $query_params );
$structure_key = str_replace( '%', '', $structure[$key_position] );
// If the structure key exists in the structure references, add to to the query
if ( array_key_exists( $structure_key, $structure_refs) ) {
$query[$structure_refs[$structure_key]] = $param;
}
}
// Pass off to Query handler to create JSON response
api_single( $query );
}
add_action( 'wp_ajax_nopriv_api_query_url', 'api_query_url' );
Using the above function I’m able to pass url
as a parameter to it to perform an ajax call, and it will parse it to find the WP_Query parameters.
So, a URL like http://example.com/blog/my-first-post/
will be parsed to extract name => 'my-first-post'
and a URL like http://example.com/?p=124
will be parsed to extract p => 124
. This then gets passed to a WP_Query
and so forth. FTR, I also remove any blacklisted parameters, like post_status
or has_password
in an attempt to keep things secure.
In order to parse a pretty URL structure I take the components of the path, so for /2014/07/hello-world/
we get 2014, 07, and hello-world, and then I compare them to the set permalink structure, which in this case would be /%year%/%monthnum%/%postname%/
– and since some permalink tags don’t work with WP_Query, I do some conversion; for example, postname
would be name
.
Anyhow… it felt like I was off to a good start, until I ran in to pages. With my above code a page URL like http://example.com/about/
and the above permalink structure the parameters extracted would be year => 'about'
. Not good.
If anyone has any guidance as to how I should approach this it would be much appreciated. Also, please let me know if I’m approaching this all wrong. I just need to determine a query without reloading the page.