Drupal 7: Crear nuevas acciones para Views bulk operations (VBO)
VBO se puede alimentar de acciones desde tres lugares distintos: De las acciones del sistema, de las acciones que uno crea con rules (vean http://nodeone.se/da/node/775) y las acciones creadas por módulos de terceros.
En este caso vamos a hacer lo tercero.
El caso ideal para crear una action propia es cuando necesitas flexibilidad total. En el ejemplo que voy a compartir necesitaba que la acción tuviera valores por defecto:
Y un formulario para que el usuario pueda escribir algo distinto antes de realizar la acción:
Hagamoslo!
El caso de uso es el siguiente: tengo un view con VBO que tiene que poder hacer una solicitudes de información para cada uno de los nodos (productos), pero dando la oportunidad de que el usuario pregunte algo conciso.
Para esto, la implementación tiene 3 actores bien diferenciados:
- La acción
- El formulario de configuración que exponemos a la hora de configurar la acción en VBO
- El formulario que le mostramos al usuario para que pueda personalizar su solicitud
1: La acción:
Declarar una nueva action en Drupal es fácil, solo necesitas el hook_action_info() y una función que haga de action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/** * Implements hook_action_info(). */ function mimodulo_action_info() { $info['mimodulo_send_solinfo_action'] = array( 'type' => 'node', 'label' => t('Enviar solicitudes de información'), 'configurable' => TRUE, ); return $info; } function mimodulo_send_solinfo_action($node, $context = array()) { _mimodulo_send_solinfo($node, $context['user_data']); } /** * Envía una solicitud de informacion por email. */ function _ecentros_send_solinfo($node, $user_data) { // $user_data['tu_diras']; } |
No voy a entrar en detalles porque pueden leer lo necesario en hook_action_info(). Solo comentar que hemos declarado una nueva acción que solo se puede usar en contenidos de tipo nodo, y que es configurable. Que sea configurable quiere decir que le vamos a proporcionar un formulario al usuario para que haga algo. En mi caso el formulario tiene un textarea para que nos diga sobre que quiere informarse.
2: El formulario para el administrador:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * Implememts HOOK_ACTION_views_bulk_operations_form */ function mimodulo_send_solinfo_action_views_bulk_operations_form($settings, $entityType, $settings_dom_id) { //establecemos los valores por defecto $settings += array( 'tu_diras' => "", ); $form['tu_diras'] = array( '#title' => t('Tu dirás'), '#type' => 'textarea', '#description' => t('Si quieres puedes proveer un texto por defecto para el usuario'), '#default_value' => $settings['tu_diras'], ); return $form; } |
VBO nos proporciona el “HOOK_ACTION“_views_bulk_operations_form las comillas son porque no es estrictamente un hook tradicional, pero vamos, que usa el mismo patrón, solo que en lugar de usar el nombre del modulo como “HOOK”, usamos el nombre de la función de la acción. En este ejemplo el nombre de la acción es “mimodulo_send_solinfo_action“.
El resultado de este hook lo podemos ver cuando añadimos nuestra acción a las que va a tener un view (la primer imagen de este post).
3: El formulario para el usuario:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
/** * Implememts HOOK_ACTION_form */ function mimodulo_send_solinfo_action_form($context) { $context['settings'] += array( 'tu_diras' => "", ); $form['tu_diras'] = array( '#title' => t('Tu dirás'), '#type' => 'textarea', '#description' => t('Si quieres saber algo en particular por favor indicanoslo aquí'), '#default_value' => $context['settings']['tu_diras'], ); return $form; } /** * Implememts HOOK_ACTION_validate */ function mimodulo_send_solinfo_action_validate($form, $form_state) { //No hace falta validar } /** * Implememts HOOK_ACTION_submit */ function mimodulo_send_solinfo_action_submit($form, $form_state) { //Devolvemos un array formateado como a nosotros mas nos guste. //Este array se va a enviar a la action dentro de $context['user_data'] return array( 'user_data' => array( 'tu_diras' => $form_state['values']['tu_diras'] ), ); } |
Como ya comenté antes, al declarar una acción, si esta lleva configuración (‘configurable’ => TRUE), tenemos que proporcionar un formulario. Para implementarlo es la mar de simple, solo tienes que tratarlo como un FAPI normal y tenes que tener el cuenta la forma en la que nombras el formulario HOOK_ACTION_form, su validacion HOOK_ACTION_validate y el submit HOOK_ACTION_submit.
En la declaración del formulario podemos ver que tenemos un parámetro “$context“. Bueno este parámetro contiene entre otras cosas, la configuración que hemos proporcionado en el momento que añadimos la action al view. Y la estamos usando para establecerle al usuario un valor por defecto.
Y ya está, tenemos una action que funciona.
Ah y acá está todo junto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/** * Implements hook_action_info(). */ function mimodulo_action_info() { $info['mimodulo_send_solinfo_action'] = array( 'type' => 'node', 'label' => t('Enviar solicitudes de información'), 'configurable' => TRUE, ); return $info; } function mimodulo_send_solinfo_action($node, $context = array()) { _mimodulo_send_solinfo($node, $context['user_data']); } /** * Envía una solicitud de informacion por email. */ function _ecentros_send_solinfo($node, $user_data) { // $user_data['tu_diras']; } /** * Implememts HOOK_ACTION_form */ function mimodulo_send_solinfo_action_form($context) { $context['settings'] += array( 'tu_diras' => "", ); $form['tu_diras'] = array( '#title' => t('Tu dirás'), '#type' => 'textarea', '#description' => t('Si quieres saber algo en particular por favor indicanoslo aquí'), '#default_value' => $context['settings']['tu_diras'], ); return $form; } /** * Implememts HOOK_ACTION_validate */ function mimodulo_send_solinfo_action_validate($form, $form_state) { //No hace falta validar } /** * Implememts HOOK_ACTION_submit */ function mimodulo_send_solinfo_action_submit($form, $form_state) { //Devolvemos un array formateado como a nosotros mas nos guste. //Este array se va a enviar a la action dentro de $context['user_data'] return array( 'user_data' => array( 'tu_diras' => $form_state['values']['tu_diras'] ), ); } /** * Implememts HOOK_ACTION_views_bulk_operations_form */ function mimodulo_send_solinfo_action_views_bulk_operations_form($settings, $entityType, $settings_dom_id) { //establecemos los valores por defecto $settings += array( 'tu_diras' => "", ); $form['tu_diras'] = array( '#title' => t('Tu dirás'), '#type' => 'textarea', '#description' => t('Si quieres puedes proveer un texto por defecto para el usuario'), '#default_value' => $settings['tu_diras'], ); return $form; } |
Chau!