Получите пользовательский тип сообщения для страницы архива

14

Как я могу обнаружить слаг пользовательского типа, когда я нахожусь на странице архива?

Например, если шаблон /products/запускается archive-products.php, как (прагматично) я могу получить слаг типа поста?

Благодарность

Бен Эверард
источник

Ответы:

18

Чтобы получить текущий тип сообщения, используйте 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;
}
Fuxia
источник
1
Я думаю (не проверял) get_queried_object()получал бы ту же информацию за меньшее количество ходов.
Rarst
@Rarst Возможно, но я думаю, что код, который я предложил, легче понять.
fuxia
1
Решения Toscho неверны, потому что get_post_type возвращает тип записи текущей страницы, а когда вы находитесь на странице архива, эта функция всегда возвращает «страницу». Я пытаюсь решить то же самое: когда я нахожусь на странице архива «книг» (4 примера), я хочу это: «книги». Когда я получу это, я отправлю это.
eMarine
1
к сожалению, это не так просто, хотя вам будет лучше, если просто $posttype = get_query_var('post_type');... я добавил всеобъемлющую альтернативу.
Маджик
Я не думаю, что это ответ охватывает всю историю. Вы должны проверить правила перезаписи установки, так как многие фильтры (например, страница магазина woocommerce) вносят изменения. Вместо этого используйте собственный механизм Worpdress , смотрите мой ответ где-то ниже.
Джонас Лундман
6

Я использую это вне цикла в шаблоне 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
patrickzdb
это будет работать только в том случае, если для зарегистрированного CPT установлен параметр перезаписи slug, так как он является необязательным и по умолчанию используется post_type
majick
Спасибо, что поймали этот @majick! Я обновил пост, чтобы отразить вашу информацию.
Джерри
оказывается, это была верхушка айсберга ... проверьте мой новый ответ для подводной части :-)
majick
3

Ответы становятся запутанными. И, может быть, я тоже, но главный вопрос:

Получить заказ после типа слизня для архива страницы

Если вы имеете в виду целевую страницу архива с типом поста и при 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.

cavameta
источник
Это сделало это очень ясно, спасибо. Искал это решение. Если вопрос не ищет «только имя типа сообщения», это должен быть решенный ответ.
Джонас Лундман,
1

Следует отметить, что если 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атрибут класса к миниатюрам своих сообщений ...

majick
источник
0

Вы можете использовать этот код:

$queried_object = get_queried_object();
$posttype_slug = $queried_object->query_var;
echo $posttype_slug;

используйте $ posttype_slug var, что вам нужно

Гай Ицхак
источник
это нужно для того, $queried_object->query_var['post_type'];чтобы это работало ...
Маджик
Нет. $ Queried_object-> query_var содержит только строку типа записи. это не объект или массив. посмотрите на это изображение: prntscr.com/bd58e1
Гай Ицхак,
хорошо, но только если запрашиваемый объект определенно является объектом пользовательского типа записи, вы получите другой соответствующий объект и, таким образом, пустое значение, например, для архивных страниц категории / налога / тега / автора. даже если ?post_type=postя опустошу. сравните сget_query_var('post_type');
Маджик
0

Вы можете использовать этот код, и этот код работает для меня,

 $ t_slug = get_query_var ('term');
Навин Бхудия
источник
-3
if( get_post_type( get_the_ID() ) == 'projects' )
{
  //enter code for this post type
}
subair
источник