web-dev-qa-db-fra.com

Comment créer une page "virtuelle" dans WordPress

J'essaie de créer un point de terminaison d'API personnalisé dans WordPress et je dois rediriger les demandes vers une page virtuelle située à la racine de WordPress vers une page fournie avec mon plug-in. Donc, en gros, toutes les demandes d’une page sont en réalité acheminées vers une autre page.

Exemple:
http://mysite.com/my-api.php => http://mysite.com/wp-content/plugins/my-plugin/my-api.php

L'objectif est de rendre l'URL du noeud final de l'API aussi courte que possible (similaire à http://mysite.com/xmlrpc.php mais d'envoyer le fichier de noeud final de l'API avec le plug-in plutôt que de demander à l'utilisateur de déplacer des fichiers lors de son installation et/ou de le pirater coeur.

Mon premier essai consistait à ajouter une règle de réécriture personnalisée. Cependant, cela a eu deux problèmes.

  1. Le point final a toujours eu un slash final. C'est devenu http://mysite.com/my-api.php/
  2. Ma règle de réécriture n'était que partiellement appliquée. Il ne redirigerait pas vers wp-content/plugins..., il redirigerait vers index.php&wp-content/plugins.... Cela a amené WordPress à afficher une erreur de page introuvable ou tout simplement à remplacer la page d’accueil par défaut.

Des idées? Suggestions?

50
EAMann

Il existe deux types de règles de réécriture dans WordPress: les règles internes (stockées dans la base de données et analysées par WP :: parse_request () ), et les règles externes (stockées dans .htaccess et analysées par Apache). Vous pouvez choisir l’une ou l’autre solution, en fonction de la quantité de WordPress dont vous avez besoin dans votre fichier appelé.

Règles externes:

La règle externe est la plus facile à configurer et à suivre. Il exécutera my-api.php dans votre répertoire de plugin, sans rien charger à partir de WordPress.

add_action( 'init', 'wpse9870_init_external' );
function wpse9870_init_external()
{
    global $wp_rewrite;
    $plugin_url = plugins_url( 'my-api.php', __FILE__ );
    $plugin_url = substr( $plugin_url, strlen( home_url() ) + 1 );
    // The pattern is prefixed with '^'
    // The substitution is prefixed with the "home root", at least a '/'
    // This is equivalent to appending it to `non_wp_rules`
    $wp_rewrite->add_external_rule( 'my-api.php$', $plugin_url );
}

Règles internes:

La règle interne nécessite un peu plus de travail: nous ajoutons d'abord une règle de réécriture qui ajoute un vars de requête, puis nous rendons cette requête var publique, puis nous devons vérifier l'existence de cette requête var pour passer le contrôle à notre fichier de plug-in. Au moment où nous faisons cela, l’initialisation habituelle de WordPress aura déjà eu lieu (nous nous échappons juste avant la requête normale).

add_action( 'init', 'wpse9870_init_internal' );
function wpse9870_init_internal()
{
    add_rewrite_rule( 'my-api.php$', 'index.php?wpse9870_api=1', 'top' );
}

add_filter( 'query_vars', 'wpse9870_query_vars' );
function wpse9870_query_vars( $query_vars )
{
    $query_vars[] = 'wpse9870_api';
    return $query_vars;
}

add_action( 'parse_request', 'wpse9870_parse_request' );
function wpse9870_parse_request( &$wp )
{
    if ( array_key_exists( 'wpse9870_api', $wp->query_vars ) ) {
        include 'my-api.php';
        exit();
    }
    return;
}
54
Jan Fabry

Cela a fonctionné pour moi. Je n'ai jamais touché l'API de réécriture, mais je suis toujours prêt à me pousser dans de nouvelles directions. Ce qui suit a fonctionné sur mon serveur de test pour 3.0 situé dans un sous-dossier de localhost. Je ne vois pas de problème si WordPress est installé dans la racine Web.

Il suffit de déposer ce code dans un plugin et de télécharger le fichier nommé "taco-kittens.php" directement dans le dossier du plugin. Vous aurez besoin d'écrire un flush dur pour vos permaliens. Je pense qu'ils disent que le meilleur moment pour le faire est l'activation du plugin.

function taco_kitten_rewrite() {
    $url = str_replace( trailingslashit( site_url() ), '', plugins_url( '/taco-kittens.php', __FILE__ ) );
    add_rewrite_rule( 'taco-kittens\\.php$', $url, 'top' );
}
add_action( 'wp_loaded', 'taco_kitten_rewrite' );

Meilleurs voeux, -Mike

11
mfields

Une raison de ne pas faire quelque chose comme ça à la place?

http://mysite.com/?my-api=1

Ensuite, connectez simplement votre plugin à 'init' et vérifiez que la variable get. S'il existe, faites ce que votre plugin doit faire et mourrez ()

8
Will Anderson

Je ne comprends peut-être pas bien vos questions, mais un simple shortcode résoudrait-il votre problème?

Pas:

  1. Demandez au client de créer une page i.e. http://mysite.com/my-api
  2. Demander au client d’ajouter un shortcode dans cette page, c’est-à-dire [my-api-shortcode]

La nouvelle page agit comme un point de terminaison de l'API et votre shortcode envoie des demandes à votre code de plugin dans http://mysite.com/wp-content/plugins/my-plugin/my-api.php

(bien sûr, cela signifie que my-api.php aurait défini le shortcode)

Vous pouvez probablement automatiser les étapes 1 et 2 via le plugin.

3
rexposadas

J'utilise une autre approche qui consiste à forcer la page d'accueil à charger un titre, un contenu et un modèle de page personnalisés .

La solution est très pratique puisqu'elle peut être mise en œuvre lorsqu'un utilisateur suit un lien convivial tel que http://example.com/? Plugin_page = myfakepage

Il est très facile à mettre en œuvre et devrait permettre un nombre illimité de pages.

Code et instructions ici: Génère une page Wordpress personnalisée/fictive/virtuelle à la volée

1
Xavi Esteve

Je n'ai pas encore beaucoup traité de réécriture, donc c'est probablement un peu difficile, mais cela semble fonctionner:

function api_rewrite($wp_rewrite) {
    $wp_rewrite->non_wp_rules['my-api\.php'] = 'wp-content/plugins/my-plugin/my-api.php';
    file_put_contents(ABSPATH.'.htaccess', $wp_rewrite->mod_rewrite_rules() );
}

Cela fonctionne si vous accrochez ceci à 'generate_rewrite_rules', mais il doit y avoir un meilleur moyen, car vous ne voulez pas réécrire .htaccess à chaque chargement de page.
On dirait que je ne peux pas arrêter de modifier mes propres messages ... il devrait probablement plutôt aller dans vous activez callback et référence globale $ wp_rewrite à la place. Ensuite, supprimez l'entrée de non_wp_rules et envoyez-la à nouveau à .htaccess en désactivant le rappel.

Et enfin, l'écriture sur .htaccess devrait être un peu plus sophistiquée, vous voulez seulement remplacer la section wordpress qui s'y trouve.

1
wyrfel

J'avais une exigence similaire et je voulais créer plusieurs points de terminaison basés sur des slugs uniques pointant vers le contenu généré par le plugin.

Regardez la source de mon plugin: https://wordpress.org/extend/plugins/picasa-album-uploader/

La technique que j'ai utilisée commence par l'ajout d'un filtre pour the_posts afin d'examiner la demande entrante. Si le plugin doit le gérer, une publication factice est générée et une action est ajoutée pour template_redirect.

Lorsque l'action template_redirect est appelée, il doit en résulter la sortie de l'intégralité du contenu de la page à afficher et à quitter, sinon le résultat doit être renvoyé sans qu'aucune sortie ne soit générée. Voir le code dans wp_include/template-loader.php et vous verrez pourquoi.

1
Ken

J'utilise une approche similaire à celle décrite ci-dessus par Xavi Esteve, qui a cessé de fonctionner en raison d'une mise à niveau de WordPress, pour autant que je sache, au second semestre de 2013.

C'est documenté en détail ici: https://stackoverflow.com/questions/17960649/wordpress-plugin-generating-virtual-pages-and-using-theme-template

La partie clé de mon approche consiste à utiliser le modèle existant afin que la page résultante ressemble à une partie du site; Je voulais que ce soit aussi compatible que possible avec tous les thèmes, espérons-le, dans les versions de WordPress. Le temps dira si j'avais raison!

0
Brian C