web-dev-qa-db-fra.com

Comment attraper les règles de réécriture puis afficher un post spécifique?

J'essaie de récupérer les paramètres envoyés par les règles de réécriture, puis d'afficher un message sélectionné.

Mais pour l'instant, même si je peux récupérer ces paramètres, la page sera redirigée vers l'archive de mon type de publication personnalisé. Où j'ai besoin d'afficher le message qui correspond à une construction de requête personnalisée à partir de la chaîne de requête donnée par la règle de réécriture.

add_action('init', function () {
    $terms_slug = getCustomTermsSlug();
    // @note Catch /{foo}
    add_rewrite_rule('^(' . implode('|', $terms_slug) . ')/?', 'index.php?post_type=custom&foo=$matches[1]', 'top');
});

add_action('init', function () {
    add_rewrite_tag('%foo%', '([^&]+)');
}, 10, 0);

add_action('pre_get_posts', function ($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    if (get_query_var('foo')) {
        $tax_query = [[
            'taxonomy' => 'custom',
            'field' => 'slug',
            // @note "foo" is a custom taxonomy term
            'terms' => get_query_var('foo'),
        ]];

        $query->set('tax_query', $tax_query);
    }

    return $query;
});

Tout d'abord, je ne comprends pas pourquoi il redirige vers la page d'archive?

Deuxièmement, le "pre_get_posts" n'est peut-être pas le bon endroit pour faire la requête personnalisée mais où puis-je le faire?

Troisièmement, comment afficher le message sélectionné en réponse à l'URL propre donnée?

Merci de votre aide! ;-)

@EDIT J'ai essayé d'utiliser des actions telles que "template_redirect" ou "parse_request" mais cela me semble vraiment * hacky. Quelqu'un sait-il comment forcer la redirection (par exemple, la correspondance de réécriture) vers le premier message de la requête personnalisée?

1
Monkey Monk

Il semble, comme @milo également dit, que la bonne façon de procéder consiste à utiliser l'action "parse_request" précédant l'action "pre_get_posts" (voir https: //codex.wordpress .org/Plugin_API/Action_Reference ).

La solution complète je suis venu avec:

add_action('init', function () {
    $refs_slug = getCustomRefTermsSlug(); // this will return an array of all the terms slug existing in the custom "ref" taxonomy

    // @note Catch /{foo|bar|baz} and redirect to index.php?catch_me=true?ref={foo|bar|baz}
    add_rewrite_rule('^(' . implode('|', $refs_slug) . ')/?', 'index.php?post_type=custom&catch_me=true&ref=$matches[1]', 'top');
});

add_action('init', function () {
    add_rewrite_tag('%ref%', '([^&]+)');
    add_rewrite_tag('%catch_me%', '([^&]+)');
}, 10, 0);

add_action('parse_request', function ($query) {
    if (array_key_exists('catch_me', $query->query_vars) && $query->query_vars['catch_me']) {
        $args = [
            'post_type' => 'custom',
            'posts_per_page' => 1,
            'fields' => 'ids',
            'tax_query' => [],
        ];

        if (array_key_exists('ref', $query->query_vars)) {
            $args['tax_query'][] = [
                'taxonomy' => 'ref',
                'field' => 'slug',
                'terms' => $query->query_vars['ref'],
            ];
        }

        // get the right post
        $tmp_query = new \WP_Query($args);
        $post_id = $tmp_query->posts[0];

        // tell wordpress what post to display
        $query->query_vars = [
            'post_type' => 'custom',
            'p' => $post_id,
        ];
    }

    return $query;
});

add_filter('post_type_link', function ($url, $post) {
    if (get_post_type($post) == 'custom') {
        $refs_slug = getCustomRefTermsSlug($post->ID); // this will return an array of all the terms slug of the custom "ref" taxonomy assigned to the post

        // @note Return "/{foo|bar|bar}" as the permalink of the post
        return '/' . implode('/', $refs_slug);
    }

    return $url;
}, 10, 2);

N'hésitez pas à me donner des commentaires! ;-)

1
Monkey Monk