¿Agregar una lista desplegable al formulario de comentarios?

2

¿Puede alguien ayudarme a crear un menú desplegable o (botones de radio) en el formulario de comentarios de Wordpress, para que un nuevo usuario pueda hacer una selección de sus roles de usuario (por ejemplo, profesores + estudiantes)?

  1. La salida de la lista desplegable o el botón de radio aparecería en algún lugar de El área de comentarios.
  2. Lo mejor de todo sería también si WordPress ya rellena automáticamente
    correo electrónico, nombre de inicio de sesión también mostrará nueva información de campo adicional (lista desplegable O
    botón de radio) para iniciar sesión en usuarios que ya tienen sus roles de usuario asignado
  3. No quiero usar un complemento para eso.
  4. Sé que hay muchos tutoriales sobre cómo agregar personalización adicional Campos al formulario de comentarios incluyendo esta web donde he encontrado 3. peticiones similares desafortunadamente marcadas como duplicadas, en mi opinión no son dups en absoluto, porque no hay código o tutorial para utilizando valores conocidos como botón (seleccionar - desplegable - radio).
pregunta Daniel Foltynek 02.06.2013 - 13:29

1 respuesta

6
  • Filtre comment_form_field_comment para agregar un elemento select con un label .
  • Agregue una devolución de llamada a la acción comment_post para guardar el valor.
  • Filtre comment_text para mostrar el valor de un comentario.

Código de muestra:

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 );

Actualizar

He reescrito el código para usar un patrón MVC real. Explicación a continuación. Como complemento en GitHub .

Encabezado del complemento

<?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' )
);

Controlador

/**
 * 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' ) );
    }
}

Clase de base de metadatos abstracta

/**
 * 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();
}

Clase ampliada para roles incorporados

/**
 * 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;
    }
}

Clase ampliada para la selección personalizada de roles permitidos

/**
 * 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'
        );
    }
}

Meta vista básica del comentario

/**
 * 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;
    }
}

Usar un campo de selección como vista

/**
 * 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();
    }
}

Mostrar el rol actual como vista

/**
 * 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 );
    }
}

Como puede ver, ahora tenemos siete clases:

  1. Comment_Meta_Controller
    Aquí, las otras clases se combinan para hacer algo útil.
  2. %código% Clase base para manejar los datos de comentarios. No se puede utilizar como está, debe extenderse.
  3. Comment_Meta_Data_Model
    Extiende Comment_Meta_Builtin_Roles y usa todos los roles incorporados. He usado esto para mis pruebas; Probablemente deberías usar la siguiente clase. Cambia el controlador para hacer eso.
  4. Comment_Meta_Data_Model
    Extiende Comment_Meta_Custom_Roles . Una alternativa para Comment_Meta_Data_Model .
    Como puede ver, solo tiene que cambiar un método (función) para devolver una serie de roles personalizados.
  5. Comment_Meta_Builtin_Roles
    Clase base para salida. No se puede utilizar como está, debe extenderse.
  6. Comment_Meta_View
    Extiende Comment_Meta_Role_Selector . Crea el elemento Comment_Meta_View . No sabe nada sobre la fuente de sus datos y obtiene sus valores directamente desde la Vista.
  7. select
    Extiende Comment_Meta_Role_Display . Muestra el valor actual de un comentario.

Uso

Para mostrar el campo Comment_Meta_View cualquiera ...

  • No hagas nada y deja que mis valores predeterminados hagan el trabajo. El campo de selección se establecerá justo encima del campo de texto de comentario.
  • O elimine la línea ...

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

    ... y use en su comentario de este código:

    do_action( 'comment_role_selector' );
    

Para establecer valores personalizados para los roles permitidos, eliminar la línea ...

    $data   = new Comment_Meta_Builtin_Roles( '_comment_role' );

... y descomenta la siguiente línea. Luego edita select .

Para cambiar la meta clave , solo cambia el valor Comment_Meta_Custom_Roles . Asegúrate de no usar una clave integrada de WordPress.

Eso es todo.

    
respondido por el fuxia 04.06.2013 - 13:28

Lea otras preguntas en las etiquetas