Понимание add_rewrite_rule

11

Я пытаюсь получить add_rewrite_ruleработу, чтобы извлечь параметр из URL и передать его на запрос. Посмотрел несколько постов об этом, но не могу заставить его работать.

Если URL-адрес начинается с определенной строки, я хотел бы удалить его из URL-адреса и передать в качестве параметров запроса.

Пример запроса URL:

http://domain.com/foo/my_page

Это будет преобразовано в

http://domain.com/my_page?param=foo

Если 'foo' отсутствует, он должен просто пройти как обычный запрос. Эта логика должна применяться к любому URL-адресу страницы или пользовательскому типу записи на моем сайте (обычно это foo / *). Думая, что это будет действовать как проход, если у URL есть «foo», удалите его, а затем просто перейдите к Wordpress, чтобы это стало нормой.

У меня уже есть «param» в качестве разрешенного query_vars.

В целом, это должно было бы работать для следующего:

  • / foo / my_page (Page)
  • / foo / my_folder / my_page (дополнительная страница)
  • / foo / example_type (Пользовательский почтовый архив)
  • / foo / example_type / example_post (Пользовательская запись, одиночная)
Луи В
источник
какой-либо URL, то есть сообщения, категории, теги и т. д., а не только pageтип сообщения или просто какая-либо страница? как насчет родительских / дочерних страниц в иерархии?
Майло,
@ Мило Я разъяснил тебе это. Я использую только страницы и пользовательские типы сообщений (архив и отдельные страницы).
Луи W

Ответы:

8

Основное правило, которое будет работать для вашего примера:

function wpd_foo_rewrite_rule() {
    add_rewrite_rule(
        '^foo/([^/]*)/?',
        'index.php?pagename=$matches[1]&param=foo',
        'top'
    );
}
add_action( 'init', 'wpd_foo_rewrite_rule' );

Это берет все, что приходит после, foo/и устанавливает это как pagenameдля запроса, а затем paramполучает статическое значение foo. Если вам нужны разные шаблоны URL, вам потребуются дополнительные правила для каждого уникального шаблона. Обратитесь к WP_Queryдокументации для различных вариантов запросов, которые могут быть установлены в правилах перезаписи. Не забудьте сбросить правила перезаписи после добавления новых. Это можно сделать, посетив страницу настроек постоянных ссылок.

Теперь посещая ваш пример URL:

http://domain.com/foo/my_page

загрузит правильную страницу, но она не будет вести себя так же, как посещение:

http://domain.com/my_page?param=foo

потому что при использовании внутренних перезаписей, paramустанавливается внутри $wp_queryобъекта запроса, а не $_GETсуперглобальный. Если вам нужно работать с кодом, который ищет значение $_GET, вам потребуется дополнительный шаг для установки этого значения:

function wpd_foo_get_param() {
    if( false !== get_query_var( 'param' ) ){
        $_GET['param'] = get_query_var( 'param' );
    }
}
add_action( 'parse_query', 'wpd_foo_get_param' );

Другой метод, который следует рассмотреть, - это использование конечных точек, поэтому они /foo/должны быть в конце URL, а не в качестве префикса. Преимущество этого заключается в том, что API add_rewrite_endpointупрощает добавление всех необходимых вам правил, включая включение нумерации страниц.

Milo
источник
Спасибо за исчерпывающее объяснение. Кажется близким, работает для страниц, но выдает ошибку 404 для пользовательского почтового архива и отдельных URL.
Луи W
да, как я уже сказал, вам нужно добавить дополнительные правила, соответствующие каждому из этих шаблонов. Я не знаю, как эти URL выглядят в вашей настройке.
Мило
У меня есть пользовательский тип страницы с именем «проекты», который имеет архив и отдельные страницы. Можете ли вы привести пример для этого, и я могу сделать все остальные.
Луи W
Кроме того, он не работает для подстраниц.
Луи W
1
Отредактируйте свой вопрос, чтобы добавить пример каждого шаблона URL, для которого требуется правило. Меня не очень волнует, что мой ответ будет принят, иногда я могу обмануть людей, чтобы они отвечали на их собственные вопросы, давая им что-то для начала.
Мило
6

Хорошо, я получил рабочие примеры для всех 3 типов запросов. Чтобы заставить их работать, потребовалось множество экспериментов и возни. Полагаю, Майло умеет подталкивать людей к ответам на их собственные вопросы.

После бесчисленных изменений и обновления постоянных ссылок я понял, что гораздо проще выяснить URL-адреса вне add_rewrite_url и, как только они сработают, определить перезапись. Примером является index.php?param=foo&post_type=example_type.

Еще одна очевидная вещь, но добавление ее сюда, чтобы она могла помочь кому-то еще. Вы должны определить пользовательские правила типа add_rewrite_rule ПРЕЖДЕ ЧЕМ вы определяете правила подстановки для вашей страницы / подстраницы. Я потратил немало времени на это и думаю, что это главное, что заставило меня не понять, почему правила не сработали.

Вот 3 правила, которые работают во всех моих нуждах. Правило Page / Sub-Page было объединено в одно.

// Custom Post Archive
add_rewrite_rule(
    '^foo/example_type/?$',
    'index.php?param=foo&post_type=example_type',
    'top'
    );

// Custom Post Individual
add_rewrite_rule(
    '^foo/example_type/([^/]*)/?$',
    'index.php?param=foo&example_type=$matches[1]',
    'top'
    );

// Pages, Top-Level and Sub-Pages
// This MUST be placed in the code AFTER custom post add_rewrite_rule
add_rewrite_rule(
    '^foo/(.+)/?$',    
    'index.php?param=foo&pagename=$matches[1]',
    'top'
    );

Кроме того, я создал цикл для добавления нескольких пользовательских правил типа записей. Помните, что вы должны определить пользовательские правила типа add_rewrite_rule ПРЕЖДЕ ЧЕМ вы определяете правила подстановки для вашей страницы / подстраницы.

$custom_types = array('example_type', 'projects', 'people');

foreach($custom_types as $type) {

    // Custom Post Archive
    add_rewrite_rule(
        '^foo/'.$type.'/?$',
        'index.php?param=foo&post_type='.$type,
        'top'
        );

    // Custom Post Individual
    add_rewrite_rule(
        '^foo/'.$type.'/([^/]*)/?$',
        'index.php?param=foo&'.$type.'=$matches[1]',
        'top'
        );

}

Перепишите анализатор , который Майло прошел вдоль был весьма полезным при попытке лучше понять , как Wordpress запросов для страниц / сообщений.

Луи В
источник
Поздно на шоу, но могу ли я пинговать вас для другого примера? Имейте в виду, я полностью не понимаю параметр $ tag в add_rewrite_rule. Понятия не имею, что это значит. Я также не понимаю пример использования pagename = $ match [1] '. HUH ??? У меня есть URL, например, domain.com/detail?id=2&it=3. Я хочу, чтобы страница была domain.com/detail/2-3/. Вы готовы?
Дебби Курт,