Принудительный показ страниц вместо категорий в WordPress

10 июл. 2013 г., 22:48:37
Просмотры: 22.6K
Голосов: 5

Я пытаюсь создать SILO-структуру на одном из моих сайтов WordPress.

Я всегда использовал опцию в плагине Yoast SEO "Убрать базовый префикс категории (обычно /category/) из URL категории".

Поэтому мои страницы категорий имеют такой URL: sitename.com/apple/ (где "apple" - это страница категории)

Теперь я хочу создать новую "страницу" с таким же слагом apple.

Я могу легко создать новую страницу "apple", однако, когда я перехожу по адресу sitename.com/apple/, отображается страница категории -- вместо новой созданной страницы.

Мой вопрос: Существует ли способ "переопределить" стандартный приоритет категории над страницей? Я хотел бы показывать страницу, потому что тогда у меня будет контроль над ней -- я смогу настраивать, добавлять больше контента и легко изменять их (кроме того, страницы помогут мне лучше структурировать мой сайт)

Ценю вашу помощь!

0
Все ответы на вопрос 9
7

Одно из возможных решений — не изменять базовый префикс категорий и оставить его как есть, но вместо этого модифицировать вывод ссылок на категории, удаляя базовый префикс с помощью фильтра. Конечно, это приведёт к ошибке 404, если вы не создали страницы, на которые ведут эти ссылки, поэтому необходимо создать страницу для каждой категории.

function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
    if( 'category' != $taxonomy ) return $termlink;

    return str_replace( '/category', '', $termlink );
}
add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );

Рекомендуется тщательно протестировать это решение на предмет побочных эффектов. Используйте на свой страх и риск!

РЕДАКТИРОВАНИЕ — изменение только ссылок на родительские категории:

function wpa_alter_cat_links( $termlink, $term, $taxonomy ){
    if( 'category' == $taxonomy && 0 == $term->parent ){
        return str_replace( '/category', '', $termlink );
    }
    return $termlink;
}
add_filter( 'term_link', 'wpa_alter_cat_links', 10, 3 );
11 июл. 2013 г. 06:28:52
Комментарии

Мило, это именно то, что я хотел! Не могу поверить, что это было так просто и возможно. Огромное спасибо!

Но есть проблема. Страницы подкатегорий ведут на 404. Можно ли это исправить?

Дополнительные детали: Для моих сайтов необходимы хлебные крошки. Вот формат: Главная -> Кат. 1 -> Подкат. 2 -> запись. Кат. 1 теперь это СТРАНИЦА, но подкат. 2 ведет на 404.

Sid Sid
11 июл. 2013 г. 07:39:00

вам нужно создать дочерние страницы под родительскими страницами для подкатегорий.

Milo Milo
11 июл. 2013 г. 07:42:12

Ты гений, вот кто ты. Большое спасибо. Это действительно требует много времени и усилий. Думаю, я все равно это сделаю. Но все же хотел бы узнать, могу ли я назначить только родительскую категорию как СТРАНИЦУ, а подкатегории оставить стандартными страницами категорий?

Sid Sid
11 июл. 2013 г. 09:41:33

в приведенной выше функции проверьте, равно ли $term->parent нулю. Дочерние категории будут иметь ID категории в $term->parent, а у категорий верхнего уровня это значение будет просто нулевым.

Milo Milo
11 июл. 2013 г. 18:10:18

Я понимаю, что нужно использовать if ($term->parent == 0), но не уверен, куда вставить этот код. Потратил некоторое время на поиски в Google, но не смог разобраться, как это сделать. Буду очень признателен, если вы исправите код. :)

Sid Sid
11 июл. 2013 г. 22:27:21

см. правку выше.

Milo Milo
11 июл. 2013 г. 22:38:08

Работает отлично, спасибо! Добавил in_array($term->slug, ['foo', 'bar']) чтобы применять только к тем двум категориям, для которых у меня были страницы

kero kero
22 нояб. 2018 г. 12:38:49
Показать остальные 2 комментариев
2

Я создал следующую, довольно простую функцию, чтобы при загрузке контента страницы имели более высокий приоритет, чем категории.

(Примечание: возможно, это не самый лучший, но простой способ. Я обнаружил проблему при использовании плагина Advanced Custom Fields — по умолчанию он не вставляет пользовательские поля ни старой, ни новой страницы. Добавление get_queried_object()->ID в качестве второго параметра для функции get_field() в ACF решило эту проблему. Тщательно протестируйте это в вашей среде WordPress.)

function loadPageFirst() {
    // получаем текущую категорию
    $actualCategory = get_category( get_query_var('cat') );
    // получаем страницу с таким же слагом
    $matchingPage = get_page_by_path( $actualCategory->slug );

    // Если совпадений нет, загружаем стандартный шаблон архива и завершаем выполнение (измените, если используете кастомный шаблон, например category.php)
    if (!$matchingPage) {
        include( get_template_directory() . '/archive.php');
        die();
    }

    // Создаем новый запрос с ID страницы и загружаем шаблон страницы
    query_posts( 'page_id=' . $matchingPage->ID );
    include( get_template_directory() . '/page.php');
    die();
}
add_filter( 'category_template', 'loadPageFirst' );

Вы можете добавить этот код в functions.php вашей темы. Похоже, он корректно работает с плагином Yoast SEO.

31 мая 2016 г. 17:12:05
Комментарии

Я считаю, что вам не нужно включать archive.php и die() — в зависимости от вашей темы это может не сработать. Можно просто использовать return. (Но огромное спасибо за код!)

Nabha Cosley Nabha Cosley
12 апр. 2018 г. 02:56:15

В моем случае сработало не полностью, например, заголовок страницы отображался некорректно.

kero kero
22 нояб. 2018 г. 12:38:18
2

Вот очень простое и полностью рабочее решение: https://stackoverflow.com/questions/32310453/make-wordpress-use-the-page-instead-of-category

Для полноты картины:

Исходные данные

  • example.com — домен
  • У меня есть страница WordPress под названием "foobar" с контентом
  • У меня есть категория записей WordPress под названием "foobar"
  • У меня есть запись WordPress с заголовком "fun things to do with foobars", и для неё установлена категория "foobar"

Ожидания

  • Когда я перехожу на example.com/foobar, я хочу видеть страницу о foobars, а не страницу категории WordPress, которая показывает все записи блога с этой категорией.
  • Когда я перехожу к записи о "fun things", URL должен быть example.com/foobar/fun-things-to-do-with-foobars/

Настройка

Вот моя настройка (она не требует дополнительных плагинов или правки кода). У меня установлены плагины WP Rocket и Yoast, на которых я сосредоточусь в этой теме.

  1. WP Dashboard → Настройки → Постоянные ссылки

  2. Выберите "Произвольная структура" и введите /%category%/%postname%/ в поле

  3. На той же странице измените "Префикс категорий" на одну точку "." (без кавычек, просто точка)

У меня установлен Yoast, который я настроил на переопределение настроек постоянных ссылок, но я считаю, что это помешало моей задаче.

  1. WP Dashboard → SEO → Дополнительно → Постоянные ссылки (вкладка)

  2. "Изменение URL → Удалить префикс категорий..." = Оставить

  3. Затем нужно очистить кеш. Я использую WP Rocket для кеширования, поэтому я очистил кеш, и теперь всё работает так, как должно.

Примечание: не забудьте сохранить изменения после шагов 3 и 5

18 сент. 2018 г. 13:14:06
Комментарии

по-прежнему отлично работает в 2021 году

Dark Dark
30 сент. 2021 г. 14:35:35

У меня это не сработало с подкатегорией — по какой-то причине происходил редирект на запись, у которой был похожий слаг, как у моей подкатегории.

Robbiegod Robbiegod
4 нояб. 2022 г. 22:29:46
3

Зависит от ситуации. Если вы пытаетесь сделать две разные страницы с одинаковым URL — это плохая идея. Но если вас не волнуют страницы категорий, вы можете перенаправлять их на свои страницы.

 RedirectMatch 301 ^/category/(.*)$ /$1

Этот код нужно добавить в файл .htaccess, и он будет перенаправлять /category/страница на /страница/

10 июл. 2013 г. 23:02:44
Комментарии

Спасибо! Однако, как я уже упоминал, у меня нет базовой категории, прикрепленной к URL. И я не могу использовать традиционный 301 редирект, так как оба URL одинаковые.

Sid Sid
10 июл. 2013 г. 23:14:03

?? Извините, я не понимаю

JMau JMau
10 июл. 2013 г. 23:20:29

URL страницы и URL категории одинаковые. Я делаю это "намеренно", чтобы создать SILO структуру, но WordPress показывает страницу категории вместо новой страницы. Надеюсь, теперь стало понятнее.

Sid Sid
11 июл. 2013 г. 05:20:44
6

"WordPress-подход" к решению этой задачи заключается в создании пользовательского PHP-шаблона для страницы категории и применении ваших настроек там, а не через создание уникальной "Страницы".

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

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

11 июл. 2013 г. 04:37:25
Комментарии

Проблема, на мой взгляд, в том, что WordPress обрабатывает "страницы" иначе. Они ранжируются лучше, чем традиционные страницы категорий. Многие SEO-специалисты делают то, о чем я спросил выше — полностью удаляют категорию и заменяют её страницами.

Sid Sid
11 июл. 2013 г. 05:23:08

Вероятно, стоит подробнее объяснить, как добавить этот шаблон страницы (подсказка: иерархия шаблонов) и т.д.

kaiser kaiser
11 июл. 2013 г. 05:24:34

@Sid - если контент идентичен, почему архив категории должен ранжироваться иначе, чем страница?

Milo Milo
11 июл. 2013 г. 06:10:02

@Milo - Содержание не будет идентичным, только URL. На страницах будет гораздо более структурированный контент и ссылки на связанные материалы.

Sid Sid
11 июл. 2013 г. 07:02:15

@Sid, я хотел сказать, что аналогичных результатов можно добиться через шаблон категории, подтягивая дополнительный контент из других источников. Быстрый способ реализовать это — плагин Advanced Custom Fields, который позволяет добавлять дополнительный контент на страницы администрирования терминов таксономий — WYSIWYG-редакторы, поля связей и т.д.

Milo Milo
11 июл. 2013 г. 07:37:18

@Milo, я тоже рекомендую Advanced Custom Fields для этого. Вы также можете использовать WordPress SEO от Yoast для изменения мета-описаний и заголовков, тем самым достигая тех же SEO-преимуществ, что и у обычных страниц.

qccreative qccreative
5 сент. 2013 г. 19:29:59
Показать остальные 1 комментариев
1

Сначала удалите категорию в Yoast Установите для категории no-index в Yoast, но перед этим структура постоянных ссылок должна быть настроена как /%category%/%postname%/

14 апр. 2019 г. 05:36:56
Комментарии

Это работает, но когда вы добавляете страницу с совпадающим ярлыком (slug) к одной из ваших категорий, категория всё равно имеет приоритет. Я хочу, чтобы страница имела приоритет.

Robbiegod Robbiegod
4 нояб. 2022 г. 22:22:33
1

Извините, но у меня недостаточно репутации, чтобы комментировать ответ @bencergazda.

Я считаю это лучшим решением. Но у меня возникла ошибка с отображением изображения в шапке темы, так как не получался правильный ID записи.

Для решения я добавил строку в код: "global $post; $post->ID = $matchingPage->ID;"

Результат:

function loadPageFirst() {
    // получаем текущую категорию
    $actualCategory = get_category( get_query_var('cat') );
    // получаем страницу с таким же ярлыком
    $matchingPage = get_page_by_path( $actualCategory->slug );

    // Если совпадений нет, загружаем стандартный шаблон архива и выходим (измените, если используете кастомный шаблон, например category.php)
    if (!$matchingPage) {
        include( get_template_directory() . '/archive.php');
        die();
    }

    // Создаем новый запрос с ID страницы и загружаем шаблон страницы
    global $post; $post->ID = $matchingPage->ID;
    query_posts( 'page_id=' . $matchingPage->ID );
    include( get_template_directory() . '/page.php');
    die();
}
add_filter( 'category_template', 'loadPageFirst' );

С наилучшими пожеланиями

23 окт. 2020 г. 14:15:26
Комментарии

Это не совсем работает. Когда я пробую этот метод, он всё равно загружает "категорию", но использует только соответствующую страницу для отображения контента. Мне нужно, чтобы загружалась именно страница. Есть ли способ сделать это?

Robbiegod Robbiegod
4 нояб. 2022 г. 22:21:41
0

Извините, но у меня также недостаточно репутации, чтобы комментировать ответ @bencergazda.

Я внес некоторые изменения в его функцию. Убрал часть, которая загружала страницу категории (не требуется), и добавил иерархию страниц:

function loadPageFirst( $file ) {
    // получаем текущую категорию
    $actualCategory = get_category( get_query_var('cat') );
    // получаем страницу с таким же ярлыком (slug)
    $matchingPage = get_page_by_path( $actualCategory->slug );

    if ( ! $matchingPage ) {
        return $file;
    }

    // Создаем новый запрос с ID страницы и загружаем шаблон страницы
    query_posts( 'page_id=' . $matchingPage->ID );
    $page_template = get_page_template_slug( $matchingPage->ID ) ? get_page_template_slug( $matchingPage->ID ) : null;
    $pages = array(
        $page_template,
        'page-' . $actualCategory->slug . '.php',
        'page-' . $matchingPage->ID . '.php',
        'page.php',
        'singular.php',
        'index.php',
    );
    foreach ( $pages as $page ) {
        $file = get_theme_file_path( $page );
        if ( $page === null || ! file_exists( $file ) ) {
            continue;
        }

        return $file;
    }
}
add_filter( 'category_template', 'loadPageFirst' );
16 июн. 2023 г. 15:11:46
1

Это потрясающе. Прошло ровно 10 лет с момента публикации, а решение до сих пор работает идеально. Интересно, возможно ли аналогичное решение для меток? Я хотел бы заменить архивные страницы меток на реальные страницы, которые дают мне больше контроля.

Может кто-нибудь помочь мне в этом? Заранее спасибо!

17 авг. 2023 г. 05:31:29
Комментарии

Пожалуйста, не добавляйте "спасибо" в качестве ответа. Когда у вас будет достаточно репутации, вы сможете голосовать за вопросы и ответы, которые вам помогли. - Из обзора

bueltge bueltge
18 авг. 2023 г. 08:40:26