Hooks en Drupal. form_set_value y form_alter

erdanblo

Buenas,

Tengo un problemilla con estos hooks de Drupal y es que no entiendo porque no me funcionan.

Tengo un tipo de contenido propio creado (he visto que antes era incompatibles, pero desde D7 esa incompatiblidad no existe, porque se integró en el core).

Me he creado un módulo, y estoy llamando a estos hooks así:

function modificar_urlimage_form_set_value($element, $value, &$form_state){
exit();
}

o

function modificar_urlimage_form_alter&$form, &$form_state, $form_id) {
exit();
}

En teoría eso al darle al submit o algo en el formulario, me debería de salir una página en blanco no?

El caso es que se lo salta completamente, como si form_xx no fuese nada.

:S que estoy haciendo mal.

Si declaro otros hooks como node_presave si me funcionan. Lo estoy hacinedo en un .module. También he probado a declararlos en el template.php de la plantilla y renombrar la función al nombre de la plantilla, pero igualmente, no funciona :S

alterego

No me ha quedado muy claro, qué funcionalidad quieres conseguir?

1 respuesta
erdanblo

Buenas,

En resumen:

Tengo un formulario que tiene un campo URL. Antes de que eso se guarde en la DDBB quiero tratar el campo ese, obtener una ID y guardarlo en otro campo del nodo que tengo.

Explicación larga:

Uso una plantilla que es DAN Polaroid. Esta plantilla a los articulos les pone una imagen, que viene determinado por un campo image. Para rellenar ese campo el usuario al subir la imagen tiene que elegirla.

Yo me he creado un tipo de contenido propio con un campo youtube (con el plugin de youtube field), entonces quiero que al poner el video de youtube, coger el ID del video y pasarlo al campo image, también ya he conseguido rellenarlo sin que el usuario tenga que buscar la imagen, sino a través de colocar una url (lo he hecho con FileFieldSources).

Para hacer todo eso lo necesito antes de guardar el nodo :D

Otra opción es modificar los .tpl pero es que al crear otro archivo .tpl con otro nombre, asignarle una vista distinta a la de mi tipo de contenido propio con las del frontpage que viene por defecto, no me reconoce el $node, me dice que es un objeto indefinido, y estoy muy mareado buscando eso y no encontrar solución.

#2

alterego

Una forma de alterar un campo de un nodo antes de guardarlo en base de datos es en la validación del formulario.

Para ello primero le decimos al formulario que pase por nuestra función de validación (a parte de la que tiene drupal para validar fomurlarios). Para ello te tienes que enganchar en el formulario correspondiente.

Para facilitarle las cosas te recomiendo que uses el módulo devel. Es un must a la hora de desarrollar el sitio. Una vez activado podrás visualizar los datos del formulario en la web, se ve más claro.

En tu nombre_de_modulo.module, hay que engancharse con el formulario de creación de nodo para ese tipo de contenido:

function TU_MODULO_form_alter(&$form,&$form_state,$form_id) {
  // dpm es una funcionalidad de devel, que te muestra el contenido de esa variable,
  //viene a ser lo mismo que print_r, pero mucho más amigable.
  dpm($form_id, 'form id');
  
// También puedes hacer un dpm al $form y ver todo lo que tiene el formulario }

Ahora no tienes más que ir a la página de crear ese tipo de contenido y ver el form id que tiene ese formulario, lo más seguro que sea = nombreTipoContenido_node_form

Una vez tienes el form_id del formulario vamos a añadirle nuestra función de validación, para ello usamos el hoo_form_FORM_ID_alter, para sólo tocar ese formulario:

function TU_MODULO_form_FORM_ID_DE_TU_FORM_alter(&$form, &$form_state, $form_id) {
  // Declaramos una nueva función de validación donde vas a modificar
  // el valor de los campos.
  $form['#submit']['#validate'] = 'nombre_de_tu_funcion_form_validate';
}

Ahora ya sólo queda definir tu función de validación:

function nombre_de_tu_funcion_form_validate($form, &$form_state) {
  // En el $form_state están los valores del formulario, los puedes manipular
  // los valores están en $form_state['values']
  dpm($form_state);

  //Ya "sólo" te queda pillar el valor de un campo, obtener el id y pasárselo al campo imagen
  $video_id = $form_state['values']['CAMPO_VIDEO_YOUTUBE'];
  
... Tu funcionalidad ... $form_state['values']['CAMPO_IMG'] = loquesea; }

Hay muchos formas, caminos de conseguir esto que propones, está es una de ellas.

2 respuestas
erdanblo

joder muchas gracias.

Creo que mi fallo es que no lo enganchaba, como tu dices. Luego pruebo.

El módulo devel, lo estaba usando, pero no me había dado cuenta del detalle ese que comentas. Lo dle ID del formulario, pero vamos que algo me he saltado. Lo pruebo tal como tu me detallas y te digo.

erdanblo

#4 Gracias de nuevo.

Ya he visto donde la había "liado".

Mi modulo se llama:

modificar_urlimage.module y en el .info tenia esto:

name = Modifica la URL del campo Image al vuelo
description = Modifica la URL del campo Image al vuelo
version = 0.1
core = 7.x
package = DANI Modules

He puesto en name lo mismo que en el nombre de los ficheros, deshabilitado y habilitado el modulo y ale! working like a charm!

Por cierto, ahora entiendo muchas cosas mas de cuando vi este videotutorial (me parecio muy bueno, pero claro no me funcionaba por lo anterior)

14 días después
erdanblo

Hola,

Estoy teniendo otro problemilla.

Creo que al final voy a solucionar el problema, modificando el node.tpl.php

Uso Zen+Subtheme llamado Dan Polaroid.

En la carpeta template/ del DAN tengo esto: node--dan-polaroid.tpl.php que es el que quiero cambiar.

Entonces lo renombro a node--youth-proposal.tpl.php que es el nombre de mi tipo de contenido personal.

El caso, es que nada, no hay tu tia.

No sé muy bien como debuggear con devel, en este caso, según me dijiste @alterego #4

alterego

Para crear un tpl para un tipo de contenido es como lo estás haciendo: node--nombreTipoContenido.tpl.php Tienes que poner el nombre de máquina del tipo de contenido.
Que no se te olvide vaciar las caches para que te lo pille.
Si tienes drush instalado te vale con un drush cc all, o por interfaz en /admin/config/development/performance

De todas formas puedes ver las opciones de tpl para ese tipo de contenido de la siguiente forma. En el temaplate.php de tu subtema. En la función prerpocess_node puedes ver los tpl que le puedes cascar en $variables['theme_hook_suggestions']

function TUTEMA_preprocess_node(&$variables) {
  dpm($variables, 'variables');
  dpm($variables['theme_hook_suggestions'], 'theme hook suggestions'); // las barras bajas se pasan a guiones para el nombre del tpl ej node_xxx = node--xxx.tpl.php
}
1 respuesta
erdanblo

#8 Otra vez de nuevo y gracias a tu explicación, ya he conseguido resolver el problema. De hecho me gusta más esta solución que como lo estaba intentando hacer.

En este caso pienso que lo estaba haciendo bien, de hecho una vez, pero no sé cosa del drupal y las caches, tras borrar muchas veces me salio, aun así el truquito que me has puesto para sacar los "suggestion hooks" es la hostia :D

Creo que me va a salvar muchas mas horas de tiempo gracias a eso. Me guardo este post como en oro en paño.

De nuevo,

Muchas gracias @Alterego

Usuarios habituales

  • erdanblo
  • alterego