Удалите слаг из URL-адресов сообщений произвольного типа
-
-
Думаю,я ломаю голову,зачем тебе это нужно?Смущенный.I guess I'm scratching my head as to why you would want to do that? Confused.
- 0
- 2017-05-29
- Michael Ecklund
-
@MichaelEcklund,потому что любой CPT,который используется для создания общедоступных веб-страниц,имеет принудительное имя слага в URL-адресе.На самом деле существует множество разработчиков WP,которые хотят безопасно удалить слаг.@MichaelEcklund because any CPT that is used to create public facing web pages has a forced slug name in the URL. There is actually a lot of wp devs looking to remove the slug safely.
- 3
- 2017-07-18
- Ben Racicot
-
10 ответ
- голосов
-
- 2015-09-30
Следующий код будет работать,но вы просто должны иметь в виду,что конфликты могут возникнуть легко,если слаг для вашего пользовательского типа сообщения такой же,как слаг страницы или сообщения ...
Сначала мы удалим слаг из постоянной ссылки:
function na_remove_slug( $post_link, $post, $leavename ) { if ( 'events' != $post->post_type || 'publish' != $post->post_status ) { return $post_link; } $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link ); return $post_link; } add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );
Недостаточно просто удалить пулю. Прямо сейчас вы получите страницу 404,потому что WordPress ожидает такого поведения только от постов и страниц. Вам также необходимо добавить следующее:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { $query->set( 'post_type', array( 'post', 'events', 'page' ) ); } } add_action( 'pre_get_posts', 'na_parse_request' );
Просто измените "события" на свой собственный тип сообщения,и готово. Возможно,вам потребуется обновить постоянные ссылки.
The following code will work, but you just have to keep in mind that conflicts can happen easily if the slug for your custom post type is the same as a page or post's slug...
First, we will remove the slug from the permalink:
function na_remove_slug( $post_link, $post, $leavename ) { if ( 'events' != $post->post_type || 'publish' != $post->post_status ) { return $post_link; } $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link ); return $post_link; } add_filter( 'post_type_link', 'na_remove_slug', 10, 3 );
Just removing the slug isn't enough. Right now, you'll get a 404 page because WordPress only expects posts and pages to behave this way. You'll also need to add the following:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { $query->set( 'post_type', array( 'post', 'events', 'page' ) ); } } add_action( 'pre_get_posts', 'na_parse_request' );
Just change "events" to your custom post type and you're good to go. You may need to refresh your permalinks.
-
Благодарю.Как вы думаете,это лучше,чем переписывать вручную?Я видел это решение,и оно может сдерживать упомянутые вами конфликты?thanks. Do you think this is better than creating the rewrites manually? I've seen that solution and it may keep the conflicts you mention at bay?
- 0
- 2015-10-01
- Ben Racicot
-
Я думаю,что это хорошее автоматизированное решение,если вы уверены,что не создадите конфликтов.Это не лучшее решение,если вы предоставляете это ... скажем,клиенту,который не разбирается в технологиях.I think this is a good automated solution if you're confident that you won't be creating conflicts. This isn't a good solution if you're providing this to... let's say a client that isn't tech savvy.
- 0
- 2015-10-01
- Nate Allen
-
не могли бы вы обновить,как использовать этот код для нескольких типов сообщенийcan you please update, how to use this code for multiple post types
- 1
- 2016-01-25
- Abin
-
Это не удается сnginx,потому что условие `2!=Count ($ query-> query)`.Сnginx вы можете иметь $ query-> query как `array ('page'=> '','name'=> '...','q'=> '...')`.Итак,@NateAllen,в чем смысл этого условия?It fails with nginx because the condition `2 != count( $query->query )`. With nginx, you can have $query->query as `array('page' => '', 'name' => '...', 'q' => '...')`. So @NateAllen, what is the meaning of that condition?
- 1
- 2016-11-08
- Fabio Montefuscolo
-
Нам нужно что-то получше.Поддержка удаления встроенного ярлыка,чтобы в дальнейшем мы не могли создавать конфликтующие URL-адреса.Как обычные сообщения и страницы создают свои URL-адреса.We need something better than this. Support to remove the slug built in so that we cannot create conflicting URLs later on. The way regular posts and pages create their URLs.
- 3
- 2017-07-18
- Ben Racicot
-
Это только у меня или это нарушает некоторые условные теги wordpress,такие какis_single () иis_singular ()?Is it just me or does this break some wordpress conditional tags like is_single() and is_singular()?
- 4
- 2017-07-18
- rob-gordon
-
Это решение,к сожалению,привело к появлению некоторых неработающих ссылок,и мой блог перестал показывать сообщения и стал обычной страницей.См. Лучшее решение ниже от Мэтта Киса.This solution unfortunately caused some broken links and my blog stopped showing posts and was just a normal page. See a better solution below by Matt Keys.
- 1
- 2018-10-08
- Radley Sustaire
-
Этот код предполагает,что имяpost_type такое же,как и у настраиваемого типа сообщения slug,что не обязательно должно быть в каждом случае.Но в остальном отличное решение,хотя я согласен,что родное решение WP было бы лучше.This code assumes that the `post_type` name is the same as the custom post type `slug` which doesn't necessarily have to be in every case. But for the rest, great solution although I agree a native WP solution would be better.
- 0
- 2019-06-14
- Marco Miltenburg
-
single- {cpt} .php перестает работать при таком подходеsingle-{cpt}.php stops working using this approach
- 0
- 2020-01-05
- Saleh Mahmood
-
Для тех,у кого есть проблема с приведенным выше кодом,он отлично подойдет,если вы замените вторую функцию (**functionna_parse_request () **) той,которая найдена в этом [ответе] (https://wordpress.stackexchange.com/a/292379/175093).Не забудьте изменить код своим собственным именем типа пользовательского сообщения.For those who have a problem with the code above, it works like a charm if you replace the second function ( **function na_parse_request()** ) by the one found on this [answer](https://wordpress.stackexchange.com/a/292379/175093). Dont forget to modify the code with your own Custom Post Type name.
- 0
- 2020-04-03
- PhpDoe
-
Я использовал этот красивый код до выхода WP 5.2.После обновления этот код начинает давать сбой в моем плагине Custom Post Type и Advanced Custom Fields,потому что,я думаю,они используют ту же функциюpre_get_posts,поэтому вместо Advanced Custom Field Groups я вижу свои пользовательские сообщения в этом плагине..Тоже не работает с плагином CPT UI - больше не может создавать новые сообщения,они не отображаются в списке после их создания.Пожалуйста помоги!!I have been using this nice code until WP 5.2 came. After the update this code starts to fail on my Custom Post Type plugin and Advanced Custom Fields plugin, because, I think, they are using the same pre_get_posts function, so instead of Advanced Custom Field Groups I see my custom posts in this plugin... Also fails with CPT UI plugin - can not create new posts anymore, they are not appearing in list after creating them. Please help!!
- 0
- 2020-05-04
- Gediminas
-
Это сработало для одиночного типа сообщения.Как использовать код для нескольких типов сообщений?It worked for single post type. How to use the code for multiple post type?
- 0
- 2020-07-02
- Swaranan Singha Barman
-
- 2017-04-12
Введите следующий код в регистрацию таксономии.
'rewrite' => [ 'slug' => '/', 'with_front' => false ]
Самое важное,что нужно сделать после изменения кода
После того как вы изменили документ таксономии произвольного типа сообщения,попробуйте перейти в Настройки> Постоянные ссылки и повторно сохранить настройки ,иначе вы не получите страницу 404.найдено.
Write following code into the taxonomy registration.
'rewrite' => [ 'slug' => '/', 'with_front' => false ]
Most important thing that you have to do after code changing
After you’ve altered your custom post type taxonomy document, try to go to Settings > Permalinks and re-save your settings, else you will get 404 page not found.
-
Это действительно работает,я не знаю,как этого раньше никто не заметил.Конечно,это может мешать работе других страниц,если у них такая же постоянная ссылка,но в противном случае это отличное решение.This actually works, i don't know how no one noticed this before. Of course this can interfere with other pages if they have same permalink, but if not this is a great solution.
- 0
- 2017-07-31
- Aleksandar Đorđević
-
Пробовал это.Это дает желаемый результат для моих ссылок пользовательского типа сообщений.Однако он «ловит» все ярлыки типа POST или PAGE и пытается разрешить их как URL-адрес для моего пользовательского типа сообщения,а затем 404.(да,я сохранил постоянные ссылки).Tried this out. It gives the desired result for my custom post type links. However it 'catches' all POST or PAGE post type slugs and tries to resolve them as a URL for my custom post type, then 404s. (yes I've saved permalinks).
- 6
- 2017-10-05
- Matt Keys
-
Может быть один и тот же слаг для любой страницы и произвольного типа сообщения,измените заголовок страницы и затем проверьте ..There might be the same slug of any page and custom post type, change your page slug and then check..
- 0
- 2017-10-11
- Mayank Dudakiya
-
Это не работает.Выдает 404,даже если вы обновили постоянные ссылки.This doesn't work. Gives 404 even when you've updated permalinks.
- 5
- 2017-11-12
- Christine Cooper
-
@ChristineCooper Вы должны выполнить этот шаг После того как вы изменили документ таксономии произвольного типа записей,попробуйте перейти в «Настройки»> «Постоянные ссылки» и повторно сохраните настройки,иначе вы получите страницу 404,которая не найдена.@ChristineCooper You have to follow this step After you’ve altered your custom post type taxonomy document, try to go to Settings > Permalinks and re-save your settings, else you will get 404 page not found.
- 0
- 2017-11-15
- Mayank Dudakiya
-
Как я подчеркнул в своем последнем комментарии,вы получите ошибку 404 даже * после * обновления постоянных ссылок.Пожалуйста,попробуйте сами.As I highlighted in my last comment, you will get an 404 error even *after* you have updated permalinks. Please give it a try yourself.
- 0
- 2017-11-15
- Christine Cooper
-
Работает как шарм,особенно при чтении всего сообщения,включая часть «повторно сохранить настройки».+1Works like a charm, especially when reading the whole message, including the "re-save your settings" part. +1
- 0
- 2018-01-25
- davewoodhall
-
Опять же,даже после повторного сохранения настроек постоянной ссылки сообщения и страницы больше не работают (404)Again, even after re-saving the permalink settings, posts and pages no longer work (404)
- 3
- 2018-02-13
- amklose
-
Это решение работает для удаления слага из URL.Но страницы архива больше не работают.This solution works for removing the slug from URL. But the archive pages don't work anymore.
- 1
- 2018-09-25
- Annapurna
-
Как заявляли другие,это действительно работает для самих постов CPT.Но теперь это вызывает ошибку 404 для обычных страниц.As others have stated, this does work for the CPT posts themselves. But it's causing a 404 for regular Pages now.
- 0
- 2019-07-03
- Garconis
-
- 2015-09-30
Я пытался выяснить это не так давно,и короткий ответ из того,что я знаю,- нет .По крайней мере,не из аргументов перезаписи.
Длинное объяснение становится очевидным,если вы посмотрите на фактический код
register_post_type
в wp-includes/post.php строка 1454 :add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );
Вы можете видеть,что это префиксы
$args->rewrite['slug']
к тегу перезаписи%$post_type%
.Можно было подумать: «Давай просто установим slug наnull
then»,пока вы не посмотрите на несколько строк вверх:if ( empty( $args->rewrite['slug'] ) ) $args->rewrite['slug'] = $post_type;
Вы можете видеть,что функция always ожидает непустое значение заголовка и в противном случае использует тип сообщения.
I tried to figure this out not long ago and the short answer from what I know is no. Not from within the rewrite argument at least.
The long explanation becomes apparent if you look at the actual code of
register_post_type
in wp-includes/post.php line 1454:add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );
You can see it prefixes
$args->rewrite['slug']
to the%$post_type%
rewrite tag. One could think "let's just set the slug tonull
then" until you look a few lines up:if ( empty( $args->rewrite['slug'] ) ) $args->rewrite['slug'] = $post_type;
You can see that the function always expects a slug value that is not empty and otherwise uses the post type.
-
Спасибо @JanBeck.Есть ли серьезная причина для этого?Почему бы не взломать этот основной файл с условием,чтобы исключить определенные типы сообщений из этого правила?Thanks @JanBeck . Is there a major reason for this to exist? Why not hack this core file with a conditional to omit certain post types from this rule?
- 0
- 2015-09-30
- Ben Racicot
-
Вы должны вручить ответ Яну Беку.WordPress нужен слагpost_type для правильной маршрутизации запросов.Это правило предотвращает конфликты имен между собственными страницами WP (которые отображаются без ярлыка) и любыми настраиваемыми типами сообщений.Если вы взломаете слизняк,WordPress не узнает разницы между страницей с именем «пикник» и событием (произвольный тип сообщения) с именем «пикник».You should award the answer to Jan Beck. WordPress needs the post_type slug to route requests properly. This rule prevents naming conflicts between native WP pages (which render without the slug) and any custom defined post types. If you hack the slug out then WordPress won't know the difference between a page named "picnic" and an event (custom post type) named "picnic".
- 9
- 2015-09-30
- dswebsme
-
@dswebsme Согласен,но бывают ситуации,когда вам обязательно нужно изменить URL.Итак,кроме того,почему вы не можете изначально и не должны,как вы это делаете эффективно?@dswebsme Agreed, but there are situations where you absolutely must change the URL. So other than why you can't natively and shouldn't, how do you do so efficiently?
- 3
- 2015-10-01
- Ben Racicot
-
- 2015-10-02
В ответ на мой предыдущий ответ : вы,конечно,можете установить для параметра
rewrite
значениеfalse
при регистрации нового типа сообщения и самостоятельно обрабатывать правила перезаписи<?php function wpsx203951_custom_init() { $post_type = 'event'; $args = (object) array( 'public' => true, 'label' => 'Events', 'rewrite' => false, // always set this to false 'has_archive' => true ); register_post_type( $post_type, $args ); // these are your actual rewrite arguments $args->rewrite = array( 'slug' => 'calendar' ); // everything what follows is from the register_post_type function if ( is_admin() || '' != get_option( 'permalink_structure' ) ) { if ( ! is_array( $args->rewrite ) ) $args->rewrite = array(); if ( empty( $args->rewrite['slug'] ) ) $args->rewrite['slug'] = $post_type; if ( ! isset( $args->rewrite['with_front'] ) ) $args->rewrite['with_front'] = true; if ( ! isset( $args->rewrite['pages'] ) ) $args->rewrite['pages'] = true; if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive ) $args->rewrite['feeds'] = (bool) $args->has_archive; if ( ! isset( $args->rewrite['ep_mask'] ) ) { if ( isset( $args->permalink_epmask ) ) $args->rewrite['ep_mask'] = $args->permalink_epmask; else $args->rewrite['ep_mask'] = EP_PERMALINK; } if ( $args->hierarchical ) add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" ); else add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" ); if ( $args->has_archive ) { $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive; if ( $args->rewrite['with_front'] ) $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; else $archive_slug = $wp_rewrite->root . $archive_slug; add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' ); if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) { $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); } if ( $args->rewrite['pages'] ) add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' ); } $permastruct_args = $args->rewrite; $permastruct_args['feed'] = $permastruct_args['feeds']; add_permastruct( $post_type, "%$post_type%", $permastruct_args ); } } add_action( 'init', 'wpsx203951_custom_init' );
Вы можете видеть,что теперь вызов
add_permastruct
больше не включает ярлык. Я протестировал два сценария:- Когда я создавал страницу с ярлыком «календарь»,эта страница перезаписывалась архивом типа сообщений,который также использовал ярлык «календарь».
- Когда я создал страницу с ярлыком «my-event» и событие (CPT) с ярлыком «my-event»,отображается настраиваемый тип сообщения.
- Другие страницы тоже не работают. Если вы посмотрите на картинку выше,станет ясно,почему: правило настраиваемого типа сообщения всегда будет совпадать со слагом страницы. Поскольку WordPress не может определить,является ли это страницей или пользовательским типом сообщения,которого не существует,он вернет 404. Вот почему вам нужен слаг для идентификации страницы или CPT. Возможное решение - перехватить ошибку и найти страницу,которая может существовать похожая на этот ответ .
In response to my previous answer: you could of course set the
rewrite
parameter tofalse
when registering a new post type and handle the rewrite rules yourself like so<?php function wpsx203951_custom_init() { $post_type = 'event'; $args = (object) array( 'public' => true, 'label' => 'Events', 'rewrite' => false, // always set this to false 'has_archive' => true ); register_post_type( $post_type, $args ); // these are your actual rewrite arguments $args->rewrite = array( 'slug' => 'calendar' ); // everything what follows is from the register_post_type function if ( is_admin() || '' != get_option( 'permalink_structure' ) ) { if ( ! is_array( $args->rewrite ) ) $args->rewrite = array(); if ( empty( $args->rewrite['slug'] ) ) $args->rewrite['slug'] = $post_type; if ( ! isset( $args->rewrite['with_front'] ) ) $args->rewrite['with_front'] = true; if ( ! isset( $args->rewrite['pages'] ) ) $args->rewrite['pages'] = true; if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive ) $args->rewrite['feeds'] = (bool) $args->has_archive; if ( ! isset( $args->rewrite['ep_mask'] ) ) { if ( isset( $args->permalink_epmask ) ) $args->rewrite['ep_mask'] = $args->permalink_epmask; else $args->rewrite['ep_mask'] = EP_PERMALINK; } if ( $args->hierarchical ) add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" ); else add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" ); if ( $args->has_archive ) { $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive; if ( $args->rewrite['with_front'] ) $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug; else $archive_slug = $wp_rewrite->root . $archive_slug; add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' ); if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) { $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')'; add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' ); } if ( $args->rewrite['pages'] ) add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' ); } $permastruct_args = $args->rewrite; $permastruct_args['feed'] = $permastruct_args['feeds']; add_permastruct( $post_type, "%$post_type%", $permastruct_args ); } } add_action( 'init', 'wpsx203951_custom_init' );
You can see the
add_permastruct
call now doesn't include the slug anymore. I tested two scenarios:- When I created a page with the slug "calendar" that page is overwritten by the post type archive which also uses the "calendar" slug.
- When I created a page with the slug "my-event" and an event (CPT) with the slug "my-event", the custom post type is displayed.
- Any other pages do not work either. If you look at the picture above it becomes clear why: the custom post type rule will always match against a page slug. Because WordPress has no way of identifying if it's a page or a custom post type that does not exist, it will return 404. That's why you need a slug to identify either the page or CPT. A possible solution would be to intercept the error and look for a page that might exist similar to this answer.
-
Итак,если цель состоит в том,чтобы удалить слаг для CPT,не могли бы мы назвать CPT чем-то уникальным,что не будет конфликтовать,поскольку оно никогда не будет отображаться в URL-адресе?Или пост-имя является возможным конфликтом,если названо так же,как и страница?So if the goal is to remove the slug for CPT's couldn't we name the CPT something unique that wouldn't collide since it will never be seen in the URL anyways? Or is the post-name the possible conflict if named the same as a page?
- 0
- 2015-10-02
- Ben Racicot
-
Я обновил свой ответ,чтобы показать,что это действительно приводит к поломке * всех * страниц.Без slug WP будет искать CPT вместо страницы и,если не найдет,вернет ошибку.Так что на самом деле это не связано с названием поста.I have updated my answer to show that this does actually break *all* pages. Without a slug, WP will look for a CPT instead of a page and if it doesn't find it, return an error. So it's actually not related to the post-name.
- 0
- 2015-10-02
- Jan Beck
-
Понимаю.Должны быть правила перезаписи,которые добавляют «-1» к будущим конфликтующим URL-адресам,например,собственные сообщения WP и страницы.Я создал тикет https://core.trac.wordpress.org/ticket/34136#ticket,хотелось бы узнать ваши мысли.I see. There should be rewrite rules that append '-1' to future conflicting URL's like native WP posts vs pages. I've created a trac ticket https://core.trac.wordpress.org/ticket/34136#ticket would love your thoughts.
- 1
- 2015-10-02
- Ben Racicot
-
- 2019-12-17
Обзор плагинов
Уже почти 2020 год,и многие из этих ответов не работают. Вот мой собственный обзор текущих вариантов:
- Ответ Мэтта Киз кажется единственным правильным ответом,если вам нужно собственное решение кода. Ни один из найденных мной плагинов не может выполнять все перечисленное здесь,особенно проверку дубликатов. Этот подход кажется действительно хорошей возможностью для плагина,если кто-то хочет этим воспользоваться.
- Permalink Manager Lite
- Лучшие из бесплатных плагинов,которые я пробовал.
- Предоставляет полный контроль над всей структурой постоянных ссылок страниц/сообщений/CPT и позволяет им быть одинаковыми. Графический интерфейс пользователя - безусловно,самый многофункциональный.
- Позволяет полностью переопределить каждую публикацию и позволяет увидеть исходное значение/значение по умолчанию и при необходимости сбросить его до значения по умолчанию.
- Поддерживает несколько сайтов.
- не проверяет дубликаты между типами сообщений,что печально. Если страница и CPT имеют один и тот же URL-адрес,страница загружается и CPT недоступен. Никаких предупреждений или ошибок,вам просто нужно вручную проверить наличие дубликатов.
- Все функции таксономии находятся в версии PRO. Проблемы с обновлением довольно тяжелые.
- Пользовательские постоянные ссылки
- Бесплатная версия делает многое. Постоянные ссылки таксономии и премиум-поддержка,похоже,единственное,чего не хватает в профессиональной версии.
- Позволяет изменить полную постоянную ссылку для любой отдельной страницы/сообщения/CPT.
- Поддерживает несколько сайтов.
- не позволяет изменить структуру по умолчанию,чтобы ваши пользовательские типы сообщений по-прежнему былиexample.com/cpt-slug/post-title,но вы могли изменять их индивидуально.
- не проверяет дубликаты между типами сообщений,что печально.
- Постоянные ссылки настраиваемого типа сообщения
- Позволяет пользователям,не являющимся разработчиками,изменять то,что уже легко изменить с помощью
register_post_type
- не позволяет вам изменить базовый ярлык CPT - только ту часть,которая идет после этого - что в значительной степени бесполезно для разработчиков и проблемы в этом вопросе.
- Позволяет пользователям,не являющимся разработчиками,изменять то,что уже легко изменить с помощью
- удалить базовый ярлык ... - мертв уже несколько лет ... не использую.
Plugin Roundup
It's almost 2020 and a lot of these answers don't work. Here's my own roundup of the current options:
- Matt Keys answer seems to be the only one on the right track if you want a custom code solution. None of the plugins I found can do everything listed here, especially the duplicate checking. This approach seems like a really good opportunity for a plugin if anyone wanted to take that on.
- Permalink Manager Lite
- Best of the free plugins I tried.
- Gives full control over all Page/Post/CPT complete permalink structure and allows them to be the same. The GUI is by far the most feature-rich.
- Allows full override per-post as well and lets you see what the original/default would be and reset to the default if needed.
- Supports multi-site.
- Does not check for duplicates between post types, which is sad. If a page and a CPT have the same URL, the page loads and the CPT is inaccessible. No warnings or errors, you just have to do your own manual checking for duplicates.
- All taxonomy features are in the PRO version. The upgrade nags are pretty heavy.
- Custom Permalinks
- The free version does a lot. Taxonomy permalinks and premium support seem to be the only things withheld from the pro version.
- Allows you to change the full permalink for any individual page/post/CPT.
- Supports multi-site.
- Does not allow you to change the default structure so you your Custom Post Types will still be example.com/cpt-slug/post-title but you can change them individually.
- Does not check for duplicates between post types, which is sad.
- Custom Post Type Permalinks
- Allows non-developer users to change the things that are easy to change already with
register_post_type
- Does not allow you to change the CPT base slug - only the part that comes after that - so pretty much useless for developers and the issue in this question.
- Allows non-developer users to change the things that are easy to change already with
- remove base slug... - dead for several years now... do not use.
-
Плагин Permalink Manager Lite определенно является лучшим решением: стабильный,надежный,чистый,а бесплатная версия позволяет удалить базу слагов.И с Polylang это тоже работает!Протестировано на Wordpress 5.4,с темой TwentyTwenty,без активации каких-либо других плагинов.Работает как шарм с настраиваемым типом сообщения,независимо от того,создали ли вы иерархический (с дочерним постом и постом внука).От всех,кто хочет чистого решения.The plugin Permalink Manager Lite is definitively the best solution : steady, robust, clean, and the free version allow you to remove the slug base. And it works with Polylang too ! Tested on Wordpress 5.4, with TwentyTwenty Theme, without any other plugin activated. Works like a charm on Custom Post Type, no matter if you have created a hierarchical one (with child post and grandchild post). From everyone who wants a clean solution.
- 1
- 2020-04-04
- PhpDoe
-
- 2017-02-25
Вам не нужно столько жесткого кода.Просто используйте легкий плагин:
Он имеет настраиваемые параметры.
You dont need so much hard-code. Just use lightweight plugin:
It has customizable options.
-
Теперь я знаю,почему вас проголосовали против: это мешает разрешению обычных ссылок на страницы.Я не видел этого,потому что получал кешированные копии существующих страниц,несмотря на обновление.Now I know why you got downvoted, it prevents normal page links resolving. I didn't see it because I was getting cached copies of the existing pages despite refreshing.
- 0
- 2017-09-14
- Walf
-
@Walf Вы можете подробнее рассказать о проблеме?@Walf Can you tell me about the issue in details?
- 0
- 2017-09-14
- T.Todua
-
Переход по ссылкам на страницы (которые не были настраиваемым типом публикации) из главного меню выдавал 404 ошибки,как если бы страница не существовала;это оно.Following links to pages (that weren't the custom post type) from the main menu gave 404 errors, as if the page did not exist; that's it.
- 0
- 2017-09-14
- Walf
-
@Walf,можете ли вы дать мне какой-нибудь пример URL-адреса вашего мероприятия?(вы можете указать доменное имя,если хотите,мне просто нужен пример) спасибо,я обновлю его@Walf can you give me any example url of your occasion? (you can cover domain name if you want, i just need an ex example) thanks, i wil update it
- 0
- 2017-09-15
- T.Todua
-
«Этот плагин был закрыт 19 сентября 2018 г. и недоступен для загрузки. Это закрытие навсегда»."This plugin has been closed as of September 19, 2018 and is not available for download. This closure is permanent."
- 1
- 2019-12-16
- squarecandy
-
- 2017-03-01
и мы можем внести некоторые изменения в вышеупомянутую функцию:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { $query->set( 'post_type', array( 'post', 'events', 'page' ) ); } }
кому:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { global $wpdb; $pt = $wpdb->get_var( "SELECT post_type FROM `{$wpdb->posts}` " . "WHERE post_name = '{$query->query['name']}'" ); $query->set( 'post_type', $pt ); } }
для установки правильного значенияpost_type.
and we can make some changes to above-mentioned function:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { $query->set( 'post_type', array( 'post', 'events', 'page' ) ); } }
to:
function na_parse_request( $query ) { if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) { return; } if ( ! empty( $query->query['name'] ) ) { global $wpdb; $pt = $wpdb->get_var( "SELECT post_type FROM `{$wpdb->posts}` " . "WHERE post_name = '{$query->query['name']}'" ); $query->set( 'post_type', $pt ); } }
in order to set right post_type value.
-
- 2017-05-03
У меня сработало:
'rewrite' => array('slug' => '/')
This worked for me:
'rewrite' => array('slug' => '/')
-
Это не работает.Выдает 404,даже если вы обновили постоянные ссылки.This doesn't work. Gives 404 even when you've updated permalinks.
- 1
- 2017-11-12
- Christine Cooper
-
- 2017-05-29
Для всех,кто читал это и у кого были проблемы с дочерними постами,как у меня,я нашел лучший способ - добавить свои собственные правила перезаписи.
Основная проблема,с которой я столкнулся,заключалась в том,что WordPress обрабатывает перенаправление со страниц с двухуровневой глубиной (дочерние сообщения) немного иначе,чем с трехуровневой глубиной (дочерние записи).
Это означает,что когда у меня есть/post-type/post-name/post-child/,я могу использовать/post-name/post-child,и он перенаправит меня на тот,у которого впередиpost-type,но если у меня естьpost-type/post-name/post-child/post-grandchild,тогда я не могу использоватьpost-name/post-child/post-grandchild.
Если взглянуть на правила перезаписи,похоже,что они совпадают с вещами,отличными от имени страницы на первом и втором уровнях (я думаю,что второй уровень соответствует вложению),а затем что-то там делает,чтобы перенаправить вас на нужный пост. На трех уровнях не работает.
Первое,что вам нужно сделать,это также удалить ссылку типа сообщения у детей. Эта логика должна произойти здесь,если вы посмотрите на ответ Нейта Аллена выше:
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
Я сам использовал сочетание различных условных выражений,чтобы проверить,есть ли у сообщения дочерние элементы и еще много чего,чтобы перейти к нужной постоянной ссылке. Эта часть не слишком сложна,и вы найдете примеры,когда люди делали это в другом месте.
На следующем шаге все меняется от данного ответа. Вместо добавления элементов в основной запрос (который работал для пользовательских сообщений и их дочерних элементов,но не для последующих дочерних элементов) я добавил перезапись,которая пошла в конец правил WordPress,так что если имя страницы не проверяется,и он собирался нажмите 404,он выполнит последнюю проверку,чтобы увидеть,имеет ли страница в пользовательском типе сообщения такое же имя,иначе он выбросит 404.
Вот правило перезаписи,которое я использовал,предполагая,что "событие" - это имя вашего CPT
function rewrite_rules_for_removing_post_type_slug() { add_rewrite_rule( '(.?.+?)?(:/([0-9]+))?/?$', 'index.php?event=$matches[1]/$matches[2]&post_type=event', 'bottom' ); } add_action('init', 'rewrite_rules_for_removing_post_type_slug', 1, 1);
Надеюсь,это поможет кому-то другому,я не мог найти ничего,что связано с дочерними записями дочерних элементов и удалением из них слага.
For anyone reading this that had trouble with child posts like I did I found the best way was to add your own rewrite rules.
The main issue I was having was that WordPress treats the redirect from pages that are 2 levels (child posts) deep a little differently than it treats 3 levels deep (child of child posts).
That means when I have /post-type/post-name/post-child/ I can use /post-name/post-child and it will redirect me to the one with post-type in front but if I have post-type/post-name/post-child/post-grandchild then I can't use post-name/post-child/post-grandchild.
Taking a look into the rewrite rules it looks like it matches for things other than pagename at the first and second levels (I think the second level matches attachment) and then does something there to redirect you to the proper post. At three levels deep it doesn't work.
First thing you need to do is to remove the post type link from children as well. This logic should happen here if you look at Nate Allen's answer above:
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
Myself I used a mix of different conditionals to check if the post had children and whatnot in order to get to the right permalink. This part isn't too tricky and you'll find examples of people doing it elsewhere.
The next step though is where things change from the given answer. Instead of adding things to the main query (which worked for custom posts and their children but not the further children) I added a rewrite that went to the bottom of the WordPress rules so that if pagename didn't check out and it was about to hit a 404 it would do one last check to see if a page within the custom post type had the same name otherwise it would throw out the 404.
Here is the rewrite rule I used assuming 'event' is the name of your CPT
function rewrite_rules_for_removing_post_type_slug() { add_rewrite_rule( '(.?.+?)?(:/([0-9]+))?/?$', 'index.php?event=$matches[1]/$matches[2]&post_type=event', 'bottom' ); } add_action('init', 'rewrite_rules_for_removing_post_type_slug', 1, 1);
Hope this helps someone else, I couldn't find anything else that had to do with child of child posts and removing the slug from those.
-
Похоже,в регулярном выражении есть опечатка.Между '(:' a '?' Необходимо использовать как не захватывающий подшаблон=> '(?:'. Третий? Кажется неуместным,поскольку он допускает пустой первый подшаблон. Вероятно,он должен быть расположен между (и:.Без этой опечатки выражение будет таким же,как и для встроенного типа поста 'page'.There seems to be a typo in the regex. Between '(:' a '?' is needed to use it as non-capturing subpattern => '(?:'. The third ? seems misplaced as it allows an empty first subpattern. Propably it should be positioned between ( and :. Without this typo the expression will be the same as the one which can be found for the build-in post type 'page'.
- 0
- 2019-10-28
- jot
-
- 2019-06-19
Были те же проблемы здесь и,кажется,нет движения на сайте wordpress.В моей конкретной ситуации,когда для отдельных сообщений в блогах структура/blog/%postname%/была необходима,это решение
https://kellenmace.com/remove-custom-пост-тип-ярлык-из-постоянных ссылок/
закончился кучей ошибок 404
Но вместе с этим замечательным подходом,который не использует структуру постоянных ссылок серверной части для сообщения в блоге,он наконец-то работает как шарм. https://www.bobz.co/add-blog-prefix-permalink-structure-blog-posts/
Большое спасибо.
Had the same problems here and there seems to be no movement on wordpress site. In my particular situation where for single blogposts the structure /blog/%postname%/ was needed this solution
https://kellenmace.com/remove-custom-post-type-slug-from-permalinks/
ended in a bunch of 404s
But together with this wonderful approach, which is not using the backend permalink strukture for the blogpost it finally works like charme. https://www.bobz.co/add-blog-prefix-permalink-structure-blog-posts/
Thanks a bunch.
-
Ответы только по ссылкам не приветствуются.Если вы нашли ответ в этой статье,который отличается от других ответов на странице,включите в свой ответ краткое изложение и пример кода.Link-only answers are discouraged. If you found an answer in this article that is different from the other answers on the page, please put a summary and code example in your answer.
- 0
- 2019-12-16
- squarecandy
Похоже,что все веб-ресурсы основаны на удалении слага произвольного типа,т.е.
в настоящее время являются очень устаревшими решениями,часто ссылающимися на установки до версии WP 3.5. Распространенным является:
в вашей функции register_post_type. Это больше не работает и вводит в заблуждение. Поэтому я прошу сообщество в третьем квартале 2018 года на пороге WordPress 5 ...
Каковы современные и эффективные способы удаления слага типа сообщения из URL-адреса сообщения настраиваемого типа сообщения из аргумента перезаписи или из любого другого места?
ОБНОВЛЕНИЕ: Кажется,есть несколько способов заставить это работать с регулярным выражением. В частности,ответ от Яна Бека,если вы постоянно готовы отслеживать создание контента,чтобы гарантировать,что не создаются конфликтующие имена страниц/сообщений .... Однако я убежден,что это серьезная слабость в ядре WP,где это должно быть обработано для нас . И как опция/ловушка при создании CPT,или как расширенный набор опций для постоянных ссылок. Пожалуйста,поддержите путевой билет.
Сноска: поддержите этот тикет Trac,просмотрев/продвигая его: https://core .trac.wordpress.org/ticket/34136 #ticket