Comment créer une page "virtuelle" dans WordPress
8 réponses
- votes
-
- 2011-02-21
Ilexiste deuxtypes de règles de réécriture dans WordPress: les règlesinternes (stockées dans labase de donnéeset analyséespar WP ::parse_request () ),et des règlesexternes (stockées dans
.htaccess
et analyséespar Apache). Vouspouvez choisir l'une ou l'autremanière,en fonction de la quantité de WordPress dont vous avezbesoin dans votrefichier appelé.Règlesexternes:
La règleexterneest laplus simple à configureret à suivre. Ilexécutera
my-api.php
dans votre répertoire deplugins,sans rien charger 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èglesinternes:
La règleinternenécessite unpeuplus detravail:nous ajoutons d'abord une règle de réécriture qui ajoute une requête vars,puisnous rendons cette requête varpublique,puisnous devons vérifier l'existence de cette requête varpourpasser le contrôle ànotrefichierplugin. Aumoment oùnousfaisons cela,l'initialisation habituelle de WordPress auraeu lieu (nousnous séparonsjuste avant la requête depublication régulière).
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; }
There are two types of rewrite rules in WordPress: internal rules (stored in the database and parsed by WP::parse_request()), and external rules (stored in
.htaccess
and parsed by Apache). You can choose either way, depending on how much of WordPress you need in your called file.External Rules:
The external rule is the easiest to set up and to follow. It will execute
my-api.php
in your plugin directory, without loading anything from 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 ); }
Internal Rules:
The internal rule requires some more work: first we add a rewrite rule that adds a query vars, then we make this query var public, and then we need to check for the existence of this query var to pass the control to our plugin file. By the time we do this, the usual WordPress initialization will have happened (we break away right before the regular post query).
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; }
-
Je veuxjuste ajouter qu'ilestimportant d'aller sur lapage Permalienset de cliquer sur "Enregistrer lesmodifications" dans WP-Admin.J'aijoué avec çapendant une heure avant depenser quej'avaisbesoin de rafraîchir lespermaliens ... Amoins que quelqu'un connaisse unefonction quipeutfaire ça?I just want to add that its important to go to the Permalinks page and click "Save Changes" in the WP-Admin. I was playing with this for an hour before thinking that I needed to refresh the permalinks... Unless someone knows a function that can do that?
- 3
- 2013-05-28
- ethanpil
-
Pour la règleexterne: étant donné que le chemin d'accès àma racine Web avait un caractère d'espacement,cela afaittomber Apache.Lesespaces doivent être échappés s'ilsexistent dans le chemin de votreinstallation wordpress.For the external rule: Because the path to my web root had a whitespace character, this caused apache to fall over. Whitespaces need to be escaped if they exist in the path to your wordpress installation.
- 0
- 2013-06-04
- Willster
-
Fonctionne,maisje n'arrivepas à accéder aux variables de requêtepassées avec `get_query_vars ()` dansmy-api.php.J'ai vérifié quelles variables sont chargées.Et le seul var quiest définiest un `objet WP` appelé` $ wp`.Commentpuis-je accéder outransformer cecien un objet `WP_Query` afin queje puisse accéder aux variablespassées avec`get_query_vars () `?Works, but I can't seem to access any passed query variables with `get_query_vars()` in my-api.php. I checked what variables are loaded. And the only var that is set is a a `WP object` called `$wp`. How do I access or tranform this into a `WP_Query` object so I can access the passed variables with `get_query_vars()`?
- 1
- 2013-08-13
- Jules
-
@Jules: Lorsque vous `incluez` unfichier,ilestexécuté dans laportée actuelle.Dans ce cas,il s'agit de lafonction `wpse9870_parse_request`,quin'a que leparamètre` $ wp`.Ilestpossible que l'objetglobal `$ wp_query`n'aitpas été définipour lemoment,donc`get_query_var () `nefonctionnerapas.Cependant,vous avez de la chance: `$ wp`est la classe qui contient lemembre` query_vars` dont vous avezbesoin -je l'utilisemoi-même dans le code ci-dessus.@Jules: When you `include` a file, it gets executed in the current scope. In this case, it is the `wpse9870_parse_request` function, which only has the `$wp` parameter. It's possible that the global `$wp_query` object hasn't been set at this time, so `get_query_var()` will not work. However, you are lucky: `$wp` is the class that contains the `query_vars` member that you need - I use it myself in the above code.
- 1
- 2013-08-13
- Jan Fabry
-
@JanFabry Merci.Je l'ai compris après un certaintemps.Jeme demandais simplement s'ilexiste unmoyen de convertir un objet WPen un objet WP_Query.Maisje ne saispas s'il y aurajamais unbesoin de quelque chose comme ça,alorstantpis.Mercipour celaet tous vos autresmorceaux de code.Nous avons déjàtrouvé denombreusesinformations utiles sur ce sitegrâce à vous.@JanFabry Thanks. Figured that out after a while. I was just wondering if there is a way to convert a WP object to a WP_Query object. But I'm not to sure if there would ever even be a need for something like that, so never mind. Thanks for this and all your other pieces of code. Found a lot of helpful information on this site already thanks to you.
- 0
- 2013-08-14
- Jules
-
essayer de créer des règles de réécritureexternes.a ajouté votrepremiermorceau de codemaisj'obtienstoujours 404. *btw: règles de réécriture vidées *trying to create an external rewrite rules. added your fist piece of code but I am still getting 404. *btw: flushed rewrite rules*
- 1
- 2013-11-30
- Sisir
-
Je reçois égalementtoujours uneerreur 404 avec des règles de réécritureexternes.Justepour clarifier,le code ci-dessus va dans lefichier PHPprincipal duplugin,pas lefichier defonctions desmodèles correct?I'm also still getting a 404 error with external rewrite rules. Just to clarify, the code above goes into the main plugin PHP file, not the templates functions file correct?
- 0
- 2015-02-06
- Lee
-
@ethanpil vouspouvez (maintenant?) vider les règlespourinclure vosnouvelles règles de réécriture si les règles de réécriture WPne lesincluentpas.Laméthodeest documentéeici http://codex.wordpress.org/Class_Reference/WP_Rewrite@ethanpil you can (now?) flush the rules to include your new rewrite rules if WP rewrite rules do not include them. The method is documented here http://codex.wordpress.org/Class_Reference/WP_Rewrite
- 0
- 2015-08-31
- Ejaz
-
Dansmon cas,celafonctionne sur `index.php? Wpse9870_api=1` urlet alos`my-api.php? Wpse9870_api=1` commentpuis-je supprimer la chaîne de requête?In my case it is work on `index.php?wpse9870_api=1` url and alos `my-api.php?wpse9870_api=1` how i can remove query string?
- 0
- 2016-02-12
- er.irfankhan11
-
@Irfan J'essaye de réaliser lamême chosepouvez-vousme dire ce queje devrais écrire dansmy-api.php?@Irfan I am trying to achieve the same can you tell me what I should write in my-api.php ?
- 0
- 2016-05-04
- Prafulla Kumar Sahu
-
@Prafulla Kumar Sahu J'utilise comme ceci: `add_filter ('query_vars','wpse9870_query_vars'); fonction wpse9870_query_vars ($ query_vars) { $ query_vars []='getrequest'; return $ query_vars; } add_action ('parse_request','wpse9870_parse_request'); fonction wpse9870_parse_request (& $ wp) { if (array_key_exists ('getrequest',$ wp-> query_vars)) { inclure 'my-api.php'; sortie(); } revenir; } ` et l'urlest http://homeurl/?getrequest@Prafulla Kumar Sahu I am using like this: `add_filter( 'query_vars', 'wpse9870_query_vars' ); function wpse9870_query_vars( $query_vars ) { $query_vars[] = 'getrequest'; return $query_vars; } add_action( 'parse_request', 'wpse9870_parse_request' ); function wpse9870_parse_request( &$wp ) { if ( array_key_exists( 'getrequest', $wp->query_vars ) ) { include 'my-api.php'; exit(); } return; }` and url is http://homeurl/?getrequest
- 0
- 2016-05-06
- er.irfankhan11
-
La règleinterneest-elle vraiment stockée dans labase de données?Est-ce que `add_rewrite_rule` INSERT dans labase de données?Il semble qu'il soit simplement stocké dans le code source.Is the internal rule really stored in the database? Does `add_rewrite_rule` INSERT into the database? It looks like it is just stored in the source code.
- 0
- 2017-04-10
- Jeff
-
@ethanpil `flush_rewrite_rules (vrai);`@ethanpil `flush_rewrite_rules( true );`
- 0
- 2017-05-16
- mircobabini
-
- 2011-02-20
Cela afonctionnépourmoi.Jen'aijamaistouché à l'API de réécriture,maisje suistoujoursprêt àme pousser dans denouvelles directions.Ce qui suit afonctionné surmon serveur detestpour 3.0 situé dans un sous-dossier de localhost.Jene vois aucunproblème si WordPressestinstallé à la racine Web.
Déposez simplement ce code dans unpluginet téléchargez lefichiernommé "taco-kittens.php" directement dans le dossier duplugin.Vous aurezbesoin d'écrire unflush durpour vospermaliens.Jepense qu'ils disent que lemeilleurmomentpour lefaireest l'activation duplugin.
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
This worked for me. I never ever touch the rewrite API, but am always up to push myself in new directions. The following worked on my test server for 3.0 located in a sub folder of localhost. I don't for see any issue if WordPress is installed in web root.
Just drop this code in a plugin and upload the file named "taco-kittens.php" directly in the plugin folder. You will need write a hard flush for your permalinks. I think they say the best time to do this is on plugin activation.
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' );
Best wishes, -Mike
-
J'aieu uneerreur d'accès refuséen essayant ce code.Je soupçonne quemon serveur ou WPn'apas aimé l'URL absolue.Ceci,d'autrepart,fonctionnaitbien: `add_rewrite_rule ('taco-kittens','wp-content/plugins/taco-kittens.php','top');`I got an access denied error while trying this code. I suspect my server or WP didn't like the absolute URL. This, on the other hand, worked fine: `add_rewrite_rule( 'taco-kittens', 'wp-content/plugins/taco-kittens.php', 'top' );`
- 1
- 2013-08-13
- Jules
-
Pouvez-vous s'il vousplaîtme faire savoir ce queje devraismettre danstaco-kittens.php,je n'aipas connaissance de .htaccess ou de réécriture d'url.Can you please let me know, what I should put in taco-kittens.php, I do not have knowledge of .htaccess or url rewrite .
- 0
- 2016-05-04
- Prafulla Kumar Sahu
-
- 2011-02-20
Une raison dene pasfaire quelque chose comme ça à laplace?
Ensuite,connectez simplement votreplugin à 'init'et vérifiez la variableget.S'ilexiste,faites ce que votreplugin doitfaireet mourez ()
Any reason not to do something like this instead?
Then just hook your plugin into 'init' and check for that get variable. If it exists, do what your plugin needs to do and die()
-
Celafonctionnerait,maisj'essaie defournir une distinctiontrès claireentre les variables de requêteet lepoint determinaison réel.Ilpourrait y avoir d'autres arguments de requête à l'avenir,et jene veuxpas que les utilisateursmélangent les choses.That would work, but I'm trying to provide a very clear distinction between the query variables and the actual endpoint. There might be other query args in the future, and I don't want users to mix things up.
- 5
- 2011-02-20
- EAMann
-
Et si vousgardiez la réécriture,mais la réécriviez dans la variable GET?Vouspouvez égalementexaminer lefonctionnement de la réécriture dufichier robots.txt.Celapourrait vous aider à comprendre comment éviter la redirection versmy-api.php/What if you kept the rewrite, but rewrote it to the GET var? You might also look at how the rewrite for robots.txt works. It might help you figure out how to avoid the redirect to my-api.php/
- 0
- 2011-02-20
- Will Anderson
-
C'est la solutionparfaite si vousne vous souciezpas des robots comme les appels d'API.It is perfect solution if you don't care robots like API calls.
- 0
- 2017-03-11
- beytarovski
-
- 2011-02-20
Jene comprendspeut-êtrepas complètement vos questions,mais un simple code court résoudrait-il votreproblème?
Étapes:
- Demandez au client de créer unepage,c'est-à-dire http://monsite.com/my-api
- Demandez au client d'ajouter un shortcode dans cettepage,à savoir [my-api-shortcode]
Lanouvellepage agit comme unpointfinal d'APIet votre shortcodeenvoie des requêtes au code de votreplugin dans http://monsite.com/wp-content/plugins/my-plugin/my-api.php
(bien sûr,cela signifie quemy-api.php aurait le shortcode défini)
Vouspouvezprobablement automatiser les étapes 1et 2 via leplugin.
I may not be understanding you questions fully, but would a simple shortcode solve your issue?
Steps:
- Have the client create a page i.e. http://mysite.com/my-api
- Have the client add a shortcode in that page i.e. [my-api-shortcode]
The new page acts as an API end point and your shortcode sends requests to your plugin code in http://mysite.com/wp-content/plugins/my-plugin/my-api.php
( of course this means that my-api.php would have the shortcode defined )
You can probably automate steps 1 and 2 via the plugin.
-
- 2011-02-20
Jen'aipasencorebeaucouptraité de réécriture,donc c'estprobablement unpeu difficile,mais cela semblefonctionner:
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() ); }
Celafonctionne si vous accrochez ceci dans "generate_rewrite_rules",maisil doit y avoir unemeilleurefaçon,car vousne voulezpas réécrire .htaccess à chaque chargement depage.
On dirait queje nepeuxpasm'arrêter demodifiermespropresmessages ... cela devraitprobablementplutôt vouspermettre d'activer le rappelet de référencerglobal $ wp_rewrite à laplace.Ensuite,supprimez l'entrée denon_wp_ruleset la sortie vers .htaccess ànouveaupour désactiver le rappel.Etenfin,l'écritureen .htaccess devrait être unpeuplus sophistiquée,vousne voulez remplacer que la section wordpress.
I haven't dealt with rewrite that much, yet, so this is probably a little rough, but it seems to work:
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() ); }
It works if you hook this into 'generate_rewrite_rules', but there must be a better way, as you don't want to rewrite .htaccess on each page load.
Seems like i can't stop editing my own posts...it should probably rather go into you activate callback and reference global $wp_rewrite instead. And then remove the entry from non_wp_rules and output to .htaccess again in you deactivate callback.And finally, the writing to .htaccess should be a bit more sophisticated, you want to only replace the wordpress section in there.
-
- 2011-04-08
J'avais uneexigence similaireet je voulais créerplusieurspoints determinaisonbasés sur des slugs uniques quipointaient vers le contenugénérépar leplugin.
Jetez un œil à la source demonplugin: https://wordpress.org/extend/plugins/picasa-album-uploader/
Latechnique quej'ai utilisée commencepar ajouter unfiltrepour
the_posts
pourexaminer la requêteentrante.Si leplugin doit legérer,unpostfacticeestgénéréet une actionest ajoutéepourtemplate_redirect
.Lorsque l'action
template_redirect
est appelée,elle doit aboutir à la sortie du contenuentier de lapage à afficheret à quitter ouelle doit revenir sans aucune sortiegénérée.Consultez le code danswp_include/template-loader.php
et vous comprendrezpourquoi.I had a similar requirement and wanted to create several end-points based on unique slugs that pointed to content generated by the plugin.
Have a look at the source for my plugin: https://wordpress.org/extend/plugins/picasa-album-uploader/
The technique I used starts by adding a filter for
the_posts
to examine the incoming request. If the plugin should handle it, a dummy post is generated and an action is added fortemplate_redirect
.When the
template_redirect
action is called, it must result in outputting the entire contents of the page to be displayed and exit or it should return with no output generated. See the code inwp_include/template-loader.php
and you'll see why. -
- 2012-01-18
J'utilise une autre approche qui consiste à forcer lapage d'accueil à charger untitre,un contenuet unmodèle depagepersonnalisés .
La solutionesttrès soignéepuisqu'ellepeut êtremiseen œuvre lorsqu'un utilisateur suit un lien convivialtel que http://example.com/ ?plugin_page=myfakepage
Ilesttrèsfacile àmettreen œuvreet devraitpermettre unnombreillimité depages.
Codeet instructionsici: Créez unepage Wordpresspersonnalisée/fausse/virtuelle à la volée
I'm using another approach which consists in forcing the home page to load a custom title, content and page template.
The solution is very neat since it can be implemented when a user follows a friendly link such as http://example.com/?plugin_page=myfakepage
It is very easy to implement and should allow for unlimited pages.
Code and instructions here: Generate a custom/fake/virtual Wordpress page on the fly
-
- 2014-03-01
J'utilise une approche similaire à celle de Xavi Esteve ci-dessus,qui a cessé defonctionneren raison d'unemise àjour de WordPresspour autant queje sache au cours du second semestre 2013.
Ilest documentéen détailici: https://stackoverflow.com/questions/17960649/wordpress-plugin-generation-virtual-pages-and-using-theme-template
L'élément clé demon approche consiste à utiliser lemodèleexistantpour que lapage résultante ressemble à unepartie du site;Je voulais qu'il soit aussi compatible quepossible avectous lesthèmes,espérons-le,danstoutes les versions de WordPress.Letempsnous dira sij'avais raison!
I'm using an approach similar to Xavi Esteve's above, which stopped working due to a WordPress upgrade as far as I could tell in the second half of 2013.
It's documented in great detail here: https://stackoverflow.com/questions/17960649/wordpress-plugin-generating-virtual-pages-and-using-theme-template
The key part of my approach is using the existing template so the resulting page looks like it's part of the site; I wanted it to be as compatible as possible with all themes, hopefully across WordPress releases. Time will tell if I was right!
J'essaie de créer unpoint determinaison d'APIpersonnalisé dans WordPresset je dois rediriger les demandes vers unepage virtuelle à la racine de WordPress vers unepage réelle livrée avecmonplug-in. Donc,fondamentalement,toutes les requêtes vers unepage sonten fait acheminées vers l'autre.
Exemple:
http://mysite.com/my-api.php
=>http://mysite.com/wp-content/plugins/my-plugin/my-api.php
Lebutest de rendre l'URL dupoint determinaison de l'API aussi courte quepossible (similaire à
http://mysite.com/xmlrpc.php
mais d'expédier lefichier depoint determinaison de l'API avec leplug-inplutôt que de demander à l'utilisateur de déplacer desfichiers dans leurinstallationet/ou depirater lenoyau.Mapremièretentative a été d'ajouter une règle de réécriturepersonnalisée. Cependant,celaposait deuxproblèmes.
http://mysite.com/my-api.php/
wp-content/plugins...
,il redirigerait versindex.php&wp-content/plugins...
. Cela a conduit WordPress à afficher uneerreur depagenontrouvée ou simplement à revenir à lapage d'accueilpar défaut.Desidées? Des suggestions?