FAQ: Gestión de un espacio Web Departamental

Como crear un programa (CGI) sencillo para contestar a formularios.

Vamos a explicar un ejemplo de un programa CGI que conteste a un formulario sencillo, en este caso se nos enviará un mail con los datos introducidos por el usuario en el formulario.

El CGI está escrito en lenguaje Perl, que es un lenguaje muy sencillo de utilizar y que permite escribir programas de escasa dificultad con poco código.

Veamos primero cual será el formulario:

Será un formulario en el que se pida al usuario la introducción de ciertos datos y el envio de comentarios, el formulario será el siguiente:

Nombre:

Apellidos:

Email:

Estamento:

Introduzca sus comentarios:

Definido por las siguientes instrucciones HTM:

<form action="nombre.cgi" method=post>

Nombre: <input type=text name=nombre size=30><p>
Apellidos: <input type=text name=apellido size=50s><p>
Email: <input type=text name=email size=20><p>

Estamento: <select name=estamento>
<option value=pas>PAS
<option value=pdi>PDI
</select>
<p>
Introduzca sus comentarios:
<p>
<textarea name=comentar rows=5 cols=80>
</textarea>

<input type=submit value="Enviar">
</form>

Crearemos un pequeño programa que lea la salida del formulario y lo trate enviandonos un mail con los datos introducidos por el usuario.

Para ello crearemos un programa con la extensión .cgi que será el que se especifique en el atributo ACTION de la instrucción FORM.

El contenido de este programa escrito en lenguaje perl es el siguiente:

#!/usr/local/bin/perl -- -*-perl-*-

# Definición del programa para enviar correo, debe dejarse sin cambios.
$progmail = '/usr/lib/sendmail';

# Usuario al que se enviarán los mensajes. Deberá poner su alias de correo electrónico.
$destino = '___________@uca.es';

# Indica que se trata de un documento HTML
print "Content-type: text/html\n\n";

Esta primera parte debe incluirse sin realizan ningún cambio, solo añadir la dirección email de retorno, en esta definen las variables generales y se incluye la instrucción Content-type que indica al navegador que se trata de un documento HTML (text/html).

# Obtiene la entrada
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

# Divide las variables entre nombre y valor.
@pairs = split(/&/, $buffer);

# Optiene todas las variables y sus valores
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);

$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

$FORM{$name} = $value;
}

En esta parte se obtienen del formulario los pares variables, valor. El código es independiente del número de variables que se hayan introducido, ya que detectará todas las variable que se hayan pasado desde el formulario. Esta parte de código debe ser dejada sin ningún cambio.

# Si la respuesta es vacia, se llama a una función que la trata
&blank_response unless $FORM{'comentar'};

En este caso se llamará a la función si la variable comentar del formulario anterior, que se referencia mediante $FORM{'comentar'}, no tiene nigún valor. Se pueden añadir una linea similar por cada atributo que no pueda contener un campo blanco.

# Imprime el título y la cabecera
print "<Head><Title>Gracias</Title></Head>";
print "<Body><H1>Muchas Gracias, sus comentarios serán bienvenidos</H1>";
# Imprime el texto del texto a mostar.
print "Gracias por enviar sus comentarios a <I>__________</I>!<P>";
print "Vuelva a la <A HREF=\"__________\">página inicial</A>, si lo desea.<P>";

Se incluirá el mensaje que se mostrará tras analizar el formulario, este mensaje será de agradecimiento o de indicación de que su petición ha sido atendida. Aquí se podrá indicar el texto que desee. Será conveniente que incluya un enlace a la página inicial desde la que se accedió al formulario, para facilitar al usuario la vuelta atrás.

Cada línea la formará una instrucción print y entre comillas el texto HTML que se quiere que aparezca. En caso que la instrucción HTML tenga comillas, deberá incluir la secuencia de escape \" como se ve en el ejemplo.

# Ahora enviamos el mail al $destino
open (SALIDA, "|$progmail $destino") || die "No puedo abrir $progmail!\n";
print SALIDA "Reply-to: $FORM{'email'} ($FORM{'nombre'} $FORM{'apellidos'})\n";
print SALIDA "Subject: Comentarios al formulario de prueba ($FORM{'nombre'} $FORM{'apellidos'})\n\n";
print SALIDA "$FORM{'nombre'} $FORM{'apellidos'} del $FORM{'estamento'}envio \n";
print SALIDA "El siguiente comentario::\n\n";
print SALIDA "------------------------------------------------------------\n";
print SALIDA "$FORM{'comentar'}";
print SALIDA "\n------------------------------------------------------------\n";
close (SALIDA);

En este caso todo lo que se incluya en la instrucción print SALIDA será enviado dentro del mail.

En la línea que comienza como Reply-to: se incluirá la dirección de correo a la que se debe replicar el mail, normalmente la dirección de correo de quién envió el formulario.

En la línea que comienza con Subject: Se incluirá el texto que se desea que aparezca como subject del mensaje, que será un texto que le ayuda a identificar el origen del mensaje.

Y luego se incluirán las respuestas al formulario, el orden que lo ponga es indiferente, siendo el formato que utilice el que se mostrará en el mensaje que usted reciba, en este caso como respuesta del formulario se obtendría por correo electrónico:

Date: Thu, 30 May 96 12:55:53 +0200
From: Servidor WWW de la UCA
Reply-To: usuario@uca.es (Nombre del usuario)
Subject: Comentarios al formulario de prueba (Nombre del usuario)
Apparently-To: destino@uca.es

Nombre del usuario del PDI envio
El siguiente comentario:
------------------------------------------------------------
Texto del comentario.

------------------------------------------------------------

# ------------------------------------------------------------
# subrutina blank_response para comentarios en blanco
sub blank_response
{
print "Sus comentarios estan en blanco, de manera que no seran";
print " enviados a __________. Por favor vuelva a introducirlos o vuelva";
print " a la <A HREF=\"__________\">página inicial</A> si lo desea.<P>";
exit;
}

Este procedimiento se ejecutará cuando se introduzca unos comentarios en blanco, se indicará esto y se le permitirá volver a la página inicial o pulsando el boton de retorno a la página anterior introducir de nuevo el formulario.

Por tanto uniendo los trozos formaremos el programa que trataba el formulario anterior. Sobre este mismo programa se pueden introducir pequeñas modificaciones que permitan tratar practicamente cualquier tipo de formulario. Sí se desea que en vez de enviar un mail se genere un fichero donde se acumulen los comentarios, bastará cambiar la linea que ejecuta la instrucción open y cambiar el destino donde se realiza la salida.

Por ejemplo con cada comentario crearemos un fichero html en el que se irán acumulando en formato html los comentarios enviados, la forma de hacerlo será:

# Ahora enviamos la salida al fichero: /usr/local/etc/httpd/htdocs/dept/dept_img/datos/respuestas.htm
open (SALIDA, ">> /usr/local/etc/httpd/htdocs/dept/dept_img/datos/respuestas.htm") || die "No puedo abrir el fichero!\n";
print SALIDA "<hr>\n"
print SALIDA "<b>$FORM{'nombre'} $FORM{'apellidos'}</b> del <i>$FORM{'estamento'}</i> envio <br>\n";
print SALIDA "El siguiente comentario:<p>\n\n";
print SALIDA "<pre>\n"
print SALIDA "------------------------------------------------------------\n";
print SALIDA "$FORM{'comentar'}";
print SALIDA "\n------------------------------------------------------------\n";
print SALIDA "</pre>\n"
close (SALIDA);

En el nombre del fichero hay que indicar el camino completo a la raiz del servidor, que será /usr/local/etc/httpd/htdocs y luego el comienzo de la URL del departamento /dept/dept_img y por último el camino del fichero que se desea que acumule los datos /datos/respuestas.htm, el directorio donde se incluya este fichero debe ser escribible por el servidor de la WWW, por tanto bastará que tenga permiso para escribir en él el grupo wwwdept, que es al que pertenece su cuenta de departamento. El modo de darle los permisos adecuados desde el directorio superior será:

11:32 merlin> chmod 775 datos

Se puede cambiar de forma que el formato de salida sea todo lo vistoso que se desee, creando así por ejemplo un libro de firmas con comentarios.