web-dev-qa-db-fra.com

L'ajout d'un point de terminaison de réécriture brise la page de couverture statique

J'ai une page d'accueil statique pour mon ensemble d'installation WP à partir de settings > reading. Ensuite, j'ai ajouté un point de terminaison d'URL en utilisant.

add_rewrite_endpoint('foo', EP_ALL);

La page de couverture devrait donc être accessible via

http://example.com/
http://example.com/foo
http://example.com/foo/bar

Pour n ° 1, tout fonctionne bien, mais pour n ° 2 et n ° 3, home.php par défaut est affiché à la place de la page d'accueil statique. Testé localement dans les installations mono et multisites.

Est-ce un comportement souhaité ou je frappe quelque chose d'inhabituel? Plus important encore, comment puis-je faire WP afficher la page d'accueil statique dans l'état donné?

Solution

J'étais déjà connecté à parse_request pour traiter une partie du code si foo existe. donc, selon la solution de @ gmazzap. Je n'ai besoin que de le désamorcer après. Pas besoin de fonction supplémentaire accrochée pour contourner le bogue.

add_action('parse_request', function(&wp){

    $key = 'foo';

    if (!array_key_exists( $key, $wp->query_vars ) ) {
        return;
    }

    // do things when foo exists

    // we no longer need 'foo'
    unset($wp->query_vars[$key]);

});
7
Sisir

Peut-être que je ne l’ai pas très bien compris, mais si vous devez simplement supprimer 'foo' des vars de requête, il ne serait pas beaucoup plus simple d’utiliser le filtre 'request' et de supprimer la var de là?

Code requis:

add_filter('request', function($query_vars) {
     return array_diff_key($query_vars, array('foo'=>''));
});

Il:

  • ne fonctionne que sur la requête principale
  • supprime la var pour l'objet $wp
  • agit avant que la requête ne soit définie sur $wp_query, il n'est donc pas nécessaire de supprimer la requête à partir de là
  • n'affecte pas toutes les autres variables

Modifier:

Un problème de ce code est qu'il s'exécute très tôt, de sorte qu'il sera difficile de détecter la présence de la variable de requête et de faire quelque chose en fonction de sa présence/valeur.

Une solution peut consister à exécuter les conditions sur le même filtre 'request', juste avant de supprimer la requête var (par exemple, en utilisant le même hook avec une priorité plus élevée).

Une autre solution peut être d'ajouter un drapeau à l'objet $wp:

add_filter('request', function($query_vars) {
     $GLOBALS['wp']->_foo = isset($query_vars['foo']) ? $query_vars['foo'] : false;
     return array_diff_key($query_vars, array('foo'=>''));
});

Après cela, il serait possible de vérifier la variable 'foo' dans n'importe quel hook déclenché après 'request', la plus ancienne étant 'parse_request'

add_action('parse_request', function($wp) {
    $foo = $wp->_foo;
    // do something with foo
});

Le dernier est 'shutdown':

add_action('shutdown', function() {
    $foo = $GLOBALS['wp']->_foo;
    // do something with foo
});
4
gmazzap

Ceci est un bug 25143 comme @toscho l'a signalé et sera corrigé dans la version 4.3

Solution de contournement trouvée dans le ticket et légèrement modifiée

WordPress ajoute foo comme requête var qui cause le problème. Donc, nous devons le supprimer avant WP interroger le DB

add_action( 'pre_get_posts', 'wpse191771_unset_query_arg' );
function wpse191771_unset_query_arg($query){

    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    $key = 'foo';

    $query_vars =& $query->query_vars;

    if ( array_key_exists($key, $query_vars) ) {
        // unset ref var from $wp_query
        $query->set( $key, null );

        global $wp;
        // unset ref var from $wp
        unset( $wp->query_vars[ $key ] );

        // if in home (because $wp->query_vars is empty) and 'show_on_front' is page
        if ( empty( $wp->query_vars ) && get_option( 'show_on_front' ) === 'page' ) {
            // reset and re-parse query vars
            $wp->query_vars['page_id'] = get_option( 'page_on_front' );
            $query->parse_query( $wp->query_vars );
        }
    }

}
4
Sisir