Je me demande s'il est possible de déterminer les paramètres WP_Query avec seulement en utilisant l'URL de la page donnée. J'essaie de le faire parce que je développe un thème SPA (et finalement une réponse JSON) et que je devrais être en mesure de déterminer une requête sans recharger la page.
Bien que ce soit assez difficile, j'ai réussi à associer une URL de publication à la structure Permalink afin de déterminer ce que devrait être une requête de publication unique:
<?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( '/', get_option( 'permalink_structure' ) ) );
// Break our query parameters in to an array
$query_params = array_filter( explode( '/', $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' );
En utilisant la fonction ci-dessus, je peux passer url
en tant que paramètre pour effectuer un appel ajax. Il sera ensuite analysé pour rechercher les paramètres WP_Query.
Ainsi, une URL telle que http://example.com/blog/my-first-post/
sera analysée pour extraire name => 'my-first-post'
et une URL telle que http://example.com/?p=124
sera analysée pour extraire p => 124
. Ceci est ensuite passé à un WP_Query
et ainsi de suite. FTR, je supprime également tous les paramètres de la liste noire, tels que post_status
ou has_password
, dans le but de protéger les données.
Afin d'analyser une jolie structure d'URL, je prends les composants du chemin, donc pour /2014/07/hello-world/
nous obtenons 2014 , 07 , et hello-world , puis Je les compare à la structure permalink définie, qui dans ce cas serait /%year%/%monthnum%/%postname%/
- et comme certaines balises permalink ne fonctionnent pas avec WP_Query, je fais une conversion; Par exemple, postname
serait name
.
Quoi qu'il en soit ... j'avais l'impression d'avoir pris un bon départ, jusqu'à ce que je me précipite dans les pages. Avec mon code ci-dessus, une URL de page telle que http://example.com/about/
et la structure permalien ci-dessus, les paramètres extraits seraient year => 'about'
. Pas bon.
Si quelqu'un a des indications sur la façon dont je devrais aborder cela, ce serait beaucoup apprécié. Aussi, s'il vous plaît laissez-moi savoir si j'aborde tout cela de travers. Je dois juste déterminer une requête sans recharger la page.
Édité le 07 juillet 2014 à 6:28
Votre approche comporte beaucoup de pièges. Cela ne fonctionnera pas s'il existe une règle de réécriture personnalisée, cela (probablement) ne fonctionnera pas si le serveur est IIS et si les permaliens sont actifs, cela ne fonctionnera pas pour les types de publication personnalisés, cela ne fonctionnera pas pour les archives ou rechercher des URL et ainsi de suite.
Pour obtenir une URL de publication/page à partir d'une URL de manière abordable, vous devez utiliser la fonction url_to_postid
, par exemple.
$id = url_to_postid( $query_url['path'] );
if ( is_numeric( $id ) && (int) $id > 0 ) {
// the required post id is: $id
} else {
// the url is not for a single post, may be an archive url, a search url or even
// a non-valid 404 url
}
Si vous êtes intéressé uniquement si vous avez un seul message (même CPT) ou des URL de page, alors les quelques lignes ci-dessus sont probablement la seule chose dont vous avez besoin, mais si vous devez analyser toutes sortes d’URL WordPress, vous avez besoin de quelque chose d’autre, mais ce n’est pas le cas. quelque chose de vraiment facile.
Le seul moyen d'obtenir des vars de requête à partir d'une URL de manière abordable consiste à reproduire la méthode utilisée par WordPress pour analyser une URL.
Cela se fait en core par la méthode parse_request
de la classe WP
.
Cependant, l’utilisation de cette méthode pour notre objectif expliqué ci-dessus est difficile/déconseillée pour les raisons suivantes:
$_SERVER
, $_POST
et $_GET
, ce qui rend difficile l'analyse des URL arbitraires non liées à la requête HTTP actuelle$wp
et les modifie; celles-ci ne doivent pas être changées une fois la requête analysée ou très probablement, des choses se casseront.Ce que nous pouvons faire, c'est partir du code là-bas, supprimer les parties dont nous n'avons pas besoin et faire en sorte que le code utilise une URL arbitraire au lieu de celle de la requête HTTP actuelle.
La méthode de base parse_request
a une longueur de 214 lignes (v. 3.9.1) et faire ce travail peut être très pénible, mais heureusement, quelqu'un a déjà fait le travail, voir ici .
Il existe une solution simple utilisant un mécanisme bon et un mécanisme étrange.
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!" );
}
// Add an extra parameter to the url.
$api_url = add_query_arg( 'json_vars', time(), $_POST['url'] );
$request = wp_remote_request( $api_url );
$content = wp_remote_retrieve_body( $request );
if( is_wp_error($content) ){
api_response( false, 400, "couldn't retrive the data" );
}
if( !empty($content) )
$vars = json_decode( $content );
else
$vars = array();
// pass the array to your function
api_single( $vars );
}
add_action( 'wp_ajax_nopriv_api_query_url', 'api_query_url' );
/* Comparing the extra parameter (json_vars), we return the json of the vars & no html */
function api_parse_request( $q )
{
/* home/front-page doesn't have any q-vars */
/* so you might be setting some defaults for that */
$vars = $q->query_vars;
if( isset($_REQUEST['json_vars']) ){
echo json_encode( $vars );
die();
}
}
add_action( 'parse_request', 'api_parse_request' );