Удаление слага типа записи из URL в WordPress
Не смог найти полезного ответа на этот вопрос. Я осознаю проблемы с конфликтами и все сложности, которые это может вызвать, мне интересно ВОЗМОЖНО ли это, а не РЕКОМЕНДУЕТСЯ ли. Для этого потребуется перезапись правил WP, это я понимаю.
Допустим, у нас есть тип записи "events". Я хочу, чтобы страница отдельного события имела URL http://domain.com/nazvanie-sobytiya, а не http://domain.com/events/nazvanie-sobytiya. Есть идеи, как это реализовать?

Вот как можно выполнить первую часть задачи — убрать slug типа записи (CPT) из ссылки на пост (например, для типа записи news).
function df_custom_post_type_link( $post_link, $id = 0 ) {
$post = get_post($id);
if ( is_wp_error($post) || 'news' != $post->post_type || empty($post->post_name) )
return $post_link;
return home_url(user_trailingslashit( "$post->post_name" ));
}
add_filter( 'post_type_link', 'df_custom_post_type_link' , 10, 2 );
Теперь нужно добавить правила перезаписи (rewrite rules) для 'news', иначе вы получите ошибку 404.
Добавьте правило перезаписи следующим образом:
function df_custom_rewrite_rule() {
add_rewrite_rule('(.*?)$', 'index.php?news=$matches[1]', 'top');
}
add_action('init', 'df_custom_rewrite_rule');
Затем необходимо сбросить правила перезаписи. Для этого перейдите в Настройки — Постоянные ссылки и сохраните изменения.

Вам не следует добавлять правила перезаписи на init. Вместо этого вам следует добавить ваше правило к текущим правилам.

@Chris_O Можете уточнить? Как именно можно добавить правило к текущим правилам?

После добавления этого кода все мои страницы с URL вида http://example.com/about-us перестали работать? Есть какие-то решения для этой проблемы?

Вы можете попробовать этот плагин (http://wordpress.org/extend/plugins/remove-slug-from-custom-post-type/) для удаления слага, но он будет работать только если структура постоянных ссылок "/%postname%/".

Этот плагин просто потрясающий! Я опытный пользователь этого плагина и настоятельно рекомендую его!
Вот ссылка на сайт плагина, где он подробно объясняется http://www.ultimatewebtips.com/remove-slug-from-custom-post-type/

Отличный плагин, который содержит именно ту функцию, которую я искал. Решение @bartosz относится к конкретному CPT, хотя из него можно понять общую идею. После изучения этого плагина все стало понятно, спасибо!

Похоже, этого плагина больше нет в репозитории WordPress. Однако вы можете использовать этот плагин вместо него... https://wordpress.org/plugins/remove-cpt-base/

// Регистрация нового типа записи (CPT)
function register_cpt_type() {
register_post_type('cpt', array(
'rewrite' => array("slug" => "/cpt", "with_front" => false),
));
}
add_action('init', 'register_cpt_type')
// Добавление правила перезаписи URL
function cpt_rewrite_rule() {
add_rewrite_rule('(.*?)$', 'index.php?cpt=$matches[1]', 'top');
}
add_action('after_theme_setup', 'cpt_rewrite_rule');
обновите/сбросьте перезапись URL, затем отредактируйте файл .htaccess
RewriteRule ^cpt/(.+)$ /$1 [R=301,L]

Вы всегда можете подключиться к хуку "parse_request", чтобы проверить, существует ли пользовательский тип записи с запрашиваемым именем, и затем соответствующим образом изменить query_vars. Вам понадобится что-то вроде ответа @Bartosz для генерации постоянных ссылок в дополнение:
add_filter('parse_request', "t21_parse_request" , 1, 1);
function t21_parse_request($wpobj)
{
$query_vars = $wpobj->query_vars;
$slug = $query_vars['pagename'];
$posts = get_posts(array(
"post_type" => "event",
"post_name" => $slug
));
if($posts)
{
//мы знаем, что запись типа "event" существует, поэтому изменяем query_vars
//сначала удаляем 'page' и 'pagename'
unset($query_vars['page']);
unset($query_vars['pagename']);
//теперь перестраиваем query_vars
$query_vars['post_type'] = "event"; //имя CPT
$query_vars['name'] = $slug;
$query_vars['event'] = $slug; //снова - это создает строку запроса "event=myevent"
}
else
{
//просто возвращаем $wpobj, так как мы знаем, что "event" не существует
return $wpobj;
}
}
Однако это предполагает, что у вас не будет записей с таким же именем, как имя записи, иначе запись никогда не появится, так как сначала будет совпадение с типом event.
