CGI en WML

Autor: J. G. Castellano (fjgc@decsai.ugr.es)

1.- Cabecera de los scripts para generar páginas WML

Lo primero que debe hacer el script es informar del tipo de salida que va a dar como resultado (WML, WMLC, etc).

El tipo de documento se especifica en una línea del tipo:

     Content-type: tipo_MIME
donde tipo_MIME puede ser:

Tras esta linea, hay que enviar otra en blanco (dos retornos de carro). Por ejemplo, si se quiere devolver una página en WML, usando Perl:

     ....
     print "Content-type: text/vnd.wap.wml\n\n";
     ....
y usando C (aunque también funcionaría en Perl):
     ....
     printf ("Content-type: text/vnd.wap.wml\n\n");
     ....


2.- Datos de salida

Una vez especificada la cabecera, hay que proporcionar el documento acorde al tipo especificado como cabecera. Los datos se envian al browser simplemente sacándolos por salida estándar.

Por ejemplo, en Perl:

	

#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";

print<<"pagina_wap";

	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="Hola Mundo">
	<p>Hola mundo del wap</p>
	</card>
	</wml>

pagina_wap

	
y en C:
	
	#include <stdio.h>
	main ()
	{
		printf ("Content-type: text/vnd.wap.vml\n\n");
		printf ("<?xml version=""1.0""?>\n");
		printf ("<wml> \n");
		printf ("<card id="hw" title="Hola Mundo">\n");
		printf ("<p>Hola mundo del wap</p>\n");
		printf ("</card>");
		printf ("</wml>");
		printf ("");

		return 0;
	}
	
En este ejemplo crea un carta (card) con un párrafo que nos dice hola mundo.

Probar el ejemplo...

Es importante que los datos enviados al browser (sacados por salida estándar) sean compatibles con el formato especificado en la cabecera, es decir, si indicamos que vamos a generar un fichero WML, el browser interpretará correctamente los tags de WML que incluyamos.


3.- Consejos para evitar y resolver problemas

Cuando ejecutemos un CGI a través de un browser, si el CGI tiene algún error de programación, el error que obtendremos en el navegador será parecido a algunos de los siguientes:

	Errors/Warnings:
	-------------------------

	500   DNS Error.
O también:
	NO CARD IN THIS FILE
O también:
	Error 500: Server Internal Error
lo cual no es muy útil a la hora de detectar los errores o depurar el programa.

Es conveniente (que no obligatorio) hacer uso de sentencias print cortas y claras, terminándolas con retornos de carro, para que el código HTML generado sea claro y fácil de depurar.

De esta forma, y antes de probar un script a través del browser, lo que haremos será ejecutarlo desde la línea de órdenes (shell), con lo cual, si hay errores, nos saldrá la línea/s donde los hay, y si todo está bien, nos imprimirá el código HTML que formaría la página a visualizar.

Por otro lado, si el código generado es fácil de seguir, nos será más fácil después ver porqué los elementos y la información generada para visualizar en el browser cliente no aparece como deseamos (si es que aparece mal). En el siguiente ejemplo tenemos CGI mal hecho: Probar el ejemplo...


4.- Ejemplos

Hora actual

Se trata de un programa que al ser ejecutado muestra la hora actual:
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";
	
# parte activa del programa
($s,$m,$h, @resto) = localtime(time);
	
print<<"pagina_wap";

	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="La hora">
	<p>La hora actual es $h:$m:$s</p>
	</card>
	</wml>

pagina_wap

	
Probar el ejemplo...

Procesado de las variables de entorno

El siguiente ejemplo muestra como visualizar todas las variables de entorno que se le pasan a un CGI en el array asociativo %ENV al ser llamado.
	
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";

print<<"pagina_wap";
	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="Variables de Entorno">
pagina_wap

#Mostramos el número de argumentos
foreach $clave (keys(%ENV))
	{print "<p>$clave = $ENV{$clave} </p>\n";}

print<<"pagina_wap2";
	</card>
	</wml>
pagina_wap2
Probar el ejemplo...

Pasarle valores a los CGIs al llamarlos

Hay dos formas de conseguir esto: como argumentos de la misma forma que en la llamada a programas en Perl desde la línea de órdenes (metodo GET) o como ya se verá más adelante, con otro método más potente (POST).

El ejemplo que pondremos aqui simplemente es llamado y muestra los argumentos pasados, si ha habido alguno:

	
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";

#Impimo la cabecera de la pagina WML
print<<"pagina_wap";

        <?xml version="1.0"?>
        <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
        <wml>
        <card id="hw" title="Argumentos">
pagina_wap

#Usamos metodo get => cogemos los argumentos de la variable de entorno QUERY_STRING
$parametros=$ENV{"QUERY_STRING"};

#Si no hay parametros lo ponemos
print "<p>No se han pasado parametros a este CGI ...</p>" if ($parametros eq "")

# Obtengo las variables (divididas por &) y las imprimo
foreach (split(/&/,$parametros))
{    #Separo la variable y su valor asociado
    ($variable,$valor) = split(/=/, $_);
    #En las cadenas sustituyo el + por espacios
    $valor=~tr/+/ /;
    #Reformateo
    $valor=~s/%([0-9|A-F]{2})/pack(C,hex($1))/eg;

    #Imprimo el valor y la variable
    print "<p> $variable = $valor</p>\n"
}


#Imprimo la cola de la página WML
print<<"pagina_wap2";
        </card>
        </wml>

pagina_wap2		
	
	
Probar el ejemplo...


5.- Ejercicios

Hora y fecha actuales en formato WML

Ejercicio
Se trata ahora de hacer lo mismo que el primer ejemplo visto (el de la hora), sólo que ahora también pintaremos la fecha.

Probar el ejemplo...
Truco:Para los que no sepan Perl(o no se acuerden) para sacar la fecha y la hora, lo podeis hacer con:
	.....
	($segundos,$mes,$hora,$dia,$mes,$anio,@resto) = localtime(time);	
	anio+=1900; #Efecto 2000 en Perl
	.....

Contador de visitas

Ejercicio
Se trata de hacer un contador de accesos a una página WML que guarde en un fichero de texto la cuenta de accesos que se han hecho hasta la fecha, lea el contenido, lo incremente y vuelva a guardar la cuenta actualizada antes de "crear" página WML a mostrar en el móvil WAP.

Probar el contador...

Truco:Para los que no sepan Perl(o no se acuerden) para leer,incrementar y guardar el contador se hace con:
	.....

	# cargar la cuenta actual e incrementarla
	open(F, "cuenta.dat");
	$contador = <F>;
	close(F);

        #Incremento del contador
	$contador ++ ;
	
	# guardar la nueva cuenta
	open(F, ">cuenta.dat");
	print F "$contador";
	close(F);

	.....

Truco:Para que se pueda modificar el contador el fichero con el contador (contador.dat) debe tener derechos de lectura/escritura para todos los usuarios. En Unix, esto se hace con:
chmod 777 contador.dat
.

 
Grupo GeNeura. http://geneura.ugr.es
Departamento de Arquitectura y Tecnología de los Computadores.
Universidad de Granada