Cómo modificar el formulario de un tipo de contenido en Drupal
Carlos — Mié, 14/01/2009 - 11:57
Pablo (no sé su web) me preguntó en un comentario cómo podía modificar el formulario de un tipo de contenido para adecuar el diseño según sus necesidades.
Lo primero de todo es ver si los cambios que queremos hacer se pueden realizar sólo con CSS ya que así será mucho más fácil y rápido. Estos puede ser algunos trucos:
- Si no queremos que salga algo le ponemos un display: none
- Si un label sale encima del input y queremos que salga en la misma línea podemos poner un display: inline o flotarlo. Esto será necesario hacerlo también con el propio input
- Si por el contrario queremos que salgan en líneas diferentes le ponemos un display: block a lo que queramos que esté él sólo en una línea.
Si vemos que no es posible y que es necesario cambiar el html se puede hacer asi:
Ponemos en el fichero template.php del theme lo siguiente:
<?php
function phptemplate_node_form($form) {
//drupal_set_message("Reescribiendo el formulario de " . $form['#node']->type);
if($form['#node']->type) {
if(file_exists(path_to_theme() . '/forms/form-' . $form['#node']->type . '.tpl.php')) {
//drupal_set_message("Encuentra el fichero y lo reescribe");
return _phptemplate_callback(path_to_theme() . 'forms/form-' .
$form['#node']->type, array('form' => $form));
}
else {
return theme_node_form($form);
}
}
}
?>
Luego creamos un directorio forms en el directorio del theme y allí ponemos las plantillas de nuestros formularios con nombres que sean: form-nombre_del_tipo_de_contenido.tpl.php. Por ejemplo, si tenemos un tipo de contenido que se llama articulos el formulario se llamará form-articulos.tpl.php
Dentro de ese archivo tenemos la variable $form que es un array con cada uno de los campos del formulario. Lo esencial de ese archivo es lo siguiente:
<?php
print drupal_render($form);
?>
Esto imprime todo el formulario. Pero por ejemplo nosotros podemos imprimir primero un campo y luego imprimir el resto:
<?php
print '' . drupal_render($form['trozo_del_formulario') . '';
print drupal_render($form);
?>
Podemos también quitar cosas del formulario dependiendo del usuario:
<?php
global $user;
if ($user->uid <> 1) {
unset($form['body_filter']);
}
?>
Por cierto, en Drupal 6 funciona distinto la forma de decirle que use la plantilla que queremos:
<?php
function nombre_de_tu_tema_theme(&$existing, $type, $theme, $path) {
$hooks['nombre_tipo_contenido_form'] = array( 'arguments' => array('form' => NULL),
'template' => 'path_que_quieras/el_nombre_que_quieras' );
return $hooks;
}
?>
Hola Carlos! Bueno muchas
Pablo (no verificado) — Mié, 14/01/2009 - 16:20Hola Carlos!
Bueno muchas gracias en primer lugar por el post. Queria consultarte algo ya que todavia no tengo muy en claro el manejo de los css en drupal. quiero probar si puedo hacer estas modificaciones como decis solo con css, el problema es que no se como hacer para que estas modificaciones solo se apliquen a un tipo de contenido especial que tengo hecho con cck, es decir como vos decis si tengo un tipo de contenido articulo y quiero modificar algun aspecto con css en el form como hago para que ese aspecto se modifique pero solo para ese tipo de contenido y no para otros. Por ejemplo quiero poner como explicas supongamos un display: none en la descripcion de un campo pero no quiero que esto sea general para todos los tipos de contenido.
No se si me explico muy bien, por ahi podria crearse algun archivo style-tipodecontenido.css solo para este tipo o algo asi.
Nuevamente muchas gracias y muy bueno el blog!
saludos
Yo denuevo: Bueno molestando
Pablo (no verificado) — Mié, 14/01/2009 - 16:59Yo denuevo:
Bueno molestando nuevamente... estoy tratando de seguir lo que pones en el post pero no me imprime en form con esto
<?php
print drupal_render($form);
?>
Es decir el otro codigo si funciona probe habilitando los mensajes que pones y llega todo bien hasta el archivo en la carpeta forms pero no me muestra el formulario, sale todo en blanco.
No se si influira pero tengo los campos divididos en grupos en tabs, aunque he probado sacando algunos y tampoco se ven.
Nuevamente muchas gracias y disculpas por las molestias
Sobre lo primero si lo
Carlos — Mié, 14/01/2009 - 18:13Sobre lo primero si lo quieres hacer con CSS mira bien que normalmente cada formulario de tipo de contenido tiene un id específico con lo cual puedes aplicar una regla que sólo se aplicará donde quieres. Por ejemplo:
#id_formulario #id_campo {
display: none;
}
Para lo segundo, podría ser que el código que he puesto no funcione correctamente porque lo he modificado un poco sin probarlo pero para estar seguro lo mejor es ir poniendo mensajes en cada paso para ver cual es el que no funciona. En el código que he puesto con descomentar un par de líneas ya puedes saber un poco más de donde falla.
Esto se suele preguntar
manuee — Jue, 15/01/2009 - 01:06Esto se suele preguntar bastante, y es una de las cosas que atascan a los "plantilleros", seguro que a mas de uno le vendra bien el articulo :)
Si quieren profundizar, hay un articulo en la documentacion que habla de themear formularios CCK
No se olviden de usar el codigo siguiente para ver como se llama cada campo:
<?php
print("");
print_r(array_values($form));
print("");
?>
Otra alternativa, para tener el tpl mas limpio es crear las variables para cada campo en tu funcion preprocess (drupal 6) en template.php tal que asi:
<?php
$vars['blabla_title'] = drupal_render($vars['form']['title']);
?>
y de esta forma solo has de hacer <?php print $blabla_title ?> en el tpl :)
Buen apunte manuee! Me olvidé
Carlos — Jue, 15/01/2009 - 10:24Buen apunte manuee! Me olvidé de poner lo de preprocess. Pedro me ha pasado un enlace donde está muy bien explicado para Drupal 6: http://11heavens.com/theming-the-contact-form-in-Drupal-6
Hola, muchas gracias por este
Gustavo Cabral (no verificado) — Jue, 15/01/2009 - 20:12Hola, muchas gracias por este tuto, quería preguntarte si existe la manera de diseñar un formulario tipo "tabloide" para la impresión de mi formulario en pantalla; la idea es llenar ese formulario impreso con los datos obteniados de mi formulario en pantalla. Vi en un manual de css que tambien se puede modificar los estilos para la impresión, pero se pueden realizar líneas, rectangulos, etc?
Sino, ¿como podría realizar esto?
Espero que entiendan mi idea.
Saludos.-
Hola Gustavo, la verdad es
admin — Jue, 15/01/2009 - 23:08Hola Gustavo,
la verdad es que no te he entendido del todo. ¿Podrías hacer un dibujo?
Pingback
Artículos destacados, Enero de 2009 | cambrico.net (no verificado) — Vie, 06/02/2009 - 14:31[...] Modificar el formulario de un tipo de contenido, en el blog de Carlos Rincón. [...]
Hola chicos, no llego a
Javi (no verificado) — Vie, 06/02/2009 - 18:42Hola chicos, no llego a comprender completamente el proceso de drupal 6:
<?php
function nombre_de_tu_tema_theme(&$existing, $type, $theme, $path) {
$hooks['nombre_tipo_contenido_form'] = array( 'arguments' => array('form' => NULL),
'template' => 'path_que_quieras/el_nombre_que_quieras' );
return $hooks;
}
?>
¿Desde donde se le llama a esta función?
Supongamos que mi tema es garland y que quiero asociar el contenido a un tipo nuevo que he creado que se llama política, como se haría el code ya que he probado de varias formas y no me ha funcionado.
Agradeceré su ayuda.
Salu2.
Pues deberías poner en el
admin — Sáb, 07/02/2009 - 14:40Pues deberías poner en el template.php de tu tema lo siguiente:
<?php
function garland_theme(&$existing, $type, $theme, $path) {
$hooks['politica_form'] = array( 'arguments' => array('form' => NULL),
'template' => 'forms/politica' );
return $hooks;
}
?>
Y con esto podrás modificar el formulario usando la plantilla politica.tpl.php situada dentro del directorio forms dentro de tu tema (en este caso garland).
De todas maneras dos cosas:
Hola, te comento... He
Javi (no verificado) — Sáb, 07/02/2009 - 19:22Hola, te comento...
He cambiado de template a otro y en el documento template.php del tema he puesto el code sin acentos y he modificados los acentos dejando solo politica.
He creado una carpeta llamada forms y dentro de ella el documento politica.tpl.php y no me sale nada. También he probado crear dentro de la carpeta forms una carpeta que se llame politica y dentro de esta politica.tpl.php y tampoco muestra nada.
Es como si no los cargase o no los tuviese en cuenta.
Alguna sugerencias ??
Gracias a todos.
Hola Carlos, acabo de
Limay (no verificado) — Lun, 09/02/2009 - 21:35Hola Carlos, acabo de encontrar un módulo que también puede ayudar a esconder campos si no se quiere trastear mucho con la API: http://drupal.org/project/formfilter
Parece útil :)
Hola, tengo una duda
kikeleash (no verificado) — Lun, 18/05/2009 - 21:39Hola, tengo una duda existencial sobre el camino que debo seguir para darle mayor funcionalidad al sitio que estoy armando con drupal, soy nuevo y mi problema es el sigueinte.
Un tipo de contenido en el sitio puede ser escrito por cualquier usuario que nos visita, este tipo de contenido es llamado "Denucnia Ciudadana", esta Denuncia debe llevar un Nombre de Ciudad, Colonia/barrio, y Código postal. añadí los campos con CCK, ahora, queremos que los campos estén ligados y que al seleccionar la ciudad solo se puedan seleccionar las colonias de dicha ciudad; Mi duda es, puedo implementar esta funcionalidad personalizando el form?? ó es necesario que agregue un módulo para esto??
Agredecería mucho una orientación, porque ando medio perdido :(
si la carpeta forms está
Adam (no verificado) — Mié, 08/07/2009 - 03:38si la carpeta forms está dentro de la plantilla y al mismo nivel que template.php quedaría asi.
function phptemplate_node_form($form) {
drupal_set_message("Reescribiendo el formulario de " . $form['#node']->type);
if($form['#node']->type) {
if(file_exists(path_to_theme() . '/forms/form-' . $form['#node']->type . '.tpl.php')) {
drupal_set_message("Encuentra el fichero y lo reescribe");
return _phptemplate_callback('forms/form-' . $form['#node']->type, array('form' => $form));
}
else {
return theme_node_form($form);
}
}
}
Hola Carlos excelente
Juliobravo (no verificado) — Vie, 21/08/2009 - 05:04Hola Carlos excelente articulo, es grato saber que se esta produciendo informacion sobre Drupal en español, ademas de un alivio. He estado jugando con la funcion print_r para obtener los campos disponibles del formulario de registro y de mis contenidos especificos. Ya logro imprimir algunos campos a mi antojo, pero sin embargo mi mayor problema es que no puedo leer los arrays, me explico no se como colocarlos al momento de decirle print y en un formulario es mas dificil que en algun tipo de contenido. Me gustaria que pudieras orientarnos a interpretar los resultados de la funcion print_r para posteriormente imprimir nuestros documentos y formularios a nuestro antojo.
Ahhhhh, bueno no es del tema pero aprovechando tu conocimiento, es posible realizar un tipo de contenido que este embebido dentro de otro, el simil seria como los comentarios, tienes un formulario y se publica dentro de la pagina del articulo, lo quiero para poner cotizaciones pero no se como vincular uno con otro y que se publique en la pagina que se solicito la cotizacion. jejejeje gracias de antemano por tu ayuda.
Si instalas el módulo devel y
Carlos — Vie, 21/08/2009 - 09:39Si instalas el módulo devel y usas la función dsm en lugar de print_r es más gráfico y te lo imprime dentro de la variable $messages.
Te has de fijar si es un objeto o un array. Si es un objeto para acceder a una de sus propiedades has de usar ->
Por ejemplo si pone y has imprimido $node:
"(Object) stdClass"
[nid] => 34
Para acceder a su valor has de poner $node->nid
Si pone:
array
[nid] => 34
Entonces para acceder has de usar $node['nid']
Puede ser que un objeto contenga otro objeto u otro array, simplemente has de ir uno a uno.
Para lo otro lo mejor es que uses node reference, viene con CCK.
Carlos, muchas gracias por la
juliobravo (no verificado) — Vie, 21/08/2009 - 17:57Carlos, muchas gracias por la pronta respuesta, voy a seguir tu recomendacion.
Hola Carlos, he estado
Juliobravo (no verificado) — Lun, 31/08/2009 - 00:25Hola Carlos, he estado siguiendo tus susgerencias, me ha costado la verdad, y buscando mas informacion sobre el asunto, cuando se trata de formularios (no se si solo es con formularios, o con tipos de contenido tambien), se debe "declarar" las variables en el archivo template.php
function garland_preprocess_user_register(&$vars) {
// That's where $form_markup is created
$vars['account'] = drupal_render($vars['form']['account']);
$vars['autoassignrole_user']= drupal_render($vars['form']['autoassignrole_user']);
}
para luego poner en el archivo archivo_especifico.tpl.php
<?php print $account ; ?>
<?php print $autoassignrole_user['user_roles']?>
Oh, esto es lo que he logrado, sin embargo, me gustaria seccionar la parte de autoassingrole_user en el cual por medio de radio botones los usuarios eligen el rol al que se quieren inscribir, y me gustaria colocarle un mensaje antes de cada boton.
autoassignrole_user (Array, 19 elements)
#type (String, 8 characters ) fieldset
#title (String, 10 characters ) User Roles
#collapsible (Boolean) FALSE
#collapsed (Boolean) FALSE
user_roles (Array, 23 elements)
#type (String, 6 characters ) radios
#title (String, 4 characters ) Role
#options (Array, 3 elements)
2 (String, 19 characters ) usuario autenticado
4 (String, 12 characters ) trabajadores
3 (String, 12 characters ) publicadores
#description (String, 0 characters )
2 (Array, 21 elements)
#type (String, 5 characters ) radio
#title (String, 19 characters ) usuario autenticado
#return_value (String, 1 characters ) 2
#default_value (NULL)
#attributes (Array, 0 elements)
#parents (Array, 1 element)
0 (String, 10 characters ) user_roles | (Callback) user_roles();
#id (String, 17 characters ) edit-user-roles-2
#ahah (NULL)
#post (Array, 0 elements)
#programmed (Boolean) FALSE
#tree (Boolean) FALSE
#weight (Integer) 0
#processed (Boolean) TRUE
#description (NULL)
#required (Boolean) FALSE
#input (Boolean) TRUE
#process (Array, 1 element)
#0 (String, 16 characters ) form_expand_ahah | (Callback) form_expand_ahah();
#name (String, 10 characters ) user_roles | (Callback) user_roles();
#value (String, 0 characters )
#defaults_loaded (Boolean) TRUE
#sorted (Boolean) TRUE
4 (Array, 21 elements)
#type (String, 5 characters ) radio
#title (String, 12 characters ) trabajadores
#return_value (String, 1 characters ) 4
.............................................................
3 (Array, 21 elements)
#type (String, 5 characters ) radio
#title (String, 12 characters ) publicadores
etc, etc, etc
He tratado de poner como me dijiste las cosas, pero no logro imprimir los radiobotones solos, ya he identificado que la informacion que necesio tratar se encuentra dentro de
autoassignrole_user....user_roles....2.....,
no se si debo declararlo en el template.php asi de seccionado. Disculpame, pero he tratado y nada que logro darle al chiste, ademas tengo dificultad en seguir la ruta y el tipo de signos utilizado para llamar a cada elemento, se que tener claro esto me abre la posibilidad de personalizar cada parte de mi web.
De antemano, muchas gracias.
Cuando es un objeto has de
Carlos — Lun, 31/08/2009 - 17:55Cuando es un objeto has de usar -> y cuando es un array ['']
Por ejemplo si tenemos: un objeto llamado objeto_pepe que dentro tiene otro objeto llamado objeto_luis y este tiene un array llamado array_jose y este tiene dentro otro array llamado array_maria y este tiene dentro un objeto llamado objeto_luisa y este tiene un atributo (un valor) llamado atributo_carlos
y queremos acceder al atributo_carlos la cosa sería:
objeto_pepe->objeto_luis['array_jose']['array_maria']->objeto_luisa->atributo_carlos
No sé si preguntabas algo así...
Gracias Carlos, si eso es
juliobravo (no verificado) — Mar, 01/09/2009 - 19:07Gracias Carlos, si eso es precisamente lo que buscaba, sin embargo, creo que el personalizar formularios es diferente y mas intrincado que cuando se personaliza un tipo de contenido. Como te decia en el mensaje, parece no ser suficiente el llamar los campos desde el archivo user_register.tpl.php (en mi caso), sino que para formularios, los campos se deben "referenciar" en el archivo template.php. Por lo menos a mi no me funciona si no lo hago asi.
la sintaxis de lo que digo es:
$vars['account'] = drupal_render($vars['form']['account']);
$vars['autoassignrole_user']= drupal_render($vars['form']['autoassignrole_user']);
Con esto logro imprimir el account y autoassignrole_user.
Pero que si quiero imprimir el "tipo" de account, o separar las opciones de autoassignrole_user, no se puede. Como puedo ser mas especifico en el template.php?????
bueno, mi tema se llama
McO Artista — Vie, 30/10/2009 - 00:40bueno, mi tema se llama "negocios" y tengo un tipo de contenido propaganda y pongo en el template este codigo
<?php
function negocios_theme(&$existing, $type, $theme, $path){
$hooks['propaganda_form'] = array('arguments' => array('form' => NULL), 'template' => '/forms/propaganda');
return $hooks;
}
?>
y en el propaganda.tpl.php que se encuentra dentor de forms en mi tema pongo
<?php
print 'marco';
print drupal_render($form);
?>
pero no me imprime na (osea "marco")
xq???
la solucion please ?
si es que no chequeaste el
McO Artista — Vie, 30/10/2009 - 00:41si es que no chequeaste el codigo es
<?php
function negocios_theme(&$existing, $type, $theme, $path){
$hooks['propaganda_form'] = array('arguments' => array('form' => NULL), 'template' =>
'/forms/propaganda');
return $hooks;
}
?>
hola necesito ayuda, me
maxluna (no verificado) — Lun, 13/12/2010 - 22:13hola necesito ayuda, me gustaría saber como puedo tener un tipo de contenido creado y tomar una referencia p.ej: de un producto o imagen y que salte a un formulario directamente con la referencia de ese contenido. Gracias