Как поймать правила перезаписи, а затем отобразить конкретный пост?

Я пытаюсь перехватить параметры, отправленные по правилам перезаписи, а затем отобразить выбранный пост.

Но пока, даже если я смогу получить эти параметры, страница перенаправляется в архив моего пользовательского типа записи. Где мне нужно отобразить сообщение, которое соответствует пользовательской сборке запроса из строки запроса, заданной правилом перезаписи.

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;});

Во-первых, я не понимаю, почему оно перенаправляет на страницу архива?

Во-вторых, может быть, «pre_get_posts» - это не то место, где можно сделать собственный запрос, но где я могу это сделать?

В-третьих, как отобразить выбранный пост в ответ на чистый URL-адрес, указанный ?

Спасибо за вашу помощь! ; -)

@ EDITI пытался использовать такие действия, как "template_redirect" или "parse_request", но это выглядит действительно * хакерским. Кто-нибудь знает, как принудительно перенаправить (например, переписать соответствие) на первый пост пользовательского запроса?

Ответы и комментарии:

Вы использовали term_sulg в одном месте
Создан 16-08-2017 10:28 birgire

привет @birgire, строка "term_slug" - это только пример ... но что именно ты имел в виду?
Создан 16-08-2017 12:25 Monkey Monk

Вы используете $ args, но нигде не устанавливаете его.
Создан 16-08-2017 01:27 Milo

Ой ! Это ошибка при написании вопроса ... Я исправляю это прямо сейчас! ;-)
Создан 16-08-2017 01:27 Monkey Monk

В pre_get_posts сложно, а иногда и невозможно преобразовать один тип запроса в другой. Вам нужно подключиться перед синтаксическим анализом запроса, если вы делаете что-то серьезное, или вам нужно установить правильные переменные запроса в вашем правиле, чтобы wp знал, что вы намерены использовать это как просмотр одного сообщения, а не как архив.
Создан 16-08-2017 03:49 Milo

Похоже, как и @milo также сказал, что правильный способ сделать это - использовать действие "parse_request", которое стоит перед действием "pre_get_posts" (см. Https://codex.wordpress.org/Plugin_API/Action_Reference).
Полное решение, с которым я пришел:
add_action ('init', function () {
    $ refs_slug = getCustomRefTermsSlug (); // это вернет массив всех терминов slug, существующих в пользовательской таксономии "ref"

    // @note Catch / {foo | bar | baz} и перенаправить на index.php? catch_me = true? ref = {foo | bar | baz}
    add_rewrite_rule ('^ ('. implode ('|', $ refs_slug). ') /?', 'index.php? post_type = custom & catch_me = true & ref = $ match [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',
                'term' => $ query-> query_vars ['ref'],
            ];
        }

        // получить правильный пост
        $ tmp_query = new WP_Query ($ args);
        $ post_id = $ tmp_query-> posts [0];

        // сообщаем WordPress, какой пост показывать
        $ query-> query_vars = [
            'post_type' => 'custom',
            'p' => $ post_id,
        ];
    }

    вернуть $ query;
});

add_filter ('post_type_link', function ($ url, $ post) {
    if (get_post_type ($ post) == 'custom') {
        $ refs_slug = getCustomRefTermsSlug ($ post-> ID); // это вернет массив всех слагаемых терминов пользовательской таксономии «ref», назначенной посту

        // @note Возвращаем "/ {foo | bar | bar}" как постоянную ссылку поста
        вернуть '/' . implode ('/', $ refs_slug);
    }

    вернуть $ url;
}, 10, 2);

Не стесняйтесь давать мне комментарии! ;-)
Создан 18-08-2017 09:37