Добавить выпадающий список для комментариев?

Может ли кто-нибудь помочь мне создать раскрывающееся меню или (радиокнопки) в форме комментариев WordPress, чтобы новый пользователь мог сделать выбор своих пользовательских ролей (например, преподавателей + студентов)?

  1. Вывод из выпадающего списка или переключателя появится где-нибудь в области комментариев.
  2. Лучше всего было бы, если WordPress, который уже автоматически заполняется
    адрес электронной почты, имя пользователя также отображали новую дополнительную информацию о поле (выпадающий список ИЛИ
    переключатель) для входа в систему, у которых уже назначены роли пользователей
  3. Я не хочу использовать для этого плагин.
  4. Я знаю, что есть много учебников по добавлению дополнительных настраиваемых полей в форму комментариев, включая эту сеть, где я нашел 3 похожих запроса, к сожалению, отмеченных как дубликаты, по моему мнению, они вовсе не дублируют, потому что нет кода или учебника для использования известными значениями (кнопка выбора – выпадающего меню).

Solutions Collecting From Web of "Добавить выпадающий список для комментариев?"

  • Фильтр comment_form_field_comment для добавления элемента select с label .
  • Добавьте обратный вызов к действию comment_post чтобы сохранить значение.
  • Отфильтруйте комментарий_текст, чтобы показать значение комментария.

Образец кода:

 add_filter( 'comment_form_field_comment', function( $field ) { global $wp_roles; $user = wp_get_current_user(); $select = '<p><label for="roleselect">Your role:</label> <select name="prefix_role" id="roleselect"> <option value="">Select a role</option>'; foreach ( $wp_roles->roles as $key => $role ) $select .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', esc_attr( $key ), ( in_array( $key, $user->roles) ? 'selected' : '' ), esc_html( $role['name'] ) ); $select .= '</select></p>'; return $select . $field; }); add_action( 'comment_post', function( $comment_ID ) { $roles = new WP_Roles; $role_keys = array_keys( $roles->roles ); if ( isset ( $_POST['prefix_role'] ) and in_array( $_POST['prefix_role'], $role_keys ) ) update_comment_meta( $comment_ID, 'prefix_role', $_POST['prefix_role'] ); }); add_filter( 'comment_text', function( $text, $comment ) { if ( $role = get_comment_meta( $comment->comment_ID, 'prefix_role', TRUE ) ) $text = "Role: $role<br> $text"; return $text; }, 10, 2 ); 

Обновить

Я переписал код для использования реального шаблона MVC. Объяснение ниже. Как плагин в GitHub .

Заголовок плагина

 <?php # -*- coding: utf-8 -*- namespace WPSE; /** * Plugin Name: Comment Meta Demo * Description: Create, save and display a comment meta field. Here, a commentator can select a role. * Plugin URI: http://wordpress.stackexchange.com/q/101579/73 * Version: 2013.06.06 * Author: Thomas Scholz * Author URI: http://toscho.de * Licence: MIT * License URI: http://opensource.org/licenses/MIT */ \add_action( 'wp_loaded', array( __NAMESPACE__ . '\Comment_Meta_Controller', 'init' ) ); 

контроллер

 /** * Controller * * Assigns Views and models to actions and filters */ class Comment_Meta_Controller { /** * Callback for add_action(). Creates a new instance. * * @wp-hook login_init */ public function init() { return new self; } /** * Set up objects, register footer action callback. * * @wp-hook login_init */ protected function __construct() { $data = new Comment_Meta_Builtin_Roles( '_comment_role' ); // Use this for custom roles instead //$data = new Comment_Meta_Custom_Roles( '_comment_role' ); $input = new Comment_Meta_Role_Selector( $data ); $output = new Comment_Meta_Role_Display( $data ); // remove this if you want to show the select field with // do_action( 'comment_role_selector' ); \add_filter( 'comment_form_field_comment', array ( $input, 'show' ), 10, 2 ); \add_action( 'comment_role_selector', array ( $input, 'print_select' ) ); // remove this if you want to show the select field with // do_action( 'comment_role_selector' ); \add_filter( 'comment_text', array ( $output, 'show' ), 10, 2 ); \add_action( 'comment_role_value', array ( $output, 'show_action' ), 10, 2 ); if ( 'POST' === $_SERVER[ 'REQUEST_METHOD' ] ) \add_action( 'comment_post', array ( $data, 'save' ) ); } } 

Абстрактный базовый класс метаданных

 /** * Base class for handling comment meta data. */ abstract class Comment_Meta_Data_Model { /** * Meta key * * @type string */ protected $key; /** * Constructor * * @param string $key */ public function __construct( $key ) { $this->key = $key; } /** * Get current key * * @return string */ public function get_key() { return $this->key; } /** * Wrapper for the native get_comment_meta() * * @param int $comment_ID * @return string */ public function get_comment_meta( $comment_ID ) { $meta = \get_comment_meta( $comment_ID, $this->key, TRUE ); $allowed = $this->get_allowed_values(); // get real display value if ( isset ( $allowed[ $meta ] ) ) return $allowed[ $meta ]; return ''; } /** * Save comment mate data. * * @param int $comment_ID * @return bool */ public function save( $comment_ID ) { $role_keys = array_keys( $this->get_allowed_values() ); if ( ! isset ( $_POST[ $this->key ] ) ) return; if ( ! in_array( $_POST[ $this->key ], $role_keys ) ) return; return \update_comment_meta( $comment_ID, $this->key, $_POST[ $this->key ] ); } /** * Get user role. */ public function get_current_value() { $user = \wp_get_current_user(); if ( empty ( $user->roles ) ) return array (); return $user->roles; } /** * @return array */ abstract public function get_allowed_values(); } 

Расширенный класс для встроенных ролей

 /** * User roles as comment meta. */ class Comment_Meta_Builtin_Roles extends Comment_Meta_Data_Model { /** * (non-PHPdoc) * @see WPSE.Comment_Meta_Data_Model::get_allowed_values() */ public function get_allowed_values() { global $wp_roles; if ( empty ( $wp_roles ) ) $wp_roles = new \WP_Roles; $output = array(); foreach ( $wp_roles->roles as $identifier => $role ) $output[ $identifier ] = $role['name']; return $output; } } 

Расширенный класс для пользовательского выбора разрешенных ролей

 /** * Custom roles for comment meta. */ class Comment_Meta_Custom_Roles extends Comment_Meta_Data_Model { /** * (non-PHPdoc) * @see WPSE.Comment_Meta_Data_Model::get_allowed_values() */ public function get_allowed_values() { return array ( 'teacher' => 'Teacher', 'student' => 'Student' ); } } 

Основной метаданный комментарий

 /** * Base class to show comment meta data. */ class Comment_Meta_View { /** * Model * * @type Comment_Meta_Data_Model */ protected $data; /** * Constructor. * * @param Comment_Meta_Data_Model $data */ public function __construct( Comment_Meta_Data_Model $data ) { $this->data = $data; } } 

Используйте поле выбора в виде

 /** * Show role selector from comment meta */ class Comment_Meta_Role_Selector extends Comment_Meta_View { /** * Add 'select' field before textarea. * * @param string $text_field * @return string */ public function show( $text_field ) { return $this->get_select() . $text_field; } /** * Select element. * * @return string */ public function get_select() { $allowed = $this->data->get_allowed_values(); $current = $this->data->get_current_value(); $key = $this->data->get_key(); // is the current value part of the allowed values? if ( ! empty ( $current ) && array() !== array_intersect( $allowed, $current ) ) return $this->get_hidden_field( $key, $current[0] ); $select = '<p>'; $select .= sprintf( '<label for="%1$s_id">Your role:</label> <select name="%1$s" id="%1$s_id">', $key ); $select .= '<option value="">Select a role</option>'; foreach ( $allowed as $internal => $display ) $select .= sprintf( '<option value="%1$s">%2$s</option>', \esc_attr( $internal ), \esc_html( $display ) ); return $select . '</select></p>'; } /** * Print preselcted role as hidden input field. * * @param string $name Field name * @param string $role Internal role name * @return string */ protected function get_hidden_field( $name, $role ) { return sprintf( '<input type="hidden" name="%1$s" value="%2$s">', $name, esc_attr( $role ) ); } /** * Callback for do_action. * * @wp-hook comment_role_selector * @return void */ public function print_select() { print $this->get_select(); } } 

Показывать текущую роль в виде

 /** * Show current comment role. */ class Comment_Meta_Role_Display extends Comment_Meta_View { /** * Add role to comment text. * * @wp-hook comment_text * @param string $text * @param object $comment * @return string */ public function show( $text, $comment ) { $role = $this->data->get_comment_meta( $comment->comment_ID ); if ( '' !== $role ) $text = "Role: $role<br> $text"; return $text; } /** * Print the comment meta value into a template. * * Usage: <code>do_action( 'comment_role_value', 'Role: %s<br>', $comment ); * * @wp-hook comment_role_value * @param string $template * @param object $comment * @return void */ public function show_action( $template, $comment ) { $role = $this->data->get_comment_meta( $comment->comment_ID ); if ( '' !== $role ) printf( $template, $role ); } } 

Как вы можете видеть, у нас сейчас семь классов:

  1. Comment_Meta_Controller
    Здесь другие классы объединяются, чтобы сделать что-то полезное.
  2. Comment_Meta_Data_Model Базовый класс для обработки данных комментария. Не может использоваться как есть, должен быть расширен.
  3. Comment_Meta_Builtin_Roles
    Расширяет Comment_Meta_Data_Model и использует все встроенные роли. Я использовал это для своих тестов; вы должны, вероятно, использовать следующий класс. Для этого измените контроллер.
  4. Comment_Meta_Custom_Roles
    Расширяет Comment_Meta_Data_Model . Альтернатива для Comment_Meta_Builtin_Roles .
    Как вы можете видеть, вам нужно изменить только один метод (функцию), чтобы вернуть массив пользовательских ролей.
  5. Comment_Meta_View
    Базовый класс для вывода. Не может использоваться как есть, должен быть расширен.
  6. Comment_Meta_Role_Selector
    Расширяет Comment_Meta_View . Создает элемент select . Он ничего не знает об источнике ваших данных и получает свои значения прямо из представления.
  7. Comment_Meta_Role_Display
    Расширяет Comment_Meta_View . Показывает текущее значение комментария.

Применение

Чтобы показать поле select

  • Ничего не делайте, и мои дефолты выполняют эту работу. Поле выбора будет установлено прямо над текстовым полем комментария.
  • Или удалите строку …

     \add_filter( 'comment_form_field_comment', array ( $input, 'show' ), 10, 2 ); 

    … и используйте в своем комментарии форму этого кода:

     do_action( 'comment_role_selector' ); 

Чтобы установить пользовательские значения для разрешенных ролей, удалите строку …

  $data = new Comment_Meta_Builtin_Roles( '_comment_role' ); 

… и раскомментируйте следующую строку. Затем отредактируйте Comment_Meta_Custom_Roles .

Чтобы изменить мета-ключ , просто измените значение '_comment_role' . Убедитесь, что вы не используете встроенный ключ из WordPress.

Это все.