Отримайте спеціальний слуповий тип публікації для сторінки архіву


15

Як я можу виявити користувацький слупок типу публікації, коли я перебуваю на сторінці архіву?

Наприклад, якщо /products/запускається archive-products.phpшаблон, то як (прагматично) я можу отримати слизу типу публікації?

Спасибі

Відповіді:


19

Щоб отримати поточний тип публікації 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;
}

1
Я думаю (не тестував) get_queried_object()потрапляв би до тієї ж інформації меншими ходами.
Рарст

@Rarst Можливо, але я думаю, що запропонований мною код легше зрозуміти.
fuxia

1
Рішення Toscho неправильні, оскільки get_post_type повертає тип публікації поточної сторінки, а, коли ви перебуваєте на сторінці архіву, ця функція завжди повертає "сторінку". Я намагаюся вирішити те саме: Коли я перебуваю на сторінці архіву «книги» (4 приклади), я хочу це: «книги». Коли я отримаю, я опублікую його.
eMarine

1
на жаль, це не так просто, хоча вам краще буде просто $posttype = get_query_var('post_type');... Я додав вичерпну альтернативу.
majick

Я не думаю, що ця відповідь висвітлює всю історію. Ви повинні перевірити правила перезапису встановлення, оскільки багато фільтрів (наприклад, сторінка магазину woocommerce) вносять зміни. Використовуйте замість себе власний механізм Worpdress , дивіться мою відповідь десь нижче.
Йонас Лундман

6

Я використовую це за межами циклу в шаблоні archive.php, щоб отримати, який я користувальницький архів публікацій.

Це комбінація методів, які рекомендували і @toscho, і @Rarst:

$post_type = get_queried_object();
echo $post_type->rewrite['slug'];

Оновлення: @majick зазначав, що це працює лише в тому випадку, якщо ви встановили перезаписуючу службу для CPT. Перезаписувати молюск необов’язково при реєстрації CPT, а за замовчуванням - post_type, якщо він не встановлений.


коли я спробував це, я отримавNotice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4
patrickzdb

це буде працювати лише в тому випадку, якщо для зареєстрованої CPT встановлено перезаписуючу службову скриньку, оскільки вона є необов'язковою та за замовчуванням використовується 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 зареєстровано в об'єкті типу "продукти", але насправді використовується переписана назва правила (магазин):

/* returns shop */
$responding_name = str_replace('/', '', str_replace(get_home_url(), '', get_post_type_archive_link('product')));

Позначте, я використовую $responding_name, оскільки цілі можуть відрізнятися. Архів публікацій не існує, це лише URL-адреса.


Це дозволило дуже чітко дякувати. Шукав це рішення. Якщо питання не шукало "лише лише назву типу публікації", це має бути переконливою відповіддю.
Йонас Лундман

1

t слід зазначити, що якщо 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атрибут класу до мініатюрних зображень вашої публікації ...


0

Ви можете використовувати цей код:

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

використовуйте $ posttype_slug var все, що вам потрібно


він повинен $queried_object->query_var['post_type'];для цього працювати ...
majick

№ $ queried_object-> query_var містить лише рядок типу публікації. це не об’єкт чи масив. дивіться на це зображення: prntscr.com/bd58e1
Гай

ОК, але лише якщо запитуваний об'єкт, безумовно, є об'єктом спеціального типу, ви отримаєте інший відповідний об'єкт і, таким чином, порожнє значення для сторінок архіву категорії / податку / тегу / автора, наприклад. навіть бо ?post_type=postя порожній. порівняти зget_query_var('post_type');
majick

0

Ви можете використовувати цей код, і цей код працює для мене,

 $ t_slug = get_query_var ('термін');

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.