Как использовать архив произвольного типа записей в качестве главной страницы?
Я хочу использовать архив произвольного типа записей в качестве главной страницы сайта, чтобы
http://the_site.com/
отображался как архив произвольного типа записей согласно моему файлу archive-{post-type}.php
.
В идеале я хотел бы изменить запрос, используя is_front_page()
в моем файле functions.php
. Я попробовал следующее, установив страницу "Главная" как главную страницу сайта:
// Добавляем фильтр для модификации запроса
add_filter('pre_get_posts', 'my_get_posts');
function my_get_posts($query){
global $wp_the_query;
if(is_front_page()&&$wp_the_query===$query){
$query->set('post_type','album');
$query->set('posts_per_page',-1);
}
return $query;
}
но главная страница возвращает содержимое страницы "Главная" и, похоже, игнорирует пользовательский запрос.
Что я делаю неправильно? Есть ли лучший способ решения этой задачи?
После того, как вы установили статическую страницу в качестве главной, вы можете добавить этот код в ваш файл functions.php
, и всё заработает. Это также обеспечит правильный вызов шаблона archive-POSTTYPE.php
.
add_action("pre_get_posts", "custom_front_page");
function custom_front_page($wp_query){
//Убедимся, что этот фильтр не применяется в админ-панели
if(is_admin()) {
return;
}
if($wp_query->get('page_id') == get_option('page_on_front')):
$wp_query->set('post_type', 'CUSTOM POST TYPE NAME HERE');
$wp_query->set('page_id', ''); //Очищаем
//Устанавливаем свойства, описывающие страницу, чтобы отразить,
//что мы на самом деле не отображаем статическую страницу
$wp_query->is_page = 0;
$wp_query->is_singular = 0;
$wp_query->is_post_type_archive = 1;
$wp_query->is_archive = 1;
endif;
}

Этой функции нужно добавить if(is_admin()) return;
в самом начале, иначе это нарушит работу административной области.

Хотя это сработало для меня, в результате исчезли мои основное и дополнительное меню.

Почти правильно. Этот код изменяет все wp_queries, поэтому нужно использовать if ( is_home() ) вместо if ($wp_query->get.....)

Я использую такой же код, но в своем пользовательском шаблоне страницы вместо главной, и он не показывает результатов (как будто не было добавлено ни одного произвольного типа записи). Есть идеи?

Это решение не поддерживает постраничную навигацию. Любой URL с /page/2 по-прежнему показывает первые 10 записей.

Переименуйте архив вашего CPT в home.php
Затем используйте pre_get_posts для изменения запроса главной страницы, чтобы отображались только CPT
function wpsites_home_page_cpt_filter($query) {
if ( !is_admin() && $query->is_main_query() && is_home() ) {
$query->set('post_type', array( 'your-cpt' ) );
}
}
add_action('pre_get_posts','wpsites_home_page_cpt_filter');
Замените your-cpt на название вашего пользовательского типа записи.

Привет, Eli, добро пожаловать на WPSE. "Ответы" предназначены для ответа на первоначальный вопрос (сайты stackexchange не являются форумами с ветвящимися обсуждениями). Это было бы гораздо уместнее в виде комментария.

Этот вариант работает лучше для меня, переопределяя и записи блога, и статические страницы в Настройки > Чтение > Главная страница отображает:
<?php
/**
* Устанавливает архив произвольного типа записи в качестве главной страницы.
*
* @since 1.0.0
*/
function ql_set_as_front_page( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( ql_is_front_page( $query ) ) {
$query->set( 'page_id', '' );
$query->is_page = false;
$query->is_singular = false;
$query->set( 'post_type', 'MYCPT' );
$query->is_archive = true;
$query->is_post_type_archive = true;
}
}
add_action( 'pre_get_posts', 'ql_set_as_front_page' );
/**
* Взято из WP_Query::is_front_page и адаптировано для сравнения page_on_front с ID текущей страницы.
*
* @since 1.0.0
*
* @param object $query Основной WP Query.
*/
function ql_is_front_page( $query ) {
if ( 'posts' == get_option( 'show_on_front') && $query->is_home() )
return true;
elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $query->get('page_id') == get_option( 'page_on_front' ) )
return true;
else
return false;
}
Я использую это в сочетании с переопределением шаблона с помощью фильтров front_page_template
и home_template
, чтобы возвращать пользовательский шаблон.

Для меня это ломает пагинацию: независимо от того, выбран ли индекс или статическая страница в качестве домашней, ссылки пагинации отображаются, но при переходе на страницу 2 я получаю:
- в случае индексной страницы (по умолчанию): страницу 404
- в случае статической страницы: те же результаты, что и на странице 1: аргумент "paged" интерпретируется для отображения пагинации типа страницы, а не списка записей.
Думаю, здесь нужны дополнительные правила перезаписи, чтобы корректно обработать аргумент "paged" и передать его правильно.
В любом случае, кастомный шаблон страницы с дополнительными правилами перезаписи должен решить проблему.
