условия получения не будут отображать cat продукта или любые другие пользовательские таксономии, если они указаны
Интересно, есть ли у вас какие-нибудь идеи по этой проблеме. Я гуглю уже несколько дней, но не могу этого понять.
Вот где я нахожусь:
У меня есть мета-поле для публикации Woocommerce типа "продукты’. Внутри мета-поля есть 'type' = > 'select'
, который я хочу заполнить списком всех доступных 'taxonomy' = > 'product_cat'
.
Я могу заставить поле выбора заполнять и работать со стандартными категориями сообщений 'taxonomy' = > 'category'
, используя следующий код:
function product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'category' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
// return array('options'=>$options);
return $options;
}
Все это разваливается, хотя, когда я пытаюсь использовать ‘taxonomy' = > ‘product_cat’
или любую другую пользовательскую таксономию, которая у меня есть.
Я думал, что проблема в том, что я пытаюсь получить доступ к пользовательской таксономии до ее регистрации, поэтому я поменял местами некоторые объявления/вызовы в своем function.php файл (те, которые вызывают CPT, мета-блоки и woocommece), чтобы потенциально изменить порядок выполнения, но безуспешно.
НО, основываясь на вопросе и ответе ниже, теперь я могу подтвердить, что функция может "видеть" и отображать все термины, по всем таксономиям. Если я исключу 'taxonomy =>
из аргументов, он вернет термины из разных пользовательских типов записей и таксономий.
В идеале базовая функция должна была бы гласить:
function product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
// return array('options'=>$options);
return $options;
}
Просто интересно, есть ли у вас какие-нибудь общие мысли? Я знаю, что это сложно, не видя всей кодовой базы, но я подумал, что стоит спросить.
Версия Wordpress 4.7.2
Версия Woocommerce 2.6.14
ОБНОВЛЕНИЕ:
Медленно я пытаюсь определите мою проблему.
Похоже, что к 'product_cat'
все-таки можно получить доступ (хорошо), но он выдает массив, который отображается неправильно.
Это сбивает меня с толку, как будто я просто использую get_terms()
без каких-либо параметров или указываю 'taxonomy' => 'category'
приведенный выше код работает безупречно
Другие фрагменты кода, с которыми мне нужно работать, это:
Массив, в который я хотел бы поместить список параметров для сброса
array(
'label'=> 'Collections',
'desc' => 'Select the collection you would like to display',
'id' => $prefix.'collection',
'type' => 'select',
'options' => product_cats()
),
код, который генерирует список выбора (используется для других мета-полей)
// select
case 'select':
echo '<select name="'.$field['id'].'" id="'.$field['id'].'">';
foreach ($field['options'] as $option) {
echo '<option', $meta == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
}
echo '</select><br /><span class="description">'.$field['desc'].'</span>';
break;
У меня нет проблем с любыми другими мета-полями, работающими или отображаемыми, включая списки выбора.
Я бы предпочел не переписывать весь мета-блок со всеми его полями, поэтому я пытаюсь работать с тем, что у меня есть на данный момент.
4 answers
Возможно, вы используете старую версию WordPress (до версии 4.5).
До WordPress 4.5.0 первым параметром get_terms() была таксономия или список таксономий, а начиная с 4.5.0 таксономии должны передаваться через аргумент "таксономия" в массиве $args (то, что вы делаете, должно работать именно так).
Вы найдете все подробности об этих изменениях на справочной странице get_terms().
ОБНОВЛЕНИЕ: Извините, я проверяю свой код, и я используйте get_categories(), а не get_terms, и это правильное get_terms() не работает!
Вот рабочий пример, чтобы перечислить все мои product_cat
$product_categories = get_categories( array(
'taxonomy' => 'product_cat',
'orderby' => 'name',
'pad_counts' => false,
'hierarchical' => 1,
'hide_empty' => false
) );
Надеюсь, это поможет!
Ради своей жизни я действительно хочу, чтобы это работало правильно. Хоть убей, я не могу понять, как это происходит.
Ранее я смотрел на wp_dropdown_categories()
и подумал, что это лучшее (и более простое) решение. Я начал работать над проблемой выше, потому что не мог понять, как заставить ее работать с существующим синтаксисом мета-блока.
На данный момент я принял решение о временном исправлении, приведенном ниже. Это не идеальный и, конечно, не лучший способ, но он позволяет мне продвигаться вперед с вызовом значений в шаблонах, которые будут использовать это поле.
// Wrap all categories in a function
function product_cats() {
$output = array();
$categories = get_terms( array(
'orderby' => 'name',
'pad_counts' => false,
'hierarchical' => 1,
'hide_empty' => true,
) );
foreach( $categories as $category ) {
if ($category->taxonomy == 'product_cat' ) {
$output[$category->slug] = array(
'label' => $category->name,
'value' => $category->slug
);
}
}
//return array('options'=>$output);
return $output;
}
Я буду обновлять больше по мере продвижения.
Вероятно, это не исправит ситуацию, но я хотел поделиться: сегодня я столкнулся с той же проблемой, и это было вызвано отсутствием каких-либо продуктов в моих категориях. Если это относится и к вам, не забудьте добавить 'hide_empty' => false
.
Тем не менее. Когда вы запускаете get_terms()
без каких-либо аргументов. Каков результат?
Вот полностью рабочий пример мета-окна, в котором отображается поле выбора категории продукта. Поле мета появится в типе публикации продукта.
add_action( 'add_meta_boxes', 'wpse256897_add_meta_box' );
add_action( 'save_post', 'wpse256897_save' );
/**
* Adds the meta box container.
*/
function wpse256897_add_meta_box( $post_type ) {
// Limit meta box to certain post types.
$post_types = array( 'product' );
if ( in_array( $post_type, $post_types ) ) {
add_meta_box(
'product_cat_selection',
__( 'Product Category Selection', 'textdomain' ),
'wpse256897_render_meta_box_content',
$post_type,
'advanced',
'high'
);
}
}
/**
* Save the meta when the post is saved.
*
* @param int $post_id The ID of the post being saved.
*/
function wpse256897_save( $post_id ) {
/*
* We need to verify this came from the our screen and with proper authorization,
* because save_post can be triggered at other times.
*/
// Check if our nonce is set.
if ( ! isset( $_POST['myplugin_inner_custom_box_nonce'] ) ) {
return $post_id;
}
$nonce = $_POST['myplugin_inner_custom_box_nonce'];
// Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce, 'myplugin_inner_custom_box' ) ) {
return $post_id;
}
/*
* If this is an autosave, our form has not been submitted,
* so we don't want to do anything.
*/
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
/* OK, it's safe for us to save the data now. */
// Sanitize the user input.
$mydata = sanitize_text_field( $_POST['product_cat_selection'] );
// Update the meta field.
update_post_meta( $post_id, '_product_cat_selection', $mydata );
}
/**
* Render Meta Box content.
*
* @param WP_Post $post The post object.
*/
function wpse256897_render_meta_box_content( $post ) {
// Add an nonce field so we can check for it later.
wp_nonce_field( 'myplugin_inner_custom_box', 'myplugin_inner_custom_box_nonce' );
// Use get_post_meta to retrieve an existing value from the database.
$current_product_cat = get_post_meta( $post->ID, '_product_cat_selection', true );
// Display the form, using the current value.
$product_cats = wpse256897_product_cats();
if ( !empty ( $product_cats ) ) {
echo '<select name="product_cat_selection" id="product_cat_selection">';
foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>
<option value="<?php echo esc_attr( $product_cat['value'] ); ?>" <?php if ( isset ( $current_product_cat ) ) selected( $current_product_cat, $product_cat['value'] ); ?>><?php echo esc_html( $product_cat['label'] ); ?></option><?php
}
echo '</select>';
}
}
function wpse256897_product_cats() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[$category->term_id] = array(
'label' => $category->name,
'value' => $category->slug
);
}
return $options;
}
Это не самый элегантный пример (соглашения об именовании могли бы быть лучше). Он был быстро адаптирован из добавленных заметок на справочной странице Добавить мета-поле, но он демонстрирует, что wpse256897_product_cats()
действительно получает категории продуктов и что их можно сохранить и отобразить в поле выбора на странице продукта в пределах мета-поля.
Я также хотел бы добавить, что, возможно, стоит проверить wp_dropdown_categories()
функция. Который, несмотря на свое название, также работает с пользовательскими таксономиями. Это избавит вас от необходимости создавать собственную разметку раскрывающегося списка категорий.
Обновление:
Похоже, что структура массива, возвращаемого функцией product_cats()
, не соответствует вашей реализации meta box. Обратите внимание, что в моем примере выше я использовал эту строку для перебора категорий при создании параметры для элемента select:
foreach ( $product_cats as $product_cat_id => $product_cat ) { ?>
Это связано с тем, что $product_cats
представляет собой ассоциативный массив идентификаторов категорий, каждый из которых содержит другой массив, содержащий label
и slug
для каждого идентификатора категории.
Похоже, вы могли бы использовать эту альтернативную версию product_cats()
, которая форматирует возвращаемое значение $options таким образом, чтобы оно было совместимо с вашим кодом метабокса:
function product_cats_alternate() {
$options = array();
$categories = get_terms( array( 'taxonomy' => 'product_cat' ) );
foreach( $categories as $category ) {
$options[] = array(
'label' => $category->name,
'value' => $category->slug
);
}
return $options;
}