Как Правильно Добавить Произвольные Поля к Пользовательским Таксономиям в WordPress
Сохранение дополнительных полей, добавленных к таксономии. Я хочу найти наиболее правильный и эффективный способ сделать это. Где следует сохранять новые поля?
2 возможных решения:
1) Использовать таблицу options WordPress, как описано здесь... Добавление Произвольных Полей к Пользовательским Таксономиям. Это признанно "не чистое" решение и предположительно не является правильным ответом.
// Функция обратного вызова для сохранения наших дополнительных полей таксономии
function save_taxonomy_custom_fields( $term_id ) {
if ( isset( $_POST['term_meta'] ) ) {
$t_id = $term_id;
$term_meta = get_option( "taxonomy_term_$t_id" );
$cat_keys = array_keys( $_POST['term_meta'] );
foreach ( $cat_keys as $key ){
if ( isset( $_POST['term_meta'][$key] ) ){
$term_meta[$key] = $_POST['term_meta'][$key];
}
}
//сохраняем массив опций
update_option( "taxonomy_term_$t_id", $term_meta );
}
}
2) Добавить новую таблицу, как описано здесь Пользовательские Таксономии в WordPress, которая следует соглашению об именовании 'wp_' + customtaxonomykey + 'meta'.
3) Какой-то другой вариант

Вы можете сохранить ID вложения в таблице опций и затем отображать это вложение
Существует три основные функции для добавления метабокса к таксономии. Они вызываются через следующие хуки:
- {taxonomy_name}_add_form_fields
- {taxonomy_name}_edit_form_fields
- edited_{taxonomy_name}
- create_{taxonomy_name}
Здесь вы можете заменить taxonomy_name на любую предопределенную или пользовательскую таксономию. Я использую "Таксономию товаров WooCommerce" и создал плагин для этого. Пожалуйста, ознакомьтесь со следующими функциями для добавления пользовательского поля:
{taxonomy_name}_add_form_fields добавляет новое пользовательское поле на страницу добавления нового термина. Здесь я создаю поле для добавления класса термина.
Добавьте следующий код в файл functions.php вашей темы
public function mj_taxonomy_add_custom_meta_field() {
?>
<div class="form-field">
<label for="term_meta[class_term_meta]"><?php _e( 'Добавить класс', 'MJ' ); ?></label>
<input type="text" name="term_meta[class_term_meta]" id="term_meta[class_term_meta]" value="">
<p class="description"><?php _e( 'Введите значение для этого поля','MJ' ); ?></p>
</div>
<?php
}
add_action( 'product_cat_add_form_fields', 'mj_taxonomy_add_custom_meta_field', 10, 2 );
{taxonomy_name}_edit_form_fields добавляет поле на страницу редактирования термина
public function mj_taxonomy_edit_custom_meta_field($term) {
$t_id = $term->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
?>
<tr class="form-field">
<th scope="row" valign="top"><label for="term_meta[class_term_meta]"><?php _e( 'Добавить класс', 'MJ' ); ?></label></th>
<td>
<input type="text" name="term_meta[class_term_meta]" id="term_meta[class_term_meta]" value="<?php echo esc_attr( $term_meta['class_term_meta'] ) ? esc_attr( $term_meta['class_term_meta'] ) : ''; ?>">
<p class="description"><?php _e( 'Введите значение для этого поля','MJ' ); ?></p>
</td>
</tr>
<?php
}
add_action( 'product_cat_edit_form_fields','mj_taxonomy_edit_custom_meta_field', 10, 2 );
public function mj_save_taxonomy_custom_meta_field( $term_id ) {
if ( isset( $_POST['term_meta'] ) ) {
$t_id = $term_id;
$term_meta = get_option( "taxonomy_$t_id" );
$cat_keys = array_keys( $_POST['term_meta'] );
foreach ( $cat_keys as $key ) {
if ( isset ( $_POST['term_meta'][$key] ) ) {
$term_meta[$key] = $_POST['term_meta'][$key];
}
}
// Сохраняем массив опций
update_option( "taxonomy_$t_id", $term_meta );
}
}
add_action( 'edited_product_cat', 'mj_save_taxonomy_custom_meta_field', 10, 2 );
add_action( 'create_product_cat', 'mj_save_taxonomy_custom_meta_field', 10, 2 );

Спасибо за ваши ответы! Не могли бы вы отредактировать свои ответы и добавить немного информации о том, что делает этот код и как он решает исходную проблему?

Вариант 2 является наиболее чистым методом — я также использовал его несколько раз. К сожалению, в WordPress пока нет стандартной таблицы term_metadata. В этой статье рассматривается тот же подход: http://shibashake.com/wordpress-theme/add-term-or-taxonomy-meta-data
И, конечно же, для этого есть плагин :) http://wordpress.org/extend/plugins/taxonomy-metadata/

1) Стандартная таблица wp_options
Я действительно не понимаю, почему люди предлагают
update_option( "taxonomy_term_$t_id", $term_meta );
когда мы можем иметь одну единственную опцию, где индексами будут ID терминов, а значениями — пользовательские поля
$options = get_option( 'taxonomy_term_meta' );
$options[$t_id] = $term_meta;
update_option( 'taxonomy_term_meta', $options );
и затем просто получать опцию и значение для заданного ID термина
$options = get_option( 'taxonomy_term_meta' );
echo $options[$tax->term_id];
2) Пользовательская таблица wp_taxonomymeta
Это то, что делает плагин Taxonomy Metadata, на который ссылается James. И это довольно просто: как только эта таблица создана, функции add_
, get_
, update_
и delete_<b>metadata</b>
начнут работать с 'taxonomy'
. Вот так:
function add_term_meta($term_id, $meta_key, $meta_value, $unique = false) {
return add_metadata('taxonomy', $term_id, $meta_key, $meta_value, $unique);
}
function delete_term_meta($term_id, $meta_key, $meta_value = '') {
return delete_metadata('taxonomy', $term_id, $meta_key, $meta_value);
}
function get_term_meta($term_id, $key, $single = false) {
return get_metadata('taxonomy', $term_id, $key, $single);
}
function update_term_meta($term_id, $meta_key, $meta_value, $prev_value = '') {
return update_metadata('taxonomy', $term_id, $meta_key, $meta_value, $prev_value);
}
3) Вспомогательный тип записи
Как описано в ответе Matthew Boynes (думаю, кто-то также упоминает это в тикете #10142).
4) Нестандартное решение
В коде плагина есть ссылка на Core Ticket #10142, где обсуждается всё это. Это 4-летний тикет, (closed)(maybelater)
, множество разработчиков высказались, но к какому-то выводу так и не пришли.
В конце есть вот такая жемчужина (мой акцент):
Так как мне это нужно регулярно, я написал своё решение: Использую поле "description" как контейнер для хранения сериализованного массива. Единственное, что было немного сложным — отображать обычное описание в интерфейсе админки. В любом случае, это решение, на которое я надеялся: просто преобразовать поле description вместо добавления кучи новых полей. Если в этом будет необходимость, то мы увидим случаи использования после реализации и перейдём к поисковому решению в более поздней версии.
Довольно умно.

Лучший ответ — (3) Другой вариант.
Это немного нестандартно, но масштабируется лучше всего, максимально использует ядро WordPress и не требует добавления таблицы в базу данных: создать скрытый тип записи для таксономии. Каждый термин таксономии получает свою запись в этом типе записи. В этом случае метаданные термина можно хранить как метаданные записи. Вот пример использования этого подхода.
Основные проблемы с другими подходами (включая вариант "использовать поле описания термина для хранения сериализованных данных") — это масштабируемость, производительность и совместимость.

Не только со скрытым пользовательским типом записи. Если термин связан с одной записью, постом или страницей, то метаданные термина могут хранить ID этой записи, и мы можем создать множество пользовательских полей для этой записи, которые нужны для связи с термином в нашей пользовательской таксономии. Независимо от вашего подхода, я настоятельно рекомендую добавить защиту от удаления пользовательских терминов, если они содержат так много метаданных и связаны с записями. Сейчас я реализую это в WP e-Customers, потому что удаление термина может вызвать хаос, если его метаданные используются и необходимы.

https://wordpress.org/plugins/taxonomy-metadata/
Вы можете настроить с помощью указанного выше плагина...
