Ограничить раскрывающийся список таксономии типом записи


У меня есть 5 различных пользовательских типов записей и одна пользовательская таксономия. Мне удалось получить раскрывающийся список таксономии с помощью <?php wp_dropdown_categories( $args ); ?>, но я заметил, что не смог ограничить раскрывающийся список таксономии, чтобы показать термины, в которых есть записи определенного типа.

В некоторых комментариях, которые я получил, меня попросили создать другую таксономию для каждого типа записи, но в моем случае это невозможно, поскольку моя пользовательская таксономия предназначена для определения местоположения, и я хотел бы, чтобы все 5 пользовательских типы записей для использования этой таксономии.

Я знаю, что могу загружать сообщения из типа сообщений и получать термины из этих сообщений и использовать цикл foreach для их просмотра и вывода в качестве параметров в поле выбора, но я не хочу использовать это, так как я потерял бы иерархию, которую я настроил для таксономии. Если я смогу получить иерархию с помощью этого метода, то я тоже открыт для этого.

Возможно ли это или мне нужно создавать отдельные таксономии для каждого поста тип?

ОБНОВЛЕНИЕ Я хотел иметь возможность добавлять настраиваемое значение поля также в качестве параметра. Ответ дедмедика делает это.

Author: NJT, 2015-11-05

1 answers

Вы можете использовать фрагмент , который я нашел для запроса терминов, прикрепленных к определенному типу сообщений:

function wpse_207655_terms_by_post_type_or_meta( $clauses, $taxonomy, $args ) {
    $meta_query = new WP_Meta_Query;
    $meta_query->parse_query_vars( $args );
    $post_types = '';

    if ( ! empty( $args['post_type'] ) ) {
        if ( $_post_types = array_intersect( ( array ) $args['post_type'], get_post_types() ) )
            $post_types = implode( "','", $_post_types );
    }

    if ( $post_types || $meta_query->queries ) {
        global $wpdb;

        $clauses['join']   .= " INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id";
        $clauses['orderby'] = "GROUP BY t.term_id {$clauses['orderby']}";

        if ( $post_types )
            $clauses['where'] .= " AND p.post_type IN ('$post_types')";

        if ( $meta_query->queries ) {
            $sql = $meta_query->get_sql( 'post', 'p', 'ID' );

            $clauses['join']  .= $sql['join'];
            $clauses['where'] .= $sql['where'];
        }
    }

    return $clauses;
}

add_filter( 'terms_clauses', 'wpse_207655_terms_by_post_type_or_meta', 10, 3 );

Теперь вы можете использовать аргумент post_type в wp_dropdown_categories (который на самом деле просто передается в get_terms, где в игру вступает наш фильтр):

wp_dropdown_categories( 'taxonomy=location&post_type=X' ); 

Обновление: Теперь вы также можете использовать WP_Query мета-аргументы:

wp_dropdown_categories( 'meta_key=foobar' );

...или полномасштабный мета-запрос:

wp_dropdown_categories( array(
    'post_type'  => 'foobar',
    'meta_query' => array(
        array(
            'key'   => 'this',
            'value' => 'that',
        ),
        array(
            'key' => 'foobar',
        ),
    ),
));
 3
Author: TheDeadMedic, 2015-11-23 10:55:09