пользовательская таксономия и конфликт переписывания страниц дают 404

9

Я использую плагин Custom Post Type UI для создания своих пользовательских таксономий. У меня есть портфолио, состоящее из проектов (пользовательский тип сообщения) с 2 пользовательскими таксономиями технологий и клиентов. Таксономия клиентов имеет настраиваемый параметр перезаписи portfolio/clients/, в то время как таксономия технологий содержит настраиваемый параметр перезаписи:portfolio/

Переписано:
portfolio/html <- страница отображает все проекты с использованием HTML
portfolio/clients/client-a<- страница отображает все проекты для клиента A

Теперь, когда я пытаюсь создать целевую страницу для клиентов с URL-адресом, /portfolio/clientsя получаю страницу 404. Я почти уверен, что это из-за противоречивых переписываний URL таксономии технологий. Я предполагаю, что когда он ищет его в таксономии технологий, он не существует, тогда он выплевывает страницу 404. Так как мне заставить работать слаг перезаписи URL, чтобы при нажатии /portfolio/clientsон не возвращал страницу 404 и использовал правильный шаблон страницы?

Йоханнес Пилле
источник

Ответы:

16

Вы, кажется, нуждаетесь в «правилах частичной переписки». Подробные правила перезаписи означают, что все страницы расположены сверху, потому что WordPress не может понять разницу между страницей и публикацией. Здесь он думает, что может, потому что все URL формы portfolio/([^/]+)/из вашей portfolioтаксономии, кроме этого portfolio/clients/. Вам придется поместить это поверх правил перезаписи, чтобы оно соответствовало более общей таксономии портфеля. Возможно, вы также заставите все правила переписывания быть подробными, но это повлияет на производительность, если у вас много страниц.

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

Страница не генерирует только одно правило перезаписи, она генерирует группу:

  • (pagename)/trackback/?$
  • (pagename)/feed/(feed|rdf|rss|rss2|atom)/?$
  • (pagename)/(feed|rdf|rss|rss2|atom)/?$
  • (pagename)/page/?([0-9]{1,})/?$
  • (pagename)/comment-page-([0-9]{1,})/?$
  • (pagename)(/[0-9]+)?/?$

Вам не нужно создавать их самостоятельно, вы можете повторно использовать силу WP_Rewrite. Посмотрите на его page_rewrite_rules()метод: если мы находимся в подробном режиме, он получает список всех страниц (через page_uri_index()) и их вложений, перезаписывает %pagename%тег перезаписи и генерирует правила перезаписи для этой страницы. Мы можем сделать это тоже:

// We only generate them for this page
$page_uri = 'portfolio/clients';
// Returns site root + '%pagename%'
$page_structure = $wp_rewrite->get_page_permastruct();
// Everywhere you see %pagename% in the structure used to generate rules
// in the next step, replace it with our fixed page name
$wp_rewrite->add_rewrite_tag('%pagename%', "({$page_uri})", 'pagename=');
// This generates the group given above
$page_rewrite_rules = $wp_rewrite->generate_rewrite_rules($page_structure, EP_PAGES);

Это даст нам правила для страниц, но еще не для вложений, используемых на странице. Если вы также хотите их получить, повторите этот шаг для каждого вложения, но с помощью add_rewrite_tag('%pagename%', "({$attachment_uri})", 'attachment=')(см. page_rewrite_rules()Подробнее).

Хорошо, у нас есть правила, но теперь вам нужно каким-то образом добавить их в полную структуру перезаписи. Вы можете сделать это с помощью add_rewrite_rule(), но вы должны вызывать его для каждого правила, сгенерированного в $page_rewrite_rulesмассиве. По этой причине многие люди подключаются к rewrite_rules_arrayфильтру , так как вы можете просто изменить массив там.

add_filter('rewrite_rules_array', 'add_verbose_portfolio_clients_page');
function add_verbose_portfolio_clients_page($rewrite_rules)
{
    global $wp_rewrite;

    // The previous code snippet comes here, where we generate $page_rewrite_rules

    // Our rules have priority, they should be on top
    $rewrite_rules = array_merge($page_rewrite_rules, $rewrite_rules);

    return $rewrite_rules;
}

После того, как вы включили этот фильтр, вы должны сбросить правила перезаписи (один раз, а не по одной загрузке каждой страницы, так как это довольно тяжело). Вы можете сделать это, позвонив flush_rewrite_rules()или посетив страницу настроек «Постоянные ссылки».

Ян Фабри
источник
Отлично! Спасибо, Ян! Это сработало. Я не мог получить лучшего объяснения.