Как я могу обнаружить слаг пользовательского типа, когда я нахожусь на странице архива?
Например, если шаблон /products/
запускается archive-products.php
, как (прагматично) я могу получить слаг типа поста?
Благодарность
Как я могу обнаружить слаг пользовательского типа, когда я нахожусь на странице архива?
Например, если шаблон /products/
запускается archive-products.php
, как (прагматично) я могу получить слаг типа поста?
Благодарность
Ответы:
Чтобы получить текущий тип сообщения, используйте get_post_type()
. Затем запросите get_post_type_object()
все данные, которые вам нужны, например слаг:
$post_type = get_post_type();
if ( $post_type )
{
$post_type_data = get_post_type_object( $post_type );
$post_type_slug = $post_type_data->rewrite['slug'];
echo $post_type_slug;
}
$posttype = get_query_var('post_type');
... я добавил всеобъемлющую альтернативу.
Я использую это вне цикла в шаблоне archive.php, чтобы узнать, какой пользовательский почтовый архив я использую.
Это комбинация методов, рекомендованных @toscho и @Rarst:
$post_type = get_queried_object();
echo $post_type->rewrite['slug'];
Обновление: @majick отметил, что это работает, только если вы установили параметр перезаписи для своего CPT. Перезапись slug не обязательна при регистрации CPT и по умолчанию post_type, если не установлен.
Notice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4
Ответы становятся запутанными. И, может быть, я тоже, но главный вопрос:
Получить заказ после типа слизня для архива страницы
Если вы имеете в виду целевую страницу архива с типом поста и при is_post_type_archive()
возврате true
вам нужен слаг, отвечающий на текущий просматриваемый архив:
/* returns /products/ */
$responding_name = str_replace(get_home_url(), '', get_post_type_archive_link(get_query_var('post_type')));
/* continue to get 'products' without slug slashes */
$responding_name = str_replace('/', '', $responding_name);
- КОНЕЦ ОТВЕТА НА ВОПРОС -
Объяснение:
Вы не можете положиться на зарегистрированный слизень . Wordpress тоже нет. Например, при вызове get_post_type_archive_link()
Wordpress выполняется проверка текущих правил перезаписи для вашей установки .
Где бы вы ни, внутри или вне контура, текущий архив или одиночный пост, реверс на get_post_type_archive_link()
механизм. (Постоянные ссылки включены.)
Соображения:
Как уже упоминалось, тип (ы) записей в текущем запросе может быть array
. Вы можете пойти дальше со своими намерениями, отфильтровав тип сообщения, который вы ищете, например:
$post_type = get_query_var('post_type');
if(is_array($post_type)) $post_type = reset($post_type);
или
if(isset($post_types[0])) $post_type = $post_types[0];
Другая точка зрения:
Пример Woocommerce, зарегистрирован в объекте типа поста 'products', но в действительности использует переписанное имя правила (shop):
/* returns shop */
$responding_name = str_replace('/', '', str_replace(get_home_url(), '', get_post_type_archive_link('product')));
Марк, я использую
$responding_name
, потому что цели могут отличаться. Почтовый архив не существует, это просто URL.
Следует отметить, что если has_archive
при регистрации пользовательского типа записи установлено значение true, архив типа записи /cptslug/
будет внутренне перезаписан ?post_type=cptslug
. Так что это также is_post_type_archive()
будет означать , вернется правда.
К сожалению, там, где зарегистрированный слизер переписывания отличается от типа поста, вы на самом деле не получаете достоверно post_type
. например. если ваш тип записи был, myplugin_cars
а перезаписываемый слаг был, cars
и вам нужно его получить, myplugin_cars
то даже это (во избежание ошибок, если текущий запрашиваемый объект не является пользовательским типом записи) все равно завершится ошибкой:
$queryobject = get_queried_object();
if (has_property('rewrite',$queryobject)) {
if (isset($queryobject->rewrite['slug'])) {
$posttype = $queryobject->rewrite['slug'];
}
}
Но потому что is_post_type_archive
это правда, это надежнее:
if (is_post_type_archive()) {
$posttype = get_query_var('post_type');
// which is basically the same as:
// global $wp_query;
// $posttype = $wp_query->query_vars['post_type'];
}
else ($posttype = 'post';}
Но подождите, это еще не все ... оказывается, с небольшим тестированием это тоже не так просто ... что если вы находитесь на странице архива таксономии с несколькими типами постов в таксономии ...? Или назначить теги сообщений для пользовательских типов сообщений, кроме сообщений? Или есть на странице архива автора? Дата архива страницы? ... или даже есть комплекс tax_query
или meta_query
для WP_Query
?
Единственный надежный ответ (без тестирования для каждого возможного случая архива) - это зацикливание фактических записей в запросе ... Вот полная функция, с которой я столкнулся, для работы как на единичных, так и на архивных страницах, и позволяющая при желании передать пользовательский объект запроса (или объект сообщения / идентификатор сообщения для отдельных сообщений):
function get_current_post_types($object=null) {
// if a numeric value passed, assume it is a post ID
if ( ($object) && (is_numeric($object)) ) {$object = get_post($object);}
// if an object is passed, assume to be a post object
if ( ($object) && (is_object($object)) ) {return get_post_type($object);}
// standard single post type checks
if (is_404()) {return '';}
// update: removed this check, handled by is_singular
// if (is_single()) {return 'post';}
if (is_page()) {return 'page';}
if (is_attachment()) {return 'attachment';}
if (is_singular()) {return get_post_type();}
// if a custom query object was not passed, use $wp_query global
if ( (!$object) || (!is_object($object)) ) {
global $wp_query; $object = $wp_query;
}
if (!is_object($object)) {return '';} // should not fail
// if the post_type query var has been explicitly set
// (or implicitly set on the cpt via a has_archive redirect)
// ie. this is true for is_post_type_archive at least
// $vqueriedposttype = get_query_var('post_type'); // $wp_query only
if (property_exists($object,'query_vars')) {
$posttype = $object->query_vars['post_type'];
if ($posttype) {return $posttype;}
}
// handle all other cases by looping posts in query object
$posttypes = array();
if (method_exists($object,'found_posts')) {
if ($object->found_posts > 0) {
$queriedposts = $object->posts;
foreach ($queriedposts as $queriedpost) {
$posttype = $queriedpost->post_type;
if (!in_array($posttype,$posttypes)) {$posttypes[] = $posttype;}
}
if (count($posttypes == 1)) {return $posttypes[0];}
else {return $posttypes;}
}
}
return ''; // nothin to see here
}
Это надежно (я это сказал?) Вернет массив типов записей, если присутствует более одного, или строку с одним типом записей, если существует только один тип. Все, что вам нужно сделать, это:
$posttypes = get_current_post_types();
// or pass a post ID
$posttypes = get_current_post_types($postid);
// or pass a post object
$posttypes = get_current_post_types($post);
// or pass a custom query - that has been run
$posttypes = get_current_post_types($query);
Пример использования (просто для удовольствия):
add_filter('the_posts','myplugin_fading_thumbnails',10,2);
function myplugin_fading_thumbnails($posts,$query) {
if (!is_archive()) {return $posts;}
$cptslug = 'myplugin_slug'; $dosomethingcool = false;
$posttypes = get_current_post_types($query);
if ( (is_array($posttypes)) && (in_array($cptslug,$posttypes)) ) {$dosomethingcool = true;}
elseif ($cptslug == $posttypes) {$dosomethingcool = true;}
if ($dosomethingcool) {
global $fadingthumbnails; $fadingthumbnails = $cptslug;
if (!has_action('wp_footer','myplugin_cpt_script')) {
add_action('wp_footer','myplugin_cpt_script');
}
}
function myplugin_cpt_script() {
global $fadingthumbnails;
echo "<script>var thumbnailclass = 'img.thumbtype-".$fadingthumbnails."';
function fadeoutthumbnails() {jQuery(thumbnailclass).fadeOut(3000,fadeinthumbnails);}
function fadeinthumbnails() {jQuery(thumbnailclass).fadeIn(3000,fadeoutthumbnails);}
jQuery(document).ready(function() {fadeoutthumbnails();});
</script>";
}
return $posts;
}
Чтобы увидеть эффект, измените пользовательский тип записи в коде post
и добавьте thumbtype-post
атрибут класса к миниатюрам своих сообщений ...
Вы можете использовать этот код:
$queried_object = get_queried_object();
$posttype_slug = $queried_object->query_var;
echo $posttype_slug;
используйте $ posttype_slug var, что вам нужно
$queried_object->query_var['post_type'];
чтобы это работало ...
?post_type=post
я опустошу. сравните сget_query_var('post_type');
Вы можете использовать этот код, и этот код работает для меня,
$ t_slug = get_query_var ('term');
get_queried_object()
получал бы ту же информацию за меньшее количество ходов.