Вопрос или проблема
Я пытаюсь переопределить стандартную структуру URL в WordPress для вложений, где, если они прикреплены к посту, URL имеет вид /post-slug/attachment-slug/, а если нет, то просто /attachment-slug/.
Я бы хотел, чтобы вложения вели себя как посты, то есть чтобы у них был архив, и все URL указывали на /archive-slug/attachment-slug/.
Я нашел новый (кажется, с версии 4.4) фильтр, который позволяет изменять параметры типа поста, но он, похоже, не работает, как заявлено;
add_filter('register_post_type_args', function ($args, $postType) {
if ($postType == 'attachment'){
$args['has_archive'] = true;
$args['rewrite'] = [
'slug' => 'media'
];
}
return $args;
}, 10, 2);
Если я использую var_dump($args)
, они действительно выглядят правильно (наследие архива установлено в true и т.д.), но это, похоже, не имеет никакого эффекта на URL.
Это может не быть удивительным, если этот комментарий разработчиков верен; “Не относится к встроенным типам постов” https://core.trac.wordpress.org/changeset/34242.
Так как же я могу этого добиться?
Я также пытался просто изменить объект типа поста в хуке инициализации, но это не работает:
$obj = get_post_type_object('attachment');
$obj->has_archive = true;
$obj->rewrite = [
'slug' => 'media'
];
Это не тестировалось, извините за это, но я размышляю вслух, пробовали ли вы повторно зарегистрировать тип поста позже? Или сбросить правила перезаписи после вашей первой попытки с flush_rewrite_rules();
?
function change_attachment_post_type() {
$args = get_post_type_object('attachment');
$args->has_archive = true;
$args->rewrite = [
'slug' => 'media'
];
register_post_type($args->name, $args);
// Как временная едисновременна, удалите после первого сброса
flush_rewrite_rules();
}
add_action('init', 'change_attachment_post_type', 20);
Вот мое решение. Сначала нужно изменить параметры типа поста для вложений (как упоминалось в вопросе):
add_filter( 'register_post_type_args', 'change_attachment_post_type_args', 10, 2 );
function change_attachment_post_type_args( $args, $post_type ){
//Включите страницу архива вложений
если( 'attachment' == $post_type ){
$args['has_archive'] = 'media';//это slug
$args['rewrite'] = true;
}
return $args;
}
Затем измените post_status
на inherit
внутри WP_Query
, потому что значение по умолчанию для post_status
– это publish
, но все вложения имеют статус inherit
:
add_action( 'pre_get_posts', 'get_all_posts_attachment' , 10, 1);
function get_all_posts_attachment( $query ) {
if( is_post_type_archive('attachment') && 'attachment' == $query->get('post_type') )
{
$query->set( 'post_status', 'inherit' );
}
return $query;
}
Ответ или решение
Для решения задачи изменения структуры URL вложений в WordPress на более удобную и организованную схему, требуется учитывать особенности работы системы управления контентом с типами записей и rewrite rules. В стандартной конфигурации WordPress URLs для вложений формируются в зависимости от привязки к постам. Если вложение прикреплено к посту, URL будет иметь вид /post-slug/attachment-slug/, в противном случае — /attachment-slug/.
Для достижения требуемого результата, а именно создания архивной страницы для вложений и изменения структуры URL на /archive-slug/attachment-slug/, следует провести загрузку настроек для типа записи ‘attachment’ с помощью фильтра и последующей обработки запроса.
Шаги для реализации:
1. Модификация аргументов типа записи ‘attachment’
Используйте фильтр register_post_type_args
для изменения конфигурации attachment
. Ваше решение может быть следующим:
add_filter('register_post_type_args', 'change_attachment_post_type_args', 10, 2);
function change_attachment_post_type_args($args, $post_type) {
if ('attachment' === $post_type) {
$args['has_archive'] = 'media'; // Определяем архивную страницу
$args['rewrite'] = true; // Активируем перезапись
}
return $args;
}
2. Обработка статуса постов в WP_Query
По умолчанию, WordPress использует статус записи ‘publish’. Однако для вложений статусы отличаются и чаще всего это ‘inherit’. Для корректного отображения и обработки архива вложений следует добавить фильтр, который изменяет post_status
:
add_action('pre_get_posts', 'get_all_posts_attachment', 10, 1);
function get_all_posts_attachment($query) {
if (is_post_type_archive('attachment') && 'attachment' === $query->get('post_type')) {
$query->set('post_status', 'inherit'); // Устанавливаем статус 'inherit' для вложений
}
return $query;
}
3. Сброс rewrite правил
Не забудьте сбросить правила перезаписи, что необходимо для обновления структуры URL. Выполняется один раз:
function change_attachment_post_type() {
add_action('init', function() {
flush_rewrite_rules();
}, 20);
}
Подведение итогов:
Эти изменения позволят реализовать необходимую структуру URL для вложений, добавив их на архивную страницу, задав её на уровне настроек и структуры permalink. В результате ваши вложения будут иметь хорошо организованную и логичную структуру, что позволит пользователям и поисковым системам легче находить и обрабатывать контент.
Помните, что для SEO это может поднять рейтинг сайта, улучшив доступность содержимого для поисковых систем, таким образом, ваша аудитория получит более удобный пользовательский опыт.