Unidad didáctica 4 Programación de aplicaciones Web 2.0 En esta última unidad didáctica del curso vamos a ver las aplicaciones Web 2.0 de un modo distinto de como lo llevamos haciendo hasta ahora: desde el punto de vista del programador. Actualmente y como hemos comprobado en anteriores capítulos, la Red está llena de portales y portales que hacen gala de todo tipo de funcionalidades avanzadas que se integran perfectamente con los usuarios y sus necesidades. Simplemente con el mero hecho de introducir nuestro nombre de usuario y contraseña, una experiencia totalmente personalizada da comienzo y todo el potencial de la web 2.0 casi mágicamente nos transporta a un mundo donde las aplicaciones hablan entre sí, comparten información y todo ello sin que nos demos prácticamente cuenta… ¿Cómo se consigue esto? Por medio de la programación, por supuesto. Youtube, Wikipedia, Facebook... todos estos portales sin excepción alguna han sido en algún momento un boceto en un papel y mucho antes una idea en la cabeza de algún inquieto programador que tras muchas horas de trabajo y análisis ha conseguido hacer realidad su sueño. Nosotros en esta unidad vamos a ver cómo podemos hacer nuestras propias aplicaciones web 2.0 basándonos en los conocimientos que hemos ido adquiriendo en este curso. Por medio de elementos como HTML, CSS, AJAX y otros que iremos viendo, finalmente seremos capaces de “crear” lo que nos pase por la mente en un momento dado. Al finalizar el estudio de estas lecciones serás capaz de: Conocer las técnicas y lenguajes de programación utilizados en la Web 2.0 Definir y diseñar una aplicación completa Optimizar el código y minimizar el tráfico generado Consumir servicios web y crear nuestra propia aplicación U.D. IV – Web 2.0 1 Capítulo 1 Páginas simples Para comenzar a entender la programación de las páginas web basadas en tecnologías 2.0 y que el resultado de dicha programación sea satisfactorio, debemos empezar por analizar una página HTML sencilla y comprobar el formato de la misma. Este primer estudio no en vano es uno de los más importantes porque al fin y al cabo, por compleja que sea la programación de las aplicaciones web 2.0 que se nos puedan ocurrir, el resultado de dicha programación tendrá siempre que ser una página HTML plana que un navegador de un ordenador, teléfono móvil o cualquier otro dispositivo compatible con este lenguaje sea capaz de interpretar. En la primera de las lecciones que comprenden este capítulo vamos a analizar los requerimientos o buenas prácticas que una página debe cumplir para que su código generado sea válido en función de los estándares definidos por el W3C, organismo encargado de regular la formación de código HTML en páginas de Internet. Si nuestro código es válido sabremos que vamos por el buen camino y podremos pasar al punto siguiente en la creación de una página simple: aplicar estilos a nuestro código, haciendo que la apariencia del resultado obtenido varíe hasta límites insospechados con el uso de las hojas de estilo CSS. Si el código de la página está bien formado y aplicamos un uso adecuado de las hojas de estilo, tendremos una página limpia, ligera y lo más importante, compatible con todos los navegadores, independientemente de la plataforma en la que se ejecuten. Al finalizar el estudio de estas lecciones serás capaz de: Analizar y validar una página HTML, corrigiendo los errores que aparezcan Aplicar diseño a la página generada por medio de hojas de estilo CSS U.D. IV – Web 2.0 2 Lección 1 HTML válido HTML válido es una etiqueta o galardón que es fácil de explicar, pero que conseguir que aparezca en una página es complicado si desde un principio no se tienen claras las reglas a seguir para que el código que aparece en nuestra página web las cumpla escrupulosamente. Para que una página contenga código HTML válido, necesariamente debe seguir todas las directrices que el W3C ha dispuesto para el tipo de documento seleccionado… Pero ¿qué es el W3C y qué es un tipo de documento? El World Wide Web Consortium (W3C) El W3C (World Wide Web Consortium) tal y como indica en su propia página web (http://www.w3c.com y http://www.w3c.es en su versión española), “desarrolla tecnologías inter-operativas (especificaciones, líneas maestras, software y herramientas) para guiar la Red a su potencialidad máxima a modo de foro de información, comercio, comunicación y conocimiento colectivo” 4.1.1_1 – Página web del W3C en su versión española U.D. IV – Web 2.0 3 Básicamente y en lenguaje coloquial, diríamos que el W3C es el organismo encargado de crear las guías y bases de trabajo para que la Red se desarrolle y digamos “vaya por el buen camino”, siempre y cuando todos los usuarios y en especial los programadores las respeten y cumplan en el desarrollo de sus proyectos web. 4.1.1_2 – Logotipo del W3C El W3C desde el comienzo de su andadura en 1994 ha propuesto más de 110 estándares y reglas los cuales se engloban en lo que se denominan Recomendaciones del W3C y que pueden consultarse en la dirección web http://www.w3.org/TR/. Dichos estándares y reglas no sólo se aplican a las páginas web y su código HTML, sino a multitud de aspectos relacionados con la web en general y que afectan a su funcionamiento del día a día. 4.1.1_3 – Página de Recomendaciones del W3C Asimismo el W3C hace la función de ser un foro abierto de discusión sobre las tecnologías relacionadas con la web y los diferentes estándares que proponen, llegando al consenso necesario entre todas las partes implicadas en tecnologías web para la formulación de dichos estándares. U.D. IV – Web 2.0 4 4.1.1_4 – Tim Berners-Lee, Director del W3C e inventor de la World Wide Web Para finalizar con nuestra introducción al W3C y darnos cuenta de su importancia, debemos reseñar que el director de dicha organización desde su fundación en 1994 es Tim Berners-Lee, que inventó la World Wide Web en 1989, mientras trabajaba en la Organización Europea de Investigación Nuclear (CERN), lo que nos hace a una idea de la importancia de la organización y de su función en el desarrollo de Internet. Tipos de Documento utilizados en HTML El W3C en su definición de estándares y reglas para el desarrollo de la web en Internet ha formulado diferentes versiones de documentos HTML que han ido evolucionando con el tiempo para adaptarse a las condiciones de los diferentes navegadores y sus características en función de los dispositivos en los que deben desempeñar su trabajo. Hay que pensar que desde 1994 la web ha dado pasos de gigante y con ella los diferentes ordenadores y dispositivos en los que se muestra, por lo que un formato perfectamente válido hace 10 años puede que actualmente no aproveche todas las capacidades de dispositivos más modernos y por tanto quede totalmente obsoleto en un mundo donde la innovación es la noticia de cada día. U.D. IV – Web 2.0 5 4.1.1_5 – El Lenguaje HTML y los tipos de documento estándar El tipo de documento es una directiva o encabezado que se coloca nada más comenzar un documento HTML. El tipo de documento que seleccionemos en este punto va a determinar qué elementos HTML podemos integrar en la página, la representación de los mismos en pantalla y el comportamiento que estos tendrán cuando el usuario interactué con ellos, así como los atributos que podremos definir sobre los mismos o modificar por medio del DOM en JavaScript. En el fragmento de código que podemos ver a continuación podemos encontrar la definición de tipo de documento, que en este caso se refiere al estándar del W3C “HTML 4.01” en su variante “Estricta” 4.1.1_6 – Definición de tipo de documento HTML 4.01 Estricta Como hemos comentado anteriormente, el lenguaje HTML tiene diferentes versiones que han ido evolucionando con el tiempo y las necesidades de los dispositivos y de los usuarios. Nosotros no vamos a detenernos en todas ellas, pero sí que es importante nombrar las más significativas, identificando sus características y particularidades. HTML 4.01 La especificación 4.01 de implementación del lenguaje HTML es la más reciente hasta la fecha y la única oficial hasta que aparezca el nuevo HTML 5, que todavía está en proceso experimental y que solamente unos pocos navegadores soportan en su totalidad. 4.1.1_7 – HTML 4.01 Dicha especificación nos indica el modo de utilizar los diferentes operadores y su funcionalidad, si bien dispone de tres variantes que utilizaremos en función del marco de trabajo que vayamos a utilizar: Versión Frameset: Esta versión se utilizará cuando nuestra página contenga Frames o marcos. Es una versión menos restrictiva en la que se pueden utilizar órdenes específicas para la creación y uso de dichos marcos que actualmente se encuentran en proceso de eliminación U.D. IV – Web 2.0 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> Versión Estricta (Strict): Esta versión es la más rígida del HTML 4.01 y en ella se bloquea el uso de ciertos atributos y elementos con la finalidad de extraer totalmente la capa de diseño de la de contenido y que el código generado no disponga de atributos de estilo que puedan convertirse en definiciones CSS <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> Versión Transicional (Transitional): Esta versión es la más utilizada en la vida real y combina la rigidez de la versión estricta con la posibilidad de introducir algunos parámetros de estilos y alineaciones directamente sobre los elementos HTML que se incluyan, permitiendo que la capa de diseño se entremezcle con el código, facilitando así la creación de código HTML en menor tiempo. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> ¿Cuál de las versiones es la más adecuada? Evidentemente, si conseguimos que nuestra página utilice la versión Estricta (y que el código se valide sobre la misma, claro), nuestra página estará mejor formada y será mucho más sencilla de mantener y portar a tantos sistemas como sea necesario, ya que nos aseguramos que la capa de diseño está totalmente separada de la información. No obstante esto muchas veces no es posible ya que en multitud de ocasiones debemos integrar elementos o fragmentos de códigos que no están preparados para una validación Estricta por necesidades ajenas a la programación y que nos harán cambiar la especificación a Transicional o Frameset para que nuestro documento pueda considerarse válido con todas las ventajas que ello conlleva. Si deseas obtener más información sobre la especificación HTML 4.01, puedes visitar el siguiente enlace de la web del W3C, donde se recoge la especificación completa del formato: http://www.w3.org/TR/1999/REChtml401-19991224 XHTML 1.0 La especificación XHTML 1.0 es una simple reformulación del HTML 4.01 hecha para preservar la compatibilidad con XML. De este modo se introducen ligeros cambios que hacen que el código formado bajo esta especificación sea totalmente compatible con los dispositivos que lo utilicen. U.D. IV – Web 2.0 7 4.1.1_7 – XML Al ser una reformulación del anterior HTML 4.01, disponemos de los mismos subtipos disponibles para su uso, con las mismas definiciones y aplicaciones que hemos comentado anteriormente. A continuación indicaremos las diferentes definiciones de documento para XHTML 1.0 XHTML 1.0 Frameset <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> XHTML 1.0 Strict <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> XHTML 1.0 Transitional <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> No obstante, a pesar de las aparentes similitudes en tipo de documento, aparecerán algunas restricciones o particularidades al formato del código generado. Vamos a comentar alguna de las más representativas: 9 Los elementos deben cerrarse siempre Anteriormente, cuando colocábamos elementos como imágenes o saltos de línea, no era necesario colocar la etiqueta de cierre de elemento, de este modo, era perfectamente válido un código como el que aparece a continuación: U.D. IV – Web 2.0 8 4.1.1_9 – Código no válido en XHTML El código que aquí aparece no sería validado correctamente por la herramienta que nos proporciona el W3C y que veremos más adelante ya que tiene dos elementos que no están cerrados correctamente, el elemento <br> y el elemento <img>. Para solucionar este problema deberíamos cerrar dichos elementos bien colocando el correspondiente elemento de cierre tras la apertura del mismo o incorporando una barra “/” al final del elemento. De este modo quedarían como aparece a continuación: • • <br></br> o <br/> <img src="images/logo.gif"></img> o <img src="images/logo.gif"/> 9 Los nombres de los elementos deben ir en minúsculas y los atributos entrecomillados De este modo el elemento <P> no sería válido y del mismo modo la definición <table border=0> tampoco estaría permitida según el estándar. Los elementos correctos serían <p> y <table border=”0”> 9 Las anidaciones de los elementos deben realizarse correctamente Es decir, no podríamos colocar fragmentos del tipo <a href=”#”><b>Enlace</a></b>, ya que estaríamos entremezclando los identificadores. La versión correcta en XHTML sería la siguiente: <a href=”#”><b>Enlace</b></a>. Si deseas obtener más información sobre la especificación XHTML 1.0, puedes visitar el siguiente enlace de la web del W3C, donde se recoge la especificación completa del formato: http://www.w3.org/TR/2002/RECxhtml1-20020801 Formatos anteriores: HTML 3.2 y HTML 2.0 Para finalizar con las definiciones de tipos de documento, debemos hacer una leve mención a dos formatos que ahora mismo están en desuso, pero que nos servirán para que nos hagamos a una idea del cambio que han supuesto los últimos años en la World Wide Web. U.D. IV – Web 2.0 9 El HTML 3.2 es la versión anterior al HTML 4.01 que hemos visto anteriormente y está soportada por la práctica totalidad de navegadores, pero no implementa la funcionalidad de marcos y no maneja adecuadamente la información de estilos. El HTML 2.0 es una versión más anticuada, y como tal carece de la implementación de marcos, tablas e internacionalización, pero tiene la curiosidad de que permitía la creación de elementos propios para su uso en la web, de modo que el elemento <miParrafo> sería totalmente correcto a efectos de validación de formato. Por qué debemos escribir HTML válido Cuando escribimos un código HTML validado correctamente, aunque parezca que la página se muestre del mismo modo que con algunos errores de validación, nos estamos asegurando de que no vamos a tener problemas derivados del mal uso del modelo de objetos (DOM) cuando procesemos nuestra página como una aplicación Web 2.0 4.1.1_10 – XHTML válido Esto tiene una explicación muy sencilla: cuando el navegador procesa nuestra página web, crea un modelo de datos en función de cómo la hemos definido a nivel de código, de modo que si dicho código es coherente y está bien formado, la estructura que dicho navegador tenga en su memoria también lo será. Si por el contrario nuestro código tiene elementos sin cerrar o anidaciones mal formadas (por poner algún ejemplo), cuando vayamos a utilizar JavaScript para incluir contenidos dinámicos o procesar respuestas del usuario nos llevaremos más de una sorpresa desagradable. Otro punto a valorar es que si nuestro código está validado correctamente, nos aseguramos de que el comportamiento de dicha página va a ser el mismo en todos los navegadores que soporten dichos formatos, lo que es extremadamente importante cuando vayamos a ejecutar nuestra aplicación en otros dispositivos diferentes al que ha sido creada. U.D. IV – Web 2.0 10 El siguiente código HTML no está formado correctamente: <html> <head> <title>Prueba de validación</title> </head> <body><table cellpadding="2" cellspacing="2" border="1"> <tr> <td> Web: </td> <a href="http://www.heraldo.es"> <td> Heraldo de Aragón </td> </a> </tr> </table> </html> Si te fijas, verás que el elemento de Hiperenlace (a) no está correctamente introducido, ya que debería estar colocado dentro de la celda de la tabla y no contener una de ellas tal y como aparece aquí. Este pequeño error hace que en Internet Explorer 8 el enlace funcione, pero que no aparezca marcado como enlace. En el resto de exploradores ni se marca como enlace ni funciona… Errores como el del ejemplo que acabamos de ver pueden darnos muchos problemas sobre todo si no los localizamos pronto. Las aplicaciones Web 2.0 suelen ser bastante complejas cuando llegamos a niveles de funcionalidad avanzados y un error fácilmente detectable como la validación de documento puede darnos más de un quebradero de cabeza… Cómo saber si una página es válida Con el fin de promover y facilitar la tarea de adaptación a sus estándares, el W3C pone a nuestra disposición una herramienta con la que podemos validar nuestro código HTML de un modo fácil y rápido, informándonos además de los errores que en él encuentre para que podamos corregirlo en consecuencia. El validador podemos encontrarlo en la dirección http://validator.w3.org/ y su modo de funcionamiento es realmente sencillo: basta con indicarle la URL de una página web, subir un archivo HTML o copiar y pegar un fragmento de código para saber al instante si dicho documento es válido o no. U.D. IV – Web 2.0 11 4.1.1_11 – Herramienta de validación de código HTML del W3C Si utilizamos la opción de validación por URL o subiendo un archivo, no tendremos que seleccionar más opciones, ya que detectará el tipo de documento y la codificación de caracteres del mismo. Si por el contrario optamos por copiar y pegar un fragmento de código HTML, tendremos que indicarle estos valores manualmente para que determine las reglas que debe comprobar y de los errores que debe informarnos. 4.1.1_12 – Intento de validación de un fragmento de código HTML U.D. IV – Web 2.0 12 Una vez ejecutado, el validador nos devolverá el resultado de la prueba, así como los errores de formato o avisos que considere necesarios para la corrección del documento o fragmento de código introducido. Si el documento ha validado correctamente, nos lo indicará con un mensaje y nos invitará a que coloquemos en nuestra página una etiqueta que informe de dicha condición al pie de la misma. 4.1.1_13 – Validación correcta de un documento en HTML 4.01 Estricto Abre una ventana con el validador del W3C e intenta validar el siguiente código. Localiza los errores que contiene con la ayuda del validador y consigue que el código sea considerado válido. Ignora los avisos si es necesario. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>Prueba de validación</title> </head> <body> <table cellpadding="2" cellspacing="2" border="1"> <tr> <td> Web: </td> <a href="http://www.heraldo.es"> <td> Heraldo de Aragón </td> </a> </tr> </table> </body> </html> U.D. IV – Web 2.0 13 Lección 2 Hojas de Estilo CSS Si en la anterior lección hemos hablado acerca de cómo debe estar formada una página (o más bien el código de la misma) para que sea adecuada y compatible con todos los navegadores, independientemente de la plataforma en la que se ejecuten, en esta vamos a tratar un tema no menos importante: cómo se presentan dichas páginas al usuario. Antiguamente las páginas HTML llevaban incorporada la información relativa al estilo de los elementos que contienen directamente incluida en el mismo código. De este modo era relativamente fácil ver fragmentos de código tal y como aparecen a continuación. <img src=”images/icono.gif” align=”center” hspace=”10” vspace=”15”> En este pequeño fragmento de código vemos un ejemplo de cómo el HTML permite la introducción de elementos de estilo “en línea”, es decir, a la vez que definimos el elemento que se va a mostrar. La imagen que se mostraría se alinearía al centro del párrafo en el que se encontrara, tendría un margen horizontal a ambos lados de 10 píxeles y uno vertical de 15 arriba y abajo. Esto que en principio podría resultar “cómodo” de definir (que luego veremos que no es tanto), no hace más que perjudicar el código y el rendimiento de nuestra aplicación ya que nos va a ocasionar dos problemas: 9 Aumenta el tiempo de carga de la página incluyendo información de estilo en la capa que debería contener sólo información 9 Hace que dicha información no sea repetible: Si más adelante colocamos otro elemento que tiene que disponerse del mismo modo, tendremos que repetir los mismos atributos para que aparezca posicionado del mismo modo. Para resolver esto y hacer nuestro código más manejable, separando el diseño de la programación, podemos hacer uso de las hojas de estilo CSS, pero ¿Que es una Hoja de Estilo CSS y cómo puede ayudar a mejorar el diseño de mi página web? Para obtener la definición formal de las hojas de estilo CSS, la mejor referencia que podemos obtener es la de los creadores de dicha tecnología, una vez más el W3C, que en su guía breve de CSS define a las hojas de estilo en su guía breve de CSS (http://www.w3c.es/divulgacion/guiasbreves/HojasEstilo) del siguiente modo: U.D. IV – Web 2.0 14 Hojas de Estilo en Cascada (Cascading Style Sheets), es un mecanismo simple que describe cómo se va a mostrar un documento en la pantalla, o cómo se va a imprimir, o incluso cómo va a ser pronunciada la información presente en ese documento a través de un dispositivo de lectura. Esta forma de descripción de estilos ofrece a los desarrolladores el control total sobre estilo y formato de sus documentos Es decir, nos las define como un elemento que nos permite modificar el comportamiento de la capa de diseño de una página web cuando se reproduzca en diferentes medios tales como la pantalla, la impresora o incluso lectores de texto. 4.1.2_1 – Guía breve de CSS del W3C De un modo menos formal, diríamos que las Hojas de Estilo CSS son unos documentos que contienen reglas y definiciones de estilo, de tal modo que cuando se combinan con los elementos que contienen una página web nos van a permitir modificar el aspecto de los mismos (tamaño, colores, subrayado...) sin tener que incluir atributos específicos de estilo dentro del documento principal. Por medio de la aplicación de esta tecnología conseguiremos salvar los dos problemas que hemos definido anteriormente, ya que "aligeraremos" el código fuente, que no tendrá que contener elementos de estilo y podremos dar un nombre a cada estilo que generemos, de modo que repetir el comportamiento visual de un elemento que se encuentre dentro de una página web va a ser tan sencillo como U.D. IV – Web 2.0 15 aplicarle el mismo nombre de estilo para que lo tome como referencia a la hora de mostrarse en pantalla, impresora o pronunciarse en un convertidor texto-voz. Cómo funciona una Hoja de estilo CSS Como hemos comentado anteriormente, las Hojas de Estilo CSS están formadas por reglas o declaraciones de estilo que se aplican a uno o más elementos contenidos en una página HTML. En una misma hoja podemos combinar varias reglas de modo que definamos el color de fondo de la pantalla, el tamaño y grosor de nuestros encabezados, los bordes y alineaciones de las imágenes contenidas en el documento, etc. Para definir correctamente una regla, debemos conocer las partes que contiene y el comportamiento que tiene cada una. Una regla de estilo CSS se compone siempre de un selector y una declaración. El selector va a indicar a qué elemento o elementos del código HTML se va a aplicar el estilo; por otro lado, la declaración va a contener las órdenes concretas que se van a aplicar a ese o esos elementos que hemos seleccionado por medio de dicho selector. En una regla de estilo que pretenda colorear en rojo y aplicar tamaño 14 a los encabezados de tipo 1 de una página HTML, el selector sería "H1" y las declaraciones "color: red" y "font-size: 14px" A la hora de escribir la regla de estilo completa, debemos tener claro a qué elementos se va a aplicar y qué estilo se les va a asociar. Una vez que tengamos definido este punto, pasaremos a escribir la regla del siguiente modo: SELECTOR {DECLARACION; DECLARACION; DECLARACION} De este modo podemos colocar para un mismo selector varias declaraciones de estilo separadas por punto y coma ";", permitiéndolos, por ejemplo aplicar un color rojo, letra negrita, tamaño 14 y subrayado en la misma regla de estilo. Las reglas de estilo nos permiten además incluir en un mismo selector varios elementos de HTML, por lo que las posibilidades que podemos llegar a tener en conjunto pueden ser innumerables La regla de estilo necesaria para colocar los Encabezados de tipo 1 y Encabezados de tipo 2 en color rojo, letra negrita, tamaño 14 y subrayado, se definiría tal y como aparece a continuación: H1, H2 {color:red; font-weight: decoration: underline;} U.D. IV – Web 2.0 bold; font-size: 14px; text- 16 Disposición de reglas de estilos en una página web Llegados a este punto, ya sabemos cómo crear reglas de estilo sencillas que cambien radicalmente el aspecto de nuestra página, pero ¿Cómo debemos incluir o asociar dichas reglas a nuestra página para que hagan lo que están destinadas a hacer? Actualmente disponemos de tres posibilidades a la hora de aplicar estilos a una página HTML. Cada una de estas tiene sus ventajas e inconvenientes que pasaremos a definir a continuación. En cualquier caso, siempre es recomendable utilizar la primera de ellas, que digamos que es la más "correcta", pero muchas veces y por necesidades del guión, deberemos hacer el uso de las otras técnicas, menos adecuadas, pero también funcionales al 100%. Incrustación de estilos como Hoja de Estilos CSS externa Es el método recomendado y el más eficiente que existe, si bien para llevarlo a cabo deberemos tener permisos para crear un archivo externo a la página en el que ubicaremos las reglas de estilo que deban aplicarse a la página en cuestión. Una vez que tengamos todas las reglas de estilo ubicadas en el mismo archivo, deberemos guardarlo en una ubicación de nuestro servidor web y colocar una reseña en nuestra página para indicar al navegador dónde se encuentran los archivos que debe aplicar para dar por finalizada la capa de presentación. <link href="estilos.css" rel="stylesheet" type="text/css" /> Este método, como hemos comentado, tiene el inconveniente de que necesitaremos permisos para ubicar un archivo adicional dentro del servidor que aloje la página o aplicación web que vamos a "estilizar", y aunque parezca raro, esto es bastante común dependiendo de los niveles de acceso que tengamos sobre dicho hosting. Si tenemos la suerte de poder incluir archivos en el servidor, este método está lleno de ventajas, ya que los estilos se ubican en un archivo externo que tan sólo debe descargarse una vez y esto permite mejorar las tasas de transferencia cuando varias páginas comparten una misma hoja de estilo como veremos más adelante. Incrustación de reglas de estilo en el documento HTML Este segundo método, si bien no es el más adecuado ni "limpio", nos permite seguir con la separación de capas de diseño e información, pero dentro del mismo archivo, con las mismas ventajas de aplicación que hemos visto anteriormente: podríamos repetir estilos y optimizaríamos, aunque en menor medida, el ancho de banda utilizado por la aplicación. Para incluir estilos de este modo basta con que coloquemos nuestras definiciones de estilo dentro de los elementos <style> y </style>.Una vez dentro de los mismos, el tratamiento de su contenido va a ser el mismo que si se ubicara en una hoja de estilos externa, pero se cargará en cada una de las recargas de nuestra página desde el servidor. U.D. IV – Web 2.0 17 Estilos en línea del contenido HTML El último método de incrustación de estilos CSS es además del último posible, el menos adecuado técnicamente, ya que es muy similar al modo en el que se aplicaban los estilos anteriormente, pero en lugar de aplicar dichos estilos por medio de atributos específicos (align, hspace…) lo hace por medio de declaraciones CSS válidas. Para aplicar nuestra información de estilos a un elemento por medio de este método, tan sólo deberemos aplicar el atributo “style” al elemento al que queremos dar forma, seguido de las declaraciones necesarias del mismo modo que lo haríamos en una definición en hoja de estilos externa. Si ejecutamos este código en un navegador web, formateará el elemento Encabezado de tipo 1 del mismo modo que si obtuviera dichos valores desde una hoja de estilos externa: <h1 style=”color:red; font-weight: bold; font-size: 14px; textdecoration: underline;”>Hola mundo</h1> Declaraciones de estilo más utilizadas Tras ver cómo podemos ubicar los estilos CSS y cómo debemos formularlos para que se apliquen correctamente, es necesario hacer una breve visita a las definiciones más comunes y su significado. Si las comprendemos, junto con el uso de los selectores adecuados no nos será muy difícil aplicar estilos a una página y hacer que de este modo tome una apariencia distinta a como lo hace habitualmente. En la tabla que aparece a continuación se recogen las declaraciones más comunes, así como su significado. U.D. IV – Web 2.0 18 Declaración Significado Ejemplo Margin En una caja, margen que se dispondrá en cada uno de los lados de la misma margin: 10px; Border Estilo, anchura y color del borde de una caja en cada uno de sus lados border: solid 1px red; Display Comportamiento del contenedor (visibilidad) display: none; Width Anchura del contenedor width: 100px; Height Altura del contenedor height: 50px; Color Color del texto contenido en el elemento color: blue; backgroundcolor Color de fondo del elemento background-color: yellow; backgroundimage Imagen de fondo del elemento background-image: url(‘imágenes/fondo.jpg’); font-family Especifica la tipografía a utilizar en el texto del contenedor font-family: Verdana; font-size Indica el tamaño que debe tomar la fuente contenida en el elemento definido en el selector font-size: 10px; font-weight Especifica el grosor de la fuente (negrita) font-weight: bold; text-align Alineación del texto dentro del contenedor text-align: right; textdecoration Atributos adicionales de texto que se deben aplicar text-decoration: underline; Cursor Formato del puntero del ratón al pasar por encima del elemento cursor: pointer; U.D. IV – Web 2.0 19 Toma este fragmento de HTML en el que se han definido algunos estilos en línea sobre los elementos que aparecen y conviértelos para que toda la información de estilos se encuentre entre los elementos <style> y </style> definidos. Si lo haces correctamente el código resultante debería quedar totalmente limpio de información de estilos: <style> a {text-decoration; none; font-size: 10px; font-weight: normal;} p {font-size: 12px;} </style> <p style="text-align: center; color: black; text-decoration: none"> <a href="http://www.heraldo.es"> Enlace a <b style="color: blue; font-size: 14px;">página externa</b> </a> </p> Selectores de estilo avanzados Si has completado el ejercicio anterior, te habrás dado cuenta que al utilizar los estilos CSS, el código HTML queda extremadamente limpio y que se hace muy fácil de entender, pero ¿qué pasa si en el ejemplo anterior introducimos un nuevo párrafo y queremos que su tamaño de letra o color cambie con respecto al primero? Con los conocimientos adquiridos en el curso, la única opción sería deshacer la conversión de etiquetas en línea con el contenido en reglas CSS y volver a colocarlas tal y como aparecían al principio. Al hacer este gesto, los estilos no se aplicarían a todos los elementos <a>, <p> y <b>, sino solamente a aquellos que llevaran indicadas específicamente las reglas de estilo como atributo directo. Esta solución, como sabrás, no es la más adecuada, ya que no nos permite utilizar el potencial de las hojas de estilo CSS, que es reducir el ancho de banda utilizado y hacer que dichos estilos puedan aplicarse a los elementos que nos interesen de un modo selectivo. Para resolver este entuerto vamos a explicar lo que denominaríamos “selectores avanzados de CSS”, selectores un poco más complejos que un simple “p“ o “b” y que nos permitirán seleccionar aquellos elementos que cumplan solamente las condiciones que determinemos para recibir el estilo en cuestión. Un elemento HTML como puede ser <p>, puede recibir varios atributos que se incluirán según el esquema ‘nombre=”valor”’. Esto nos permite asignarle un par de atributos muy preciados para aplicar estilos: el atributo “id” y el atributo “class” Cuando el elemento <p> se formula de este modo: <p class=”colorRojo”>, podemos utilizar un modo de selector que hará que dicho estilo se aplique solamente a los párrafos o elementos que tengan dicha propiedad. De este modo, si U.D. IV – Web 2.0 20 definimos la regla CSS “p.colorRojo {color: red;}”, todos los párrafos con el valor “colorRojo” en su atributo class tomarán el estilo definido. Esto es especialmente interesante cuando son varios los elementos que deben tomar el estilo. Si queremos reutilizar dicho estilo para enlaces y negritas, bastaría con eliminar el fragmento “p” del selector y automáticamente cualquier tipo de operador HTML que tenga “colorRojo” como valor en el atributo class lo heredará directamente. La regla entonces quedaría del siguiente modo: .colorRojo {color: red;} Del mismo modo podemos utilizar el atributo “id” para aplicar estilos, si bien en este caso, a diferencia del “class”, cada “id” debería ser único, por lo que la lógica de utilización sería totalmente a la inversa. Utilizaríamos “id” para aislar un elemento concreto que tiene que tomar el estilo en cuestión. Por ejemplo al formular <p id=”primerParrafo”>, podríamos definir el selector p#primerParrafo y su información de estilos sólo se aplicaría al párrafo con la id “primerParrafo”. Del mismo modo que en el caso anterior, podemos eliminar la información del elemento y de este modo conseguir un selector que se aplique al elemento cuya id sea “primerParrafo”, independientemente del elemento del que se trate. A continuación se muestra un fragmento de HTML en el que puede verse el uso de los selectores para aplicar estilos por medio del atributo “id” al primero de los párrafos que aparecen, y como por medio del atributo “class” aplicamos color rojo a otros dos párrafos y a un enlace contenido en el primero de los párrafos. <style> #primerParrafo {text-decoration; none; font-size: 10px; font-weight: normal;} .colorRojo {font-size: 12px;} </style> <p id="primerParrafo"> Contenido del primer párrafo con un <a href="http://www.heraldo.es" class="colorRojo"> enlace en color rojo </a> </p> <p class="colorRojo"> Contenido de otro párrafo en color Rojo </p> <p class="colorRojo"> Contenido de otro párrafo más en color Rojo </p> Una gran ventaja de las hojas de estilo: El ancho de banda Si utilizamos hojas de estilo CSS y lo hacemos correctamente (ubicando los estilos correspondientes en una hoja externa), inconscientemente vamos a conseguir una mejora abismal en la velocidad de carga de las páginas que soporten esta tecnología. ¿Cómo es posible esto? U.D. IV – Web 2.0 21 ¿Recuerdas el ejercicio en el que hemos extraído los estilos de los elementos que los incorporaban directamente en línea? Si los has extraído correctamente habrás obtenido algo parecido al fragmento que aparece a continuación: <style> a {text-decoration; none; font-size: 10px; font-weight: normal;} p {font-size: 12px; text-align: center; color: black; text-decoration: none} b {color: blue; font-size: 14px;} </style> <p> <a href="http://www.heraldo.es"> Enlace a <b>página externa</b> </a> </p> Como ves, la información relativa a estilos ocupa más de la mitad del contenido total de la página completa. Imagina ahora que extraemos estas reglas de estilo a una hoja externa. La página nos quedaría entonces así: <link href="estilos.css" rel="stylesheet" type="text/css" /> <p> <a href="http://www.heraldo.es"> Enlace a <b>página externa</b> </a> </p> Básicamente el contenido va a estar mucho más limpio de este modo, pero ¿Dónde está la ventaja en sí? Al fin y al cabo a pesar de estar en una hoja externa, los estilos tienen que ser descargados por el navegador, ¿no? La ventaja que comentamos realmente es considerada como tal cuando concentramos los estilos de varias páginas HTML (nuestra aplicación, un portal, etc.) en una misma hoja. El navegador descargará la información de estilos una única vez y después irá solicitando las páginas a medida que las necesite, pero sin descargar de nuevo la información de estilos, ahorrando mucho ancho de banda cuando el número de páginas procesadas aumente. U.D. IV – Web 2.0 22 Imagina que la página inicial pesaba 10KB y al extraer estilos hemos generado una hoja de estilos CSS de 5KB, dejando nuestra página web en 5KB. La primera vez que la solicitemos nuestro explorador descargará 10KB, pero la segunda vez con 5KB tendrá bastante, ahorrando los otros 5KB de estilos que ya ha descargado. Si se tratase de una página de noticias o mensajes que consultásemos cada minuto, a lo largo de 8 horas al día, nos ahorraríamos un total de 8 Horas x 60 minutos x 5KB por petición = 2.400KB Esto tampoco es mucho con las conexiones que tenemos hoy en día, pero si esta página de noticias es de un diario que tiene 1.000 usuarios suscritos, la cosa cambiaría bastante. Con el simple gesto de extraer los estilos de su página a una hoja de estilos CSS se estarían ahorrando 2,4GB diarios, que seguro que la empresa agradece a la hora de pagar su factura de alojamiento Web a fin de mes… Otra gran ventaja: La versatilidad de CSS Zen Garden Además de la gran ventaja del ahorro de ancho de banda que supone el correcto uso de las hojas de estilo, el hecho de que los estilos estén aislados en un documento externo nos permite un gran margen de maniobra sobre los mismos. Imagina por un momento que creamos una revolucionaria aplicación para la gestión de las compras de una empresa. Si hemos extraído previamente los estilos a una o varias hojas CSS externas, sería relativamente sencillo crear una nueva versión de la aplicación para un nuevo cliente. Modificando la hoja de estilo deberíamos ser capaces de variar completamente la capa de diseño, ofreciendo una aplicación que con el cambio de un simple archivo podría parecer otra totalmente distinta o adaptada a un entorno que no tendría nada que ver con el que inicialmente estaba pensado. Un vivo ejemplo de esto es CSS Zen Garden (http://www.csszengarden.com). CSS Zen Garden nace como un reto para los diseñadores en un recurso que muestra el verdadero potencial de las hojas de estilo CSS. Con el mismo código HTML, pero con el cambio de un archivo CSS, el portal toma una apariencia totalmente distinta. U.D. IV – Web 2.0 23 U.D. IV – Web 2.0 24 4.1.2_2, 4.1.2_3, 4.1.2_4 y 4.1.2_5 – Ejemplos de CSS Zen Garden U.D. IV – Web 2.0 25 Las imágenes que has visto están todas formadas con el mismo código HTML, pero variando solamente la hoja de estilo adjunta al mismo. Como puedes ver, las posibilidades son infinitas. Te animamos a que visites la web y que pinchando en los enlaces descubras diferentes versiones del portal para que descubras todo el potencial de las hojas de estilo con tus propios ojos. ¡Que no te engañen! Visita CSS Zen Garden y comprueba que el código de las diferentes versiones de las páginas que se muestran es el mismo. Sobre cada una de las versiones, haz click con el botón derecho del ratón y selecciona “Ver código fuente” (varía ligeramente en función del navegador). Compara el código de diferentes versiones de la misma página y juzga el resultado. U.D. IV – Web 2.0 26 Capítulo 2 XHTML En el capítulo anterior hemos visto las ventajas de que nuestra página estuviera dotada de un código HTML válido por medio del uso de las indicaciones creadas a tal efecto por el W3C. Estas recomendaciones y la condición de la validación del código van a convertirse en un requerimiento en nuestras aplicaciones Web 2.0 Como ya comentamos en el anterior capítulo, para manipular el HTML de nuestras páginas utilizaremos el modelo de objetos del documento (DOM) y técnicas de JavaScript que nos permitirán añadir funcionalidades y cambios según la interacción del usuario con las respuestas del servidor. Pues bien, para que dichas manipulaciones se realicen con éxito deberemos utilizar un código HTML bien formado y a ser posible que sea compatible con XML, que será el lenguaje con el que nos comunicaremos con el servidor para recibir o enviar datos de nuestra aplicación. Para esto qué mejor manera que utilizar la versión compatible con XML del HTML 4.01, esto es, el estándar XHTML 1.0, que cumplirá nuestras necesidades a la perfección. En la primera de las lecciones veremos ejemplos reales y casos de uso con las particularidades de este estándar para después adentrarnos en el modelo de objetos del documento y plantearnos posibles casos de manipulación de los contenidos. Para finalizar, volveremos de nuevo a las hojas de estilo en cascada CSS para ver ejemplos adicionales y funcionalidades aun más avanzadas que nos permitirán afinar la capa de diseño para cubrir las necesidades que nos imponga nuestra aplicación. Al finalizar el estudio de estas lecciones serás capaz de: 9 Utilizar el lenguaje XHTML para crear páginas complejas 9 Entender el Modelo de Objetos de Documento de XHTML 9 Utilizar estilos CSS avanzados para afinar y optimizar el documento U.D. IV – Web 2.0 27 Lección 1 Características del XHTML Como hemos visto en anteriores lecciones, podemos decir que la especificación XHTML 1.0 (recomendación del 26 de enero del 2000) es una reformulación del HTML 4.01 como aplicación XML, exactamente es la reformulación de las tres definiciones de tipo de documento HTML 4.01 (transicional, frameset y estricta) como aplicaciones XML. La finalidad de esta reformulación no es otra más que preservar la compatibilidad con dispositivos, adaptando el código a la especificación XML. Además de esta ventaja, si se siguen las especificaciones dadas para la conversión de HTML a XHTML, el código resultante podrá ser interpretado por navegadores antiguos sin mayor problema. 4.2.1_1 - XHTML Vamos de todos modos a hacer un repaso de algunas características y/o mejoras de este lenguaje que hemos visto anteriormente junto con algunas nuevas que cabe reseñar: 9 Los documentos XHTML son compatibles con XML, por lo que podemos visualizarlos, editarlos y validarlos con las mismas herramientas que utilizaríamos para trabajar con XML estándar. U.D. IV – Web 2.0 28 9 Los documentos escritos en XHTML, al ser compatible con HTML permitirán que sean visualizados y tratados sin problemas en navegadores y dispositivos preparados para visualizar HTML. 9 Los documentos XHTML pueden usar y ser utilizados por aplicaciones (nuestra gran ventaja) ya que están basados en el modelo de objetos de documento (DOM) de HTML y XML 9 A medida que se vayan produciendo nuevas especificaciones de formatos en la web, los documentos creados en XHTML serán más fáciles de migrar y adaptar a los nuevos formatos que aparezcan. 9 Con el paso del tiempo, los desarrolladores de agentes de usuario y documentos descubren nuevas etiquetas que utilizar en la creación del código (esto se da sobre todo en XML). Como XHTML está preparado y montado sobre la base de XML, crear nuevas etiquetas que sigan los estándares para estos tipos de documento es relativamente sencillo. Como vemos, cada día nuevos dispositivos tienen acceso a la red para visualizar e interaccionar con los contenidos que en ella aparecen. El uso del XHTML va a hacer esta tarea más fácil, ya que si dichos dispositivos son compatibles con XHTML y la comunidad lo utiliza como estándar, podremos aprovechar esta ventaja para optimizar nuestros desarrollos e incluso el hardware hacia esta dirección, incorporando mejoras específicas aprovechables por todas las plataformas. Queda claro con estas características que el XHTML es el nuevo estándar de la web y que desde hace ya algunos años es el más utilizado por desarrolladores de contenidos en sus documentos. Además de esto, al tener total compatibilidad con XML, podemos obtener todos los beneficios derivados del uso del lenguaje, a la vez que aseguramos la compatibilidad con agentes de los usuarios pasados y futuros Definición de Documento y plantilla En esta sección vamos a definir la estructura del documento XHTML que utilizaremos posteriormente para realizar pruebas sobre el mismo. Este punto es especialmente importante porque va a sentar las bases de todas las páginas de las que se componga nuestra aplicación, de modo que es necesario seguirlo con atención. El primer elemento que ubicaremos en la estructura de un archivo XHTML es la definición de documento en la que vamos a ubicar el contenido. Si recuerdas, XHTML nos permite definir 3 tipos de versiones de documentos: estricta, transicional y frameset. En nuestro lugar vamos a colocar la definición estricta, que debería ser el punto de partida de todos los documentos. Si más tarde vemos que tenemos que integrar fragmentos de código que no podemos validar ni convertir, pasaríamos a una de las versiones menos restrictivas... <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd "> Una vez que hayamos ubicado la definición de documento, pasaremos a definir la cabecera y el contenido, que estarán ubicados dentro de la etiqueta <html> y </html>, que consideraremos como elemento raíz de la página. En esta etiqueta, además deberemos definir el lenguaje que estamos usando y que en efecto, el tipo U.D. IV – Web 2.0 29 de documento utilizado es XHTML. Esto lo haremos por medio de la ubicación de los siguientes atributos en la etiqueta de apertura: <html xmlns="http://www.w3.org/1999/xhtml\" xml:lang="es" lang="es"> El siguiente elemento que tenemos que ubicar en nuestra página XHTML y dentro del elemento raíz sería la cabecera del documento, que vendría delimitada por las etiquetas <head> y </head>. En este caso no tenemos que definir ningún atributo dentro de las etiquetas, pero sí deberíamos incluir al menos el título de la página para que el navegador que la procese y el usuario sepan qué les vamos a enseñar. Una vez introducido nos quedaría del siguiente modo: <head> <title>Título de la página</title> </head> Dentro del elemento <head> es recomendable incluir información acerca de la codificación del documento, así como metainformación sobre la descripción de la página o las palabras clave que contiene. En nuestro caso sólo incluiremos la etiqueta de codificación, que sería como la que aparece a continuación para el caso de UTF-8, el más extendido: <meta http-equiv ="Content-Type" content="text/html;charset=utf-8" /> Llegados a este punto, deberíamos ubicar el elemento que nos va a delimitar el contenido del documento en sí, el cuerpo. Dicho elemento se define con las etiquetas <body> y </body> y se colocaría justo después del cierre de la cabecera. Dentro de él colocaremos todo el contenido de la página tal y como iremos viendo a lo largo de este capítulo. Recopilando todo lo que hemos ido viendo hasta ahora, podríamos crear una plantilla de documento XHTML que quedaría como aparece a continuación: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd "> <html xmlns="http://www.w3.org/1999/xhtml\" xml:lang="es" lang="es"> <head> <meta http-equiv ="Content-Type" content="text/html;charset=utf-8" /> <title>Título de la página</title> </head> <body> Contenido de la página </body> </html> Como ejercicio puedes escribirla en un editor de textos y guardarla como el archivo "plantilla.html". Posteriormente la podrás utilizar para probar los ejemplos que vayan apareciendo en esta lección. U.D. IV – Web 2.0 30 Elementos y uso de los mismos en el documento A lo largo de esta sección vamos a estudiar los diferentes elementos que componen la especificación de XHTML (bueno, más bien algunos de ellos) y el comportamiento que tienen cuando se visualizan dentro de nuestra página web. Párrafos Los párrafos sirven para estructurar el contenido tal y como lo haríamos en un libro o una carta. Para crear un párrafo, introduciremos texto dentro de las etiquetas <p> y </p> <p>Esto es un ejemplo de un párrafo que aparecería dentro de nuestra página web. El navegador automáticamente va a darle un margen superior e inferior para separarlo de los contenidos adyacentes</p> Atributos de texto Colocar en XHTML un texto en negrita, cursiva o subrayado es tan sencillo como utilizar el elemento <b>, <i> o <u> respectivamente. Todo el contenido que esté dentro de las etiquetas de apertura y cierre automáticamente pasará a estar marcado según el atributo seleccionado. Así de sencillo. <p>Esto es un ejemplo de un <u>párrafo que aparecería dentro de nuestra página web</u>. El navegador automáticamente va a darle un <b>margen superior e inferior</b> para separarlo de los <i>contenidos adyacentes</i></p> Saltos de línea Como habrás podido comprobar, cuando introducimos un elemento de tipo párrafo se insertan saltos de línea automáticamente para que el texto no desborde de la ventana de contenido. Ahora bien, si necesitamos incluir saltos de línea manualmente el XHTML nos brinda un elemento nuevo que cumple dicha función: el salto de línea o <br/> U.D. IV – Web 2.0 31 <p>Esto es un ejemplo de un párrafo que aparecería dentro de nuestra página web.<br/>El navegador automáticamente va a darle un margen superior<br/>e inferior para separarlo de los contenidos adyacentes</p> En cualquier caso, el elemento <br/> debe usarse solamente para insertar saltos de línea. No debemos utilizar indiscriminados br's para separar párrafos ya que es una práctica que puede darnos sorpresas desagradables cuando probemos nuestra página en otros navegadores. Separadores Horizontales Del mismo modo que el elemento <br/> insertaba un salto de línea dentro de una párrafo, el separador horizontal o <hr/> va a introducir una línea de separación entre los contenidos que "separa". Su uso es idéntico al del salto de línea, aunque como comentamos, introducirá además una línea entre las que haya separado. Esta es la primera línea<br/> Esta es la segunda línea<hr/> Esta es la tercera línea, separada de la anterior por una línea horizontal. Los Encabezados o Títulos Los títulos nos sirven para agrupar información y son necesarios en una página que vaya disponer contenido y que pretenda ser interpretada desde diferentes navegadores y dispositivos acertadamente. Para conseguir esto, el estándar XHTML nos proporciona diferentes etiquetas de encabezado o título. Dichas etiquetas comienzan por la letra "h" seguida del número de encabezado por orden de importancia. De este modo el elemento <h1> nos daría el título principal de la página y por medio de los <h2>, <h3> y hasta el <h6> iríamos definiendo títulos secundarios de página que irían guiando al lector por las diferentes secciones que contenga. U.D. IV – Web 2.0 32 El código XHTML que mostramos a continuación tiene todos los elementos que hemos visto hasta ahora combinados en un mismo documento: <h1>Prueba de elementos sencillos de XHTML</h1> <p>Esto es un ejemplo de un párrafo que aparecería dentro de nuestra página web. <b>El navegador automáticamente</b> va a darle un <u>margen superior e inferior</u> para separarlo de los contenidos adyacentes</p> <h3>Separación de líneas por medio de saltos de línea</h3> <hr/> Primera línea separada<br/> segunda línea separada<br/> Tercera línea y final del documento<hr/> 4.2.1_1 – Vista en el explorador del elemento anterior U.D. IV – Web 2.0 33 Aprovechando la plantilla que has guardado con anterioridad, crea un contenido sencillo formado por un par de títulos de diferentes niveles (h1 y h2, por ejemplo), párrafos, saltos de línea y separadores. Guárdalo todo dentro de las etiquetas <body> y </body> y comprueba el resultado ejecutando la página en tu navegador de internet predeterminado. Si lo haces correctamente la representación sería similar a la que hemos visto en el ejemplo anterior. Enlaces Los enlaces o hiperenlaces son un elemento muy importante dentro de la jerarquía de etiquetas de XHTML, ya no nos van a permitir desplazarnos a otras páginas diferentes a la que nos encontramos. Esto es especialmente importante cuando tratamos de aplicaciones web, ya que como veremos más adelante, todos los botones o acciones que realicemos, en su mayor parte van comenzar por la pulsación de un enlace. Para definir un enlace en XHTML utilizaremos la etiqueta "a" seguida de un atributo llamado "href" que nos indicará el destino del enlace. Dicho destino puede ser una página propia, una página de Internet (externa) o incluso una dirección de correo electrónico. Para finalizar, antes de la etiqueta de cierre colocaremos el texto que aparecerá en nuestra página y que hará las veces de dicho enlace. Los siguientes enlace nos llevarían a una página interna, una externa y finalmente abrirían nuestro gestor de correo para permitiéndonos crear un nuevo mensaje para una dirección de correo que especificaremos. <a href="contenidos.htm">Enlace a una página interna</a> <a href="http://www.heraldo.es">Enlace a una página externa</a> <a href="mailto:[email protected]">Enviar un correo electrónico</a> Listas Las listas nos permiten crear relaciones de elementos en nuestra página. En este punto vamos a ver dos tipos de listas: ordenadas y sin ordenar. Las listas sin ordenar se definen con la etiqueta <ul> (unordered list) y nos van a permitir alojar en su interior diferentes elementos que colocaremos dentro de las etiquetas <li> y </li>. La representación gráfica final de los elementos llevará una viñeta a su izquierda, pero en ningún caso aparecerá un número o letra para identificarlos. Por contra, las listas sin ordenar se definen con el elemento <ol> y funcionan del mismo modo que las no ordenadas, ahora bien, en este caso en lugar de aparecer U.D. IV – Web 2.0 34 una viñeta simbólica, aparecerá un número indicando la posición del elemento dentro de dicha lista. La siguiente lista muestra un listado sin ordenar. Inclúyela dentro de la plantilla de documento XHTML y cambia la etiqueta del elemento de inicio para convertirla en una lista ordenada. <ul> </ul> <li>Elemento <li>Elemento <li>Elemento <li>Elemento 1</li> 2</li> 3</li> 4</li> 4.2.2_1 – Representación en el navegador del ejercicio anterior Imágenes XHTML nos permite, al igual que su antecesor, el HTML 4.01 introducir tantas imágenes como consideremos necesario dentro de nuestra página web. Para que una imagen aparezca junto con el contenido, deberemos utilizar la etiqueta <img>. U.D. IV – Web 2.0 35 Esta es una etiqueta que ha sufrido cambios desde la anterior versión del estándar y que ahora tiene que estar cerrada obligatoriamente. De este modo, para utilizarla deberemos incluir, además del atributo "src" con la ruta a la imagen que queremos mostrar, la etiqueta de cierre o la barra correspondiente. Para insertar una imagen en XHTML podemos utilizar cualquiera de las dos opciones que aparecen a continuación: <img src="miImagen.gif"></img> <img src="miImagen.gif" /> Si la imagen está incluida en una subcarpeta, deberemos indicarla junto con la ruta de modo que el navegador sea capaz de obtenerla y mostrarla sin problemas. Es una buena práctica incluir junto con la imagen el atributo "alt" con una descripción de lo que vamos a mostrar en la imagen. Esto juega un papel importante en la accesibilidad, ya que un navegador de páginas web para invidentes podrá "explicar" al usuario qué es lo que el autor quiere mostrar en la imagen. Utilizando el atributo "alt", nuestra imagen quedaría de este modo: <img src="miImagen.gif" alt="Un bonito día soleado" /> Tablas Las tablas en XHTML nos permiten mostrar la información de manera ordenada y para ello se disponen unas etiquetas que nos permitirán componer paso a paso la estructura que necesitamos: <table> Inicio de la tabla <tr> Inicio de fila <td> Inicio de celda </td> Fin de celda </tr> Fin de fila </table> Fin de la tabla Las tablas se componen de filas y estas de celdas, de modo que para crear una tabla deberemos incluir el elemento <table> seguido del <tr> para iniciar una fila, y dentro de esta todos los elementos <td> que sean necesarios para completar las celdas que la componen. U.D. IV – Web 2.0 36 Si en XHTML es de obligado respecto el correcto anidamiento de elementos, cuando tratamos de celdas y tablas esta imposición se hace más restrictiva inclusive, ya que una incorrecta anidación de filas-celdas puede "desmontarnos" literalmente toda la estructura. A continuación puedes ver el código correspondiente a una tabla bien formada: <table> <tr> </tr> <tr> </tr> </table> <td>Fila <td>Fila <td>Fila <td>Fila 1 1 1 1 - Celda Celda Celda Celda 1</td> 2</td> 3</td> 4</td> <td>Fila <td>Fila <td>Fila <td>Fila 2 2 2 2 - Celda Celda Celda Celda 1</td> 2</td> 3</td> 4</td> 4.2.1_3 – Resultado del ejercicio anterior visto en el navegador U.D. IV – Web 2.0 37 Lección 2 El Modelo de Objetos de Documento (DOM) Hasta ahora hemos estado viendo cómo generar páginas XHTML válidas, como aplicar estilos por medio de hojas de estilo CSS y cómo podemos mejorar el rendimiento de nuestra aplicación preservando ancho de banda y aligerando el código de dichas páginas. Ahora bien, si se supone que vamos a crear aplicaciones web, es decir, páginas dinámicas que variarán en función de las opciones del usuario y el comportamiento del servidor, ¿Cómo vamos a hacer que el contenido de las mismas cambie? Para ayudarnos en esta tarea surge el DOM o Modelo de Objetos de Documento que no es más que una representación orientada a objetos de un documento XML o HTML. Esto que en principio puede sonar un poco complicado no lo es tanto. Lo que realmente es el DOM es un conjunto de variables y elementos que podremos manipular por medio de programación y que se corresponderán con los elementos HTML que hemos visto hasta ahora. Como ejemplo práctico y para aclarar un poco esta definición, diremos que si una página tiene dos párrafos y un enlace, dichos párrafos y enlace se corresponderán con “algo” que podremos manipular por JavaScript para modificar el contenido del que disponen. La estructura de un documento XML o HTML es jerárquica, por lo que la estructura del DOM puede verse como un árbol. El mismo DOM nos va a proporcionar una API o conjunto de reglas e instrucciones para modificar dicho árbol de controles y además va a ser independiente del lenguaje de programación utilizado, así que tendremos pocos problemas en el uso de la misma a través de los diferentes navegadores. La API DOM se utiliza en diversos ámbitos además de las aplicaciones Web 2.0. Podríamos poner un ejemplo en la programación de servidores con lenguaje JAVA, en la que la API DOM juega un papel fundamental en la manipulación de documentos XML. En nuestro caso veremos detalles DOM dentro del entorno del navegador y comprobaremos cómo podemos hacer uso de la API que contiene para modificar dinámicamente la página XHTML U.D. IV – Web 2.0 38 Vamos a considerar la API DOM de este fragmento <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd "> <html xmlns="http://www.w3.org/1999/xhtml\" xml:lang="es" lang="es"> <head> <meta http-equiv ="Content-Type" content="text/html;charset=utf8" /> <title>Título de la página</title> </head> <body> <h1>Prueba de elementos sencillos de XHTML</h1> <p>Esto es un ejemplo de un parrafo</p> <p>Esto es un ejemplo de un párrafo con <b>estilo en los elementos</b> que aparecen en él</p> </body> </html> La representación del documento que acabamos de ver en la ventana del navegador sería la siguiente: 4.2.2_1 – Visualización del código que aparece en el ejemplo U.D. IV – Web 2.0 39 Ahora bien, si miramos el modelo de objetos generado por este documento, obtendríamos algo como lo que aparece a continuación: 4.2.2_2 – Modelo de objetos del documento del ejemplo anterior Como hemos comentado, el DOM está estructurado como un árbol y sigue la estructura jerárquica del código HTML. El árbol contiene diferentes nodos y cada uno de estos nodos puede contener cero o más nodos hijos como podemos comprobar en el esquema que aparece en la imagen superior. Asimismo, todos los elementos tienen un padre salvo el nodo raíz, que en este caso sería el nivel superior de documento y tendría como hijos a los nodos con la definición de tipo de documento y la etiqueta de inicio del código HTML. En este esquema se reproducen algunos elementos que debemos explicar antes de continuar: 9 La mayoría de los elementos de este árbol son elementos HTML o texto y se mapearían directamente con la estructura HTML, es decir, si accediéramos por medio de la API DOM a su contenido, un cambio se reflejaría inmediatamente en el contenido visualizado. 9 Debido a que nuestro documento tiene una DTD o declaración de tipo de documento, el primer hijo del nodo raíz es dicha declaración. Si no incluimos este elemento, creando en ese caso una página no validada, el esquema DOM cambiaría y no lo contendría directamente, por lo que no podemos suponer que siempre el segundo hijo del elemento raíz es el comienzo del documento HTML. Niveles DOM En esta sección vamos a estudiar los tres niveles de soporte que tiene DOM, tal y como han sido definidos en las recomendaciones del W3C 9 El nivel 1 de DOM apareció en 1998 cuando los navegadores ofrecían una API similar a DOM, pero no estandarizada y que variaba en cada uno de ellos. Se aprobó entonces el modelo como parte de un esfuerzo para definir una API común que pudiera ser implementada en los navegadores de la época. Su adopción por parte de estos ha sido lenta, pero hoy por hoy podemos aceptar que todos los navegadores que hay en el mercado aceptan U.D. IV – Web 2.0 40 perfectamente el nivel 1 de DOM 9 El nivel 2 de DOM se publicó en 2003 y la mayor parte de su API está implementada en los principales navegadores del mercado, excepto Internet Explorer, que implementa un subconjunto de dicha API. Actualmente y para desarrollar una aplicación web que soporte DOM, esta versión sería la más indicada para utilizar. 9 El nivel 3 de DOM está todavía en proceso de aceptación y validación, ya que después del nivel 2, la especificación se dividió en varios documentos, una para componentes básicos, otra para elementos más específicos de HTML, otra para funcionalidades avanzadas y manejo de eventos… Sólo un subconjunto de estos elementos ha sido publicado por el W3C como recomendación, mientras otros todavía están en proceso de aceptación. La mayoría de los navegadores soportan un nivel mínimo de compatibilidad con el nivel 3 de DOM, pero Internet Explorer no lo soporta. Por este hecho, trabajar hoy por hoy con el nivel 3 de DOM es algo arriesgado por motivos obvios de compatibilidad. Si deseas obtener más información sobre los niveles de la API DOM, en concreto del nivel 2 de la misma, puedes visitar el siguiente enlace de la web del W3C, donde se recoge la especificación completa: http://www.w3.org/TR/DOM-Level-2-HTML/html.html 4.2.2_3 – Especificación de la API DOM en la web del W3C U.D. IV – Web 2.0 41 Revisión de la API DOM En esta sección vamos a dar unas leves pinceladas acerca del uso de la API DOM ya que no es objeto de este curso hacer una referencia completa a dicho documento. En las próximas líneas veremos cómo utilizar la API DOM para manipular el contenido de un documento HTML y más adelante en el curso veremos casos prácticos de uso de JavaScript que nos permitirán hacer que nuestra página se convierta en una aplicación. El punto de entrada al modelo de objetos del documento es, valga la redundancia, el objeto “document”, que corresponde con el nodo raíz del documento. Desde este punto podemos navegar recursivamente a través del documento por medio de los atributos disponibles en todos los nodos del mismo; funciones como “firstChild”, “lastChild”, “nextSibling”, “previousSibling”, “childNodes” y “parentNodes” nos van a permitir recorrer el árbol que hemos visto en secciones anteriores y modificar el contenido de los nodos que ubiquemos en él. El primer elemento HTML y el correspondiente al encabezado, obtendríamos con unas funciones como las que se muestran: lo html = document.childNodes[1]; head = html.firstChild.nextSibling; En todo caso, navegar de este modo un documento es un tanto tedioso y por ello, existen otras formas de acceder y modificar la información de un modo un tanto más cómodo. Por medio de los métodos “getElementById()” y “getElementsByTagName()”, podremos acceder a la jerarquía de elementos que componen el DOM referenciándolos por medio del valor del parámetro ID de los mismos. Por otro lado, el elemento “getElementsByTagName()” nos devolverá una lista de nodos que contendrá todos los que contengan un elemento que coincida con el nombre dado. U.D. IV – Web 2.0 42 En las siguientes líneas se muestran diferentes métodos y el valor que devolverían al ejecutarlos sobre el documento que hemos visto en el ejercicio inicial de esta lección: document.getElementsByTagName(“p”); -> Nos devolvería una lista con dos nodos document.getElementsByTagName(“p”).lenght; -> Devolvería “2” document.getElementsByTagName(“p”)[0]; -> Obtendríamos acceso al primero de los dos párrafos que contiene el documento document.getElementsByTagName(“p”)[1]; -> Obtendríamos acceso al segundo de los dos párrafos que contiene el documento document.getElementsByTagName(“P”); -> Obtendríamos lo mismo que el primer caso en Internet Explorer, pero en otros navegadores el resultado podría variar Comentar que los nodos disponen de una propiedad llamada “tagName” que devuelve el nombre del propio elemento. Los nodos de texto tienen la propiedad “nodeValue”, que devuelve el valor de la cadena del nodo. Hay una gran variedad de elementos que podemos utilizar para crear o anexar contenido a nuestro DOM actual, en particular podemos hacer uso de createElement() y createTextNode(), que nos permitirán respectivamente anexar un nuevo elemento y un nodo de texto. Recientemente pueden insertarse nodos ya creados en DOM por medio de funciones como “appendChild()”, “insertBefore()” y “replaceChild()”. Los nodos existentes pueden eliminarse con “removeChild()” Con las siguientes órdenes añadiríamos un nuevo párrafo al contenido: primerParrafo = document.getElementsByTagName(“p”)[0]; nuevoParrafo = document.createElement(“p”); nuevoParrafo.appendChild(document.createTextNode(“Párrafo insertado”)); primerParrafo.parentNode.insertBefore(nuevoParrafo, primerParrafo); U.D. IV – Web 2.0 43 4.2.2_4 – Resultado del ejemplo tras ejecutar las órdenes de inserción La Consola de depuración de Internet Explorer El navegador Internet Explorer en su versión 8, incorpora una herramienta muy valiosa para el estudio, interpretación y depuración del DOM: La consola de depuración. Por medio de este elemento que se abre pulsando la tecla F12 de nuestro teclado, podremos inspeccionar completamente el DOM generado en base al código de la página, modificarlo en tiempo real e incluso ver información de estilo y depurar JavaScript. Desde aquí te animamos a que sobre cualquier página pulses F12 y descubras todo lo que dicha consola de depuración te puede ofrecer, que no es poco… U.D. IV – Web 2.0 44 4.2.2_5 – Consola de depuración de Internet Explorer 8 Referencia sobre la API DOM Para obtener información más detallada sobre la API DOM, puedes dirigirte a muchas referencias en la web. Aquí te detallamos algunas de ellas: 9 Las especificaciones W3C DOM son buena referencia sobre todo puedes dirigirte a las especificaciones básicas de nivel 2 y las especificaciones de HTML de nivel 2. Puedes encontrar la especificación básica de DOM de nivel 2 en http://www.w3.org/TR/DOM-Level-2-Core/ y la correspondiente de HTML en http://www.w3.org/TR/DOM-Level-2-HTML/ 9 Si las especificaciones del W3C te parecen un poco intimidatorias, se han creado sitios y herramientas que hacen el aprendizaje y uso de las mismas más accesible. DevBoi es una herramienta de Firefox que facilita mucho la labor del trabajo con DOM y que puede descargarse como extensión del mismo. 9 ZVON.org es equivalente a DevBoi y ofrece un gran número de referencias a las recomendaciones del W3C 9 Por último, Microsoft en su MSDN ofrece una referencia sobre todos los objetos aceptados por Internet Explorer. Dado que soporta solamente un conjunto reducido, la referencia puede resultar incompleta, pero por lo menos compatible si usamos o tenemos pensado que los destinatarios de nuestra aplicación utilicen Internet Explorer como marco de trabajo para ella. U.D. IV – Web 2.0 45 Lección 3 Hojas de Estilo en Cascada (Avanzado) En el capítulo anterior estuvimos observando las ventajas que tiene el uso de las Hojas de Estilo CSS al combinarlas con una página HTML o XHTML válida. Comentábamos mejoras y estudiábamos cómo por medio de las mismas podíamos ser capaces de cambiar atributos de texto, colores y demás valores sencillos. En esta lección vamos a ver las hojas de estilo CSS como una ayuda que nos va a permitir crear el diseño de nuestra página de un modo igualmente limpio, pero que desatará todo su potencial cuando generemos "layouts" o marcos de trabajo sin el uso de tablas y con el mínimo nivel de código HTML. Si el correcto uso de las hojas de estilo en el formateo de texto y párrafos es una mejora muy importante, cuando aplicamos dichos elementos a la estructura de una página web dicha mejora se multiplica enormemente, ya que al eliminar el uso de las tablas para disponer el contenido, además de eliminar atributos de diseño de las diferentes etiquetas que contenga nuestro DOM, vamos a eliminar el número de etiquetas que contiene nuestra página. Si recuerdas la anterior lección, para crear una tabla con una sola celda necesitaríamos al menos tres etiquetas de HTML. Sin embargo, si hacemos un correcto uso de las hojas de estilo y el modelo de cajas que veremos a continuación, el número de etiquetas necesarias para hacer lo mismo va a verse reducido a una sola... Para crear una tabla con una celda en HTML necesitaríamos el siguiente código: <table> <tr> <td>Contenido de la celda</td> </tr> </table> Con el correcto uso de las hojas de estilo, dicha celda se crearía del siguiente modo: <div>Contenido de la celda</div> El Modelo de Cajas Como hemos visto en la introducción de esta lección, el modelo de cajas nos va a permitir crear bloques de contenido y posicionarlos como nos interese dentro de la web que estemos creando, diseñando entornos con diferentes disposiciones sin el uso de tablas. U.D. IV – Web 2.0 46 En realidad, todos los elementos de una web que hemos visto hasta ahora (párrafos, enlaces, imágenes, tablas, etc.) son cajas rectangulares. Los navegadores cuando procesan el documento sitúan estas cajas de la forma que nosotros les hayamos indicado para maquetar la página y después nos muestran el resultado de dicha operación. Hay dos tipos de cajas básicos: "block" e "inline". Los elementos de tipo block rompen el flujo del texto y se posicionan por defecto debajo del mismo. Esto es, aparecen solos, insertando "saltos de línea". Los elementos “inline”, por el contrario, siguen el flujo del texto y están contenidos dentro de elementos de tipo bloque. Un párrafo sería un elemento de tipo "block" (no podemos tener un párrafo al lado del otro, sino que dos párrafos seguidos aparecerán uno abajo del otro). En cambio, un enlace es un elemento inline, ya que no "corta" el texto donde está metido, simplemente se coloca a continuación del texto, como lo haría una nueva frase o un texto en negrita. Ambos tipos de elementos responden al mismo modelo de cajas que dispone cómo se comportan los atributos de margin, padding, borde, altura y anchura en el bloque que se va a representar. Un esquema válido del modelo de cajas es el que aparece a continuación: 4.2.3_1 – Esquema del modelo de cajas En las siguientes líneas vamos a describir las propiedades que aparecen en el esquema adjunto y el comportamiento que tienen sobre el modelo: U.D. IV – Web 2.0 47 Ancho y Alto El parámetro width representa el ancho de la caja. Cuando nos referimos al ancho de la caja lo que estamos indicando es el ancho interior, es decir, si bordes, márgenes, ni padding. Podemos indicarlo en medidas absolutas como suelen ser los píxeles o en relativas, en este caso nos serviremos del porcentaje. Aunque los elementos de tipo inline tienen anchura y puede ser accedida con el parámetro width, si la modificamos con CSS no veremos ningún resultado visual, ya que el ancho de estos elementos se establece automáticamente para que se ajuste a las dimensiones del elemento. Si tenemos un párrafo que contiene diez palabras, el ancho total del párrafo será lo que ocupen esas diez palabras, ni más ni menos... Lo comentado en este punto es perfectamente válido para las alturas de las cajas, ya que se comportan del mismo modo que el indicado para la anchura. Padding Con el parámetro padding vamos a indicar la distancia de “relleno” entre el límite interior del contenido de la caja y su borde exterior. Para evitarnos sorpresas, siempre que indiquemos un padding a una caja lo haremos utilizando medidas absolutas (píxeles). Si queremos establecer un padding de 20 píxeles para toda la caja, lo indicaríamos por medio de la regla: padding: 20 px. Si por el contrario queremos dotar de un padding distinto para cada lado, podremos hacerlo utilizando los sufijos -top (superior), -bottom (inferior), -left (izquierda) y -right (derecha) de este modo: padding-top: 10 px; padding-bottom : 5px; padding-left : 30 px; padding-right : 20 px; U.D. IV – Web 2.0 48 Podemos abreviar el código anterior en una sola línea, indicando primero el padding superior y luego siguiendo el orden de las agujas del reloj, es decir: arriba, derecha, abajo, izquierda: padding : 10px 20px 5px 30px; Border Si queremos aplicar bordes de diferente grosor y color a nuestra caja, lo conseguiremos con la propiedad border, que tiene la siguiente sintaxis: "border: width style color" Como fácilmente podrás suponer, width especifica el grosor del borde y puede ser indicado en píxeles (por ejemplo: 2px), pero también podemos utilizar las palabras thin (fino), medium (normal) y thick (grueso). Es recomendable utilizar medidas en píxeles, ya que la interpretación de los thin, medium y thick depende del navegador y de su motor de visualización, lo que puede llevarnos a alguna sorpresa. El parámetro style se refiere al tipo de borde. Los más comunes son: solid (línea continua), dashed (línea discontinua), dotted (línea de puntos) y double (línea continua doble). Por último, color indica el color del borde y puede ser definido con colores con nombre ("Red", "Blue"...) o por medio del código hexadecimal del mismo, que viene indicado por una almohadilla "#" y 6 dígitos que referencian al nivel de color rojo, verde y azul necesarios para generar el color. Del mismo modo que en el margen, podemos escoger un tipo de borde diferente para cada lado con los sufijos -top, -bottom, -left y -right. Por ejemplo, para crear un borde inferior basado en línea punteada y de color azul, escribiríamos la siguiente regla CSS: border-bottom : 1px dotted #Blue; Si deseamos eliminar un borde que nos venga dado por el navegador, simplemente hemos de indicar un grosor de 0px y un estilo que sea igual a "none". Esto es muy útil en el tratamiento de imágenes, ya que si dentro de un enlace incluimos una de estas, el navegador le asignará un borde por defecto. Si queremos eliminarlo, tan sólo debemos escribir la siguiente regla CSS: img {border: 0px none;} Márgenes Los márgenes se controlan con la propiedad margin, y como hemos visto en el modelo de cajas, se refiere a la distancia entre el borde de la caja y los elementos que la rodean. Su uso es idéntico al de la propiedad padding y está permitido su uso en una misma línea, por separado o indicando el mismo valor para todos los lados disponibles. U.D. IV – Web 2.0 49 Si queremos indicar un margen superior de 10 píxeles, izquierdo y derecho de 20 e inferior de 30, lo haríamos por medio de la siguiente regla de estilo: border: 10px 20px 30px 20px; Si queremos centrar el elemento, podemos hacer uso del valor "auto" (sólo en XHTML), de modo que si quisiéramos centrar un elemento concreto, añadiríamos las siguientes reglas CSS a su estilo: margin-left: auto; margin-right: auto; Flotación La flotación es uno de los parámetros CSS que podemos utilizar para hacer nuestro diseño más sencillo, ahorrándonos unos cuantos elementos HTML y evidentemente su peso en atributos de estilo si utilizábamos tablas para crear disponer elementos en la página. Lo que nos permiten hacer los parámetros de flotación es altear el flujo del texto, “incrustando” en él un elemento de bloque. El ejemplo más típico de esto se produce cuando queremos colocar una imagen acompañando a un texto, y que el texto “envuelva” a la imagen. Este efecto puede ser creado por medio de la introducción de la siguiente clase CSS: . imagenFlotante { float: left ; } U.D. IV – Web 2.0 50 4.2.3_2 – Imagen flotante a la izquierda Cabe reseñar que los elementos que se encuentren bajo la propiedad float, van a ser "apilados" al lado que le indiquemos (puede ser left o right), es decir, si tenemos dos imágenes con la propiedad "float: left", ambas se apilarán una junto a otra como podemos ver en el siguiente ejemplo: U.D. IV – Web 2.0 51 4.2.3_3 – Dos imágenes flotantes a la izquierda Uno de los problemas más importantes con los que nos vamos a encontrar al utilizar elementos flotantes en la creación de esquemas de diseño es que dichos contenidos no van a estar en línea con el texto y que por tanto no nos van a "empujar" el contenido que esté por debajo y simplemente van a floater sobre él. Para resolver esto basta con colocar la regla de estilo "clear: both" en el elemento que queremos que sea "arrastrado" por la capa que está ubicada en modo flotante. Esto es especialmente útil para crear pies de página tal y como veremos en el ejemplo de creación de un layout de 3 columnas que tenemos a continuación. Ejemplo de creación de un layout de 3 columnas con cabecera y pie Para finalizar este capítulo vamos a crear paso a paso un esquema de diseño basado en una cabecera, tres columnas y un pie sin utilizar tablas y con una estructura tanto CSS como XHTML correcta. Vamos a ir paso a paso creando todos los elementos que lo compondrían: Paso 1 - Creación del contenedor de la página Sobre nuestra plantilla XHTML, introduciremos una sección en la cabecera que albergue información de estilos por medio de las etiquetas <style> y </style>. Vamos a añadir entonces un nuevo elemento llamado "div" que nos creará una caja vacía y lo ubicaremos dentro del <body>. Una vez incluido en nuestra plantilla, añadiremos su correspondiente estilo en la cabecera, por lo que el resultado nos quedaría del siguiente modo: U.D. IV – Web 2.0 52 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd "> <html xmlns="http://www.w3.org/1999/xhtml\" xml:lang="es" lang="es"> <head> <meta http-equiv ="Content-Type" content="text/html;charset=utf-8" /> <title>Título de la página</title> <style> #wrapper { margin-left: auto; margin-right: auto; width: 600px; } </style> </head> <body> <div id="wrapper"> Contenido </div> </body> </html> Con esto conseguiremos tener un contenedor de 600 píxeles centrado en el navegador. Ahora no podemos ver todavía nada porque no hay contenido, aunque si agrandamos la ventana de nuestro navegador veremos cómo el texto "Contenido" se mueve, lo que nos indica que está colocado encima de algo... Paso 2 - Creación de las columnas laterales Añadiremos un par de capas más a nuestra plantilla dentro del elemento <wrapper> (eliminamos ya la palabra "Contenido", que no vamos a utilizar de momento). <div id="wrapper"> <div id="columnaIzquierda"> COLUMNA IZQUIERDA </div> <div id="columnaDerecha"> COLUMNA DERECHA </div> </div> Dichas capas o bloques deberán colocarse a ambos lados del diseño, por lo que estableceremos sendos estilos para cada una de ellas, uno con flotación izquierda y otro con derecha: #columnaIzquierda { float: left; width: 150px; } #columnaDerecha { float: right; U.D. IV – Web 2.0 53 } width: 150px; Paso 3 - Cabecera y Pie Nuestra página va a necesitar una cabecera y un pie. Vamos a crear dos nuevas capas y las colocaremos antes y después de las columnas del siguiente modo: <div id="wrapper"> <div id="cabecera"> CABECERA </div> <div id="columnaIzquierda"> COLUMNA IZQUIERDA </div> <div id="columnaDerecha"> COLUMNA DERECHA </div> <div id=pie"> PIE </div> </div> Para que ambos elementos se ubiquen correctamente, necesitaremos añadirles información de estilos. Vamos a colocarles un color de fondo para que podamos verlos y al pie le añadiremos la propiedad "clear:both" para que sea "empujado" por debajo de las columnas. Si quieres probar la propiedad, puedes eliminarla y verás como el pie se introduce entre las dos columnas en lugar de quedar por debajo de ellas #cabecera { background: yellow; } #pie { clear: both; background: #A2A2A2; } Paso 4 - El contenido Tan sólo nos queda un elemento que colocar, la capa que contendrá el contenido de la página. Para ello vamos a intercalar una nueva capa entre las dos columnas, por lo que el HTML resultante quedaría como aparece a continuación: <div id="wrapper"> <div id="cabecera"> CABECERA </div> <div id="columnaIzquierda"> COLUMNA IZQUIERDA </div> U.D. IV – Web 2.0 54 <div id="contenido"> CONTENIDO </div> <div id="columnaDerecha"> COLUMNA DERECHA </div> <div id=”pie"> PIE </div> </div> Asimismo, para que se coloque correctamente apilado y tenga la anchura necesaria, aplicaremos las siguientes reglas de estilo, dando nuestro diseño por finalizado: #contenido { float: left; width: 300px; } 4.2.3_4 – Resultado del ejercicio con el layout de 3 columnas U.D. IV – Web 2.0 55 Capítulo 3 JavaScript y AJAX Llegados a este punto, nuestro nivel de conocimiento de XHTML y Hojas de Estilo CSS nos permitiría crear una página web que sirviera de marco de trabajo para nuestra aplicación de modo relativamente sencillo. Asimismo seríamos capaces de definir las zonas o elementos que van a albergar contenidos dinámicos y cómo debemos ubicarlas y aplicarles estilos para que se visualizaran correctamente y no mermaran la experiencia de usuario, ya que estarían optimizadas para que toda la capa de diseño estuviera en un archivo CSS externo. Ahora bien, el corazón de las aplicaciones web 2.0 (con el permiso del lenguaje de programación de servidor que veremos en el siguiente capítulo) es el uso de AJAX, y en este binomio entran el lenguaje XML y JavaScript como jugadores principales. A lo largo de las lecciones que componen este capítulo vamos a ver unas nociones de JavaScript necesarias para que podamos entender el funcionamiento de las aplicaciones web 2.0. Conoceremos el lenguaje y por medio de ejemplos sencillos aprenderemos a utilizarlo y exprimirlo para minimizar el tráfico con el servidor y cargar la memoria del navegador del cliente lo menos posible. En la última lección nos sumergiremos completamente en AJAX para conocer el objeto que nos permitirá hacer peticiones al servidor y obtener respuestas que podremos convertir en texto y contenido legible para el usuario. Al finalizar el estudio de estas lecciones serás capaz de: 9 Utilizar el JavaScript como lenguaje de cliente para hacer tareas sencillas 9 Optimizar las aplicaciones para que la carga sea mínima 9 Hacer ejemplos que utilicen AJAX para establecer el diálogo entre clienteservidor U.D. IV – Web 2.0 56 Lección 1 Aspectos de JavaScript JavaScript es un lenguaje que se ejecuta en nuestro navegador y que permite realizar tareas en las páginas directamente en el navegador, sin que los datos lleguen al servidor que se encuentra en “el otro lado”. Dicho lenguaje es interpretado, y con esto queremos decir que no se “compila”, por tanto el código del mismo llega al navegador del cliente y puede ser visto y copiado sin problemas. JavaScript nos va a proporcionar medios y métodos para: 9 Controlar las ventanas del navegador y el contenido que muestran. 9 Programar páginas dinámicas simples sin tener que utilizar lenguajes de servidor y tecnología externa. 9 Evitar depender del servidor para cálculos que puedan realizarse en el navegador, liberando a este de la carga que ello supone. 9 Capturar los eventos generados por el usuario y responder a los mismos sin tener que utilizar tecnología de servidor. 9 Comprobar los datos que el usuario introduce en un formulario antes de enviarlos. 9 Comunicarse con el usuario por medio de ventanas y otros métodos que veremos posteriormente. Como característica especial que podemos nombrar de JavaScript es que aunque el lenguaje soporta varios tipos de datos, no es necesario definirlos en las variables ni en los argumentos o respuestas de las funciones que en él se utilizan. El tipo de las variables va a cambiar automáticamente en función de lo que necesitemos, lo que lejos de ser un problema, debido a la magnitud de los desarrollos en esta plataforma, que suelen ser sencillos, nos proporciona una gran ventaja para escribir código rápidamente. Históricamente podemos decir que JavaScript fue inventado por Netscape, que lo ofrecía dentro de su navegador en la versión 2.0. De su nombre original “LiveScript” sólo nos hemos quedado con la parte del final, ya que se cambió para aprovechar el tirón que las tecnologías basadas en Java tenían en aquel momento. Microsoft, por su parte en esta lucha de navegadores y tecnologías, nos comenzó a ofrecer una vez más una versión reducida de dicho lenguaje en sus navegadores llamada JScript. Actualmente, todos los navegadores del mercado soportan la práctica totalidad de JavaScript y gracias a esto, la programación de lado de cliente y las aplicaciones web 2.0 son más sencillas de “compatibilizar” entre los mismos. U.D. IV – Web 2.0 57 Las bases del lenguaje JavaScript El código JavaScript se inserta directamente en los documentos HTML o XHTML que podemos crear. De este modo viene junto con el contenido del mismo y el navegador es capaz de procesarlo junto con este sin mayores problemas. Podemos no obstante extraerlo en un archivo externo y colocar una referencia en la página a dicho archivo. En este caso, todos los beneficios que hemos visto a las hojas de estilo en archivo externo también se aplicarían a JavaScript. Como hemos comentado con anterioridad, JavaScript es de un lenguaje interpretado que no se compila ni se genera ningún ensamblado intermedio como en el caso de Java. Es importante no confundirlos, ya que este último tiene ciertas ventajas e implementaciones que no se dan en JavaScript. Java fue desarrollado por Sun MicroSystems, y nació como un derivado del lenguaje C++. JavaScript por su lado, tuvo su nacimiento totalmente independiente de Java y sólo su parecido semántico y cuestiones de marketing llevaron a sus desarrolladores a denominarlo de esta forma. Aun con todo, ambos lenguajes heredan ciertos elementos de C++, por lo cual la traslación de conocimiento y modo de trabajo es muy directa. Por otro lado, debemos reseñar que JavaScript es un lenguaje de Script y como tal, no tiene cabida fuera de una página HTML. No podemos crear aplicaciones de escritorio directamente en JavaScript, aunque si incluimos fragmentos de código en documentos HTML y creamos una jerarquía de páginas lo suficientemente compleja, más de uno ni se enteraría de que en realidad está viendo páginas HTML y no una aplicación de escritorio… Todo el código de JavaScript debe introducirse en la página HTML según el formato que aparece a continuación: <script language="JavaScript"> // Aquí irá el código </script> Si optamos por colocar el código en un archivo externo, el modo de referenciarlo en la página en la que va a ser procesado sería la siguiente: <script src="archivoJavaScript.js" language="javascript"></script> Si bien el código JavaScript o su etiqueta de incrustación pueden colocarse en cualquier punto de una página HTML, el modo de comportarse puede ser diferente si dicho código referencia a algunos objetos del documento. El modo más común de U.D. IV – Web 2.0 58 localización de dichas etiquetas suele ser dentro del elemento <head> o justo antes del cierre del elemento <body> Fundamentos de JavaScript En esta sección vamos a definir algunos elementos teóricos del lenguaje. Es una sección algo pesada, pero es necesario comprender correctamente estos elementos para poder avanzar en el uso de este lenguaje. Argumentos Los argumentos se utilizan en métodos y funciones y pueden ser por tanto valores y variables como objetos que con el método o función correspondiente son procesados. Por ejemplo en la función squareroot(32) tendríamos un argumento que sería el número 32 Manejadores de Eventos Los manejadores se utilizan para disparar llamadas a un script de JavaScript. De este modo podemos hacer que al hacer click sobre un elemento se ejecute un código que nosotros hayamos definido. Si queremos que cuando el usuario haga click sonbre un enlace se ejecute la función llamada “devolverNumero”, introduciremos el siguiente código: <a href=”link.htm” onClick=”devolverNumero()”>Click aquí</a> En el ejemplo tenemos un evento de click que inicia las acciones de la función devolverNumero(), es decir, al pulsar en el enlace no sólo accedemos a la página link.htm, sino que ejecutaremos la función correspondiente. Expresiones Una expresión es un conjunto de literales, variables y operadores que describen un único número, cadena o valor lógico, por ejemplo: x = y + 10. Funciones Las funciones son elementos que contienen un grupo de código que se ejecuta cuando se realiza la llamada a la función. En algunos lenguajes de programación también reciben los nombres de subrutinas o procedimientos. Teóricamente una función tiene que devolver siempre un valor y un procedimiento no. En JavaScript sólo disponemos de funciones y seremos nosotros los que decidamos si dichas funciones devuelven un valor o por el contrario se comportan como un procedimiento, ejecutando su código sin devolver ningún valor en su retorno. U.D. IV – Web 2.0 59 En el siguiente ejemplo de función vemos que usando el método alert( ), se abre una ventana de aviso con el texto "Esto es una prueba". Como se puede ver las instrucciones internas deben ir entre llaves ({ }). function prueba( ) { alert("Esto es una prueba"); } Métodos Los métodos son uno de los elementos clave en la programación a objetos. Son como una especie de funciones, pero siempre van a ir asociadas a un objeto, de modo que tendremos que indicarles una serie de argumentos y harán que las propiedades de dicho objeto cambien o nos devolverán un valor como respuesta. Objetos Los objetos son el elemento principal de JavaScript. Un ejemplo de objeto sería un botón en un formulario o un cuadro de texto también dentro del mismo. Básicamente todos los elementos que hemos visto en XHTML y que se referenciarían en el DOM serían objetos de JavaScript. En JavaScript todo son objetos. En la instrucción Document.write("hola") se está invocando al método write( ), que no es más que un método del objeto document para escribir un valor dentro del documento HTML… Los objetos son los elementos principales afectados o interpretados en JavaScript. Un ejemplo de objeto podría ser tanto un botón dentro de un formulario, como el propio formulario o documento. Operadores En JavaScript disponemos de dos tipos de operadores: los de asignación, que como su propio nombre indica, asignan valores al elemento a la izquierda del operador (por ejemplo, en " x = 5 ", el operador sería =), y los que corresponden a operadores aritméticos lógicos o booleanos, +, -, &&, ||, etc. Propiedades Las propiedades en JavaScript vendrían a asemejarse a los adjetivos que describen los objetos. Como ejemplo, de un objeto de tipo botón podríamos encontrar como propiedades su tamaño, posición, texto, etc. Sentencias de Control Son las responsables directas del flujo de ejecución del código y de que podamos hacer tareas no lineales. Un ejemplo de una sentencia de control sería un bloque U.D. IV – Web 2.0 60 condicional con la instrucción if...then que ejecutaría ciertas instrucciones sólo si se cumple la condición que definamos en entre las dos órdenes. U.D. IV – Web 2.0 61 Tipos de Datos JavaScript reconoce 4 tipos de valores diferentes, que serán sus tipos de datos: valores numéricos, booleanos, cadenas y el valor null (sin valor). Como no debemos declarar el tipo de cada una de nuestras variables, debemos ser especialmente cuidadosos en las operaciones con distintos tipos de datos ya que tenemos muchas papeletas para que se produzcan errores en la ejecución si los tipos de datos a operar no son los mismos. Variables Son representaciones de los tipos de datos que se inicializan o toman valor a través de las expresiones. Pueden ser locales o globales. Si una variable es de ámbito local, significa que sólo se usa o tiene sentido dentro de la zona en la que se ha definido (por ejemplo una función), si por el contrario la variable que hemos definido es global, tiene sentido en todo el script y podemos utilizarla, leyendo y modificando sus valores, desde cualquier punto de nuestro código. En el siguiente ejemplo vemos un ejemplo de script con una variable local y otra global. <SCRIPT> var globalvar1=5; Function multiplica() { var localvar1=2 * globalvar1; alert("Dos por cinco son= " + localvar1); } <SCRIPT> La variable “glovalvar” está definida como variable global y por tanto es válida en todo el documento. Por el contrario, “localvar” se define dentro de una función y este será su ámbito de ejecución. Si intentamos acceder al valor de dicha variable desde fuera de su función, se disparará un error de JavaScript. Sintaxis del JavaScript Como hemos comentado anteriormente, el código JavaScript va incluido dentro de las etiquetas <script> y </script>, que preferentemente ubicaremos dentro del <head> de nuestra página o a ser posible en un archivo externo para evitar que de este modo “cargue” el contenido y tamaño de la página. Vamos ahora a retomar el ejemplo de las variables globales y locales y vamos a incrustarlo dentro de un documento estándar para generar una página que un navegador podría interpretar sin mayores problemas. En este caso vamos a utilizar U.D. IV – Web 2.0 62 la especificación HTML normal para que quede patente que tampoco es necesario el uso estricto de XHTML para trabajar con JavaScript: <HTML> <HEAD> <TITLE>PRUEBA 1 </TITLE> <SCRIPT> var globalvar1=5; Function multiplica() { var localvar1=2 * globalvar1; alert("Dos por cinco son= " + localvar1); } </SCRIPT> </HEAD> <BODY BGCOLOR="#00AA00" TEXT="#FFFFFF" LINK="#0000FF" VLINK="#0000FF" ALINK="#0000FF" onLoad=multiplica()> <CENTER><H1> Esto es un ejemplo</H1></CENTER> </BODY> </HTML> Como se puede observar, hemos incluido el código de script dentro de sus etiquetas correspondientes y a su vez lo hemos ubicado dentro de la cabecera del documento. Una vez dentro del cuerpo del documento, se ha incluido un manejador de eventos “onLoad”, que llama al script, ejecutando la función correspondiente. Dicha función contiene un método, alert(), que despliega una ventana interactiva con el usuario informándole del texto definido entre paréntesis. Es importante entender que JavaScript es un añadido a los navegadores y que como tal puede ser que un usuario no disponga de dicha tecnología en el suyo o que simplemente la haya desactivado. Actualmente más del 95% de los usuarios según las estadísticas del W3C tienen habilitada esta posibilidad en su navegador, pero hay un pequeño grupo de usuarios que no serían capaces de ejecutar el código que le enviemos. Para todos estos existe la etiqueta HTML <noscript> y </noscript> y la utilizaremos para enviarles algún mensaje que le informe de que hay cierto código de JavaScript que se están “perdiendo” si no activan dicha funcionalidad o se cambian de navegador… Para poder usar JavaScript correctamente debemos entender cómo el navegador lo interpreta en el documento. La composición viene dada por el diseño de la página y se ejecuta secuencialmente. Es por esto que si queremos acceder a ciertas propiedades o elementos del DOM, tenemos que asegurarnos de que previamente hemos definido dichos elementos. U.D. IV – Web 2.0 63 Si disponemos del siguiente código: <form name="formula"> <input type="text" id="usuario" size=20 > <input type="text" id="edad" size=3 > </form> A partir de la definición de los elementos que en él aparecen, podríamos utilizar órdenes de JavaScript para acceder a su contenido por medio de document.getElementById(‘nombreDelElemento’). Esto lo haríamos del siguiente modo: <script> document.write(document.getElementById(‘usuario’).value) document.write(document.getElementById(‘edad’).value) </script> Sin embargo, si este bloque de script lo instanciamos en el documento antes de que aparezca el formulario, recibiremos un error de ejecución, ya que el navegador intentará ejecutarlo antes de que sean definidos los elementos. Esto no aplica a las funciones, que pueden definirse en cualquier punto del código, pero sí a sus llamadas, ya que del mismo modo que en este caso si ejecutamos una función que referencia algún elemento todavía no definido, obtendremos otro mensaje de error del navegador. Manejadores de Eventos Uno de los manejadores o disparadores de eventos más básicos es “onClick” que ejecutará el script que le indiquemos cuando el usuario haga click sobre el elemento que lo incluya. El resto de manejadores de JavaScript se utilizan del mismo modo, definiremos el nombre del manejador y la función, método o fragmento de código que debe ejecutar cuando se “dispare”. Vamos a ver un ejemplo práctico de uso del manejador “onClick”. No vamos a tratar el resto de manejadores que existen por el momento. Como la sintaxis de los mismos es muy similar, los iremos viendo a medida que los necesitemos. El siguiente ejemplo utiliza un manejador para generar un mensaje de alerta en el navegador. Los mensajes de alerta son utilizados diferentes propósitos, pero básicamente se utilizan para informar al usuario a través de un cuadro de diálogo que aparece tras la acción del usuario. U.D. IV – Web 2.0 64 <html> <head> <title> prueba 1 </title> <script> function boton(){ alert("esta página está en construcción, pero puedes echar un vistazo si quieres"); } </script> </head> <body> <h1>esto es un ejemplo</h1> visita nuestro <a href="menu.htm" onClick="boton();">menú </a>del día </body> </html> Como se puede ver, hemos insertado el código de script en la cabecera del documento, definiendo la función”botón()”, que se encargará de disparar la ventana de JavaScript correspondiente para el usuario. Después creamos el enlace a la página “menu.htm”, pero a su vez insertamos un atributo de dicho enlace que no es más que el manejador de eventos “onClick”. Cuando el usuario haga click en el enlace, le aparecerá la ventana informando que la página todavía está en construcción y tras su aceptación, le llevará a la misma por medio del enlace que ha ejecutado. Formularios Vamos a trabajar ahora con formularios, que son otro elemento que podemos utilizar para conseguir la interacción del usuario y que en las aplicaciones web 2.0 es tan necesaria. Antes de la aparición del JavaScript sólo era posible interactuar con los elementos de un formulario por medio de lenguaje de servidor. Con JavaScript podemos hacer ciertas operaciones más limitadas con los mismos de manera rápida. Evidentemente no podremos hacer las mismas operaciones que un lenguaje de servidor, ya que no podremos guardar datos en base de datos ni realizar operaciones similares, pero sí que podremos hacer muchas tareas cotidianas, eliminando dicha carga de procesamiento del lado de servidor. Los formularios nos proporcionan una respuesta (evento) ante las siguientes situaciones: 9 Un cambio en la opción seleccionada dentro de un grupo <select>, esto es un grupo de opciones a seleccionar por el usuario. 9 Entrar o salir dentro de un campo del formulario. 9 Transmisión de un formulario completo U.D. IV – Web 2.0 65 Vamos a enumerar ahora las etiquetas HTML que se usan habitualmente en un formulario. La explicación de las mismas se verá en la práctica con los ejemplos que veremos más adelante: 9 9 9 9 <input> <select> <textarea> <option> Todas ellas deberán ir incluidas dentro de la etiqueta <form> Los manejadores de eventos que podemos aplicar a estas etiquetas son los siguientes: onBlur: Inicializa un script cuando dejamos el campo del formulario, es decir, cuando acabamos de introducir un valor y pulsamos el tabulador para pasar al siguiente o hacemos click con el ratón fuera del mismo. Este manejador funciona con las etiquetas <input>, <select> y <textarea>. onChange: Este manejador funciona con las etiquetas <input>,<select> y <textarea> y ejecuta el script que le indiquemos cuando el contenido de uno o varios campos del formulario cambian. onFocus: Como su nombre indica, este disparador ejecuta su script cuando aplicamos el foco a un elemento, esto es cuando el usuario hace click sobre el elemento o por medio del tabulador “aterrizamos” en el mismo. Este manejador funciona con las etiquetas <input>,<select> y <textarea> onSelect: Este manejador sólo funciona con las etiquetas <input> y <textarea> y ejecuta su script al seleccionar un texto contenido en un elemento. Se suele confundir con el manejador onFocus, pero su activación es totalmente distinta. onSubmit: Se usa en unión con <form> y se activa cuando se envía el formulario. Es útil para mostrar ventanas del tipo “¿Está seguro de que desea continuar?” Vistos ya los manejadores principales, vamos a ver un par de ejemplos en HTML 4.01 que nos ilustren su funcionamiento: U.D. IV – Web 2.0 66 Este primer ejemplo utiliza el manejador onFocus para detectar la entrada del usuario en un campo del formulario, cambiando el color de fondo del mismo: <html> <head> <title> ejemplo 1 </title> </head> <body bgcolor=ffffff text=000000> <h2>onfocus - cambio de color de fondo</h2> <form> <input type="text" name="bgred" value="rojo" onfocus="document.bgcolor='red'"> <br> <input type="text" name="bggreen" value="verde" onfocus="document.bgcolor='green'"> <b/> <input type="text" name="bgblue" value="azul" onfocus="document.bgcolor='blue'"> <br> <input type="text" name="bgyellow" value="amarillo" onfocus="document.bgcolor='yellow'"> <br> </form> </body> </html> U.D. IV – Web 2.0 67 En este otro ejemplo, utilizaremos el manejador onBlur para tomar una acción al abandonar un campo del formulario. Lanzaremos un mensaje de alerta cuando el usuario salga del campo del código postal, avisando que es necesario rellenar el campo DNI para continuar. <html> <head> <title> ejemplo 2 </title> </head> <body> <h2>onfocus - mensaje de alerta</h2> <h2>introduzca su datos personales:</h2> <form><table> <tr><td>nombre:</td><td><input type="text" name="nom" size=35></td></tr> <tr><td>domicilio:</td><td><input type="text" name="dom" size=35></td></tr> <tr><td>ciudad:</td><td><input type="text" name="ciu" size=35></td></tr> <tr><td>provincia:</td><td><input type="text" name="pro" size=17 >c.p.:<input type="text" name="cp" size=12></td></tr> <tr><td>dni:</td><td><input type="text" name="dni" size=35 onblur="alert('es obligatorio insertar este dato')></td></tr> </table></form> </body> </html> U.D. IV – Web 2.0 68 Lección 2 Optimización JavaScript El rendimiento es un elemento muy importante que debemos tener siempre en cuenta en cualquier lenguaje de programación, pero en el caso de JavaScript esto es realmente importante, ya que nuestros usuarios además de disponer de diferentes máquinas en las que ejecutarán nuestro código, en cada una de ellas dicho código lo ejecutará un navegador distinto, y estos interpretan el código de maneras muy diferentes. Vamos no obstante a enumerar una serie de características que denotan la importancia de esta optimización que comentamos: 9 El código JavaScript se envía en cada una de las ejecuciones de la página desde el servidor al cliente: cuanto más código tengamos, más tiempo y ancho de banda ocuparemos en cada transferencia 9 JavaScript se interpreta en el navegador, no es compilado, lo que además de hacer más lenta su ejecución, hace que su rendimiento varíe en función del navegador y la versión del mismo 9 El código JavaScript interactúa con el usuario modificando la página HTML a través de la API DOM, por lo que tenemos un paso intermedio que también hará mella en el rendimiento. JavaScript se presenta entonces como un lenguaje potente que da facilidades al programador y es sencillo de utilizar. Esto a veces puede suponer que un sencillo cambio de un contenido en un control de texto que puede parecer trivial a simple vista, haga que el motor de renderizado de JavaScript del navegador tenga que hacer numerosos cambios y con ello requiera un uso intensivo del procesador del sistema superior al que cabe esperar de cualquier modo. Aplicaciones web como Gmail y el nuevo correo de Yahoo! basado en AJAX son un ejemplo de los retos que debe utilizar JavaScript. Hoy en día, con los ordenadores actuales no hay ningún problema en utilizarlos aprovechando todo su potencial, pero si los intentamos ejecutar en ordenadores de hace unos pocos años, la sencilla tarea de mostrar mensajes de correo o la creación de un mensaje, pueden suponer grandes tiempos de espera mientras el navegador y su motor de renderizado hacen el “trabajo sucio” para que dicha aplicación funcione correctamente. U.D. IV – Web 2.0 69 4.3.2_1 – Vista de Gmail, cliente de correo electrónico basado en AJAX Reduciendo el tiempo de descarga de JavaScript La mayor parte de los lenguajes de programación han sido diseñados para ser compilados en una máquina y posteriormente que el código ya ensamblado y paquetizado, se porte a otras diferentes y que en estas pueda ejecutarse sin problemas. Otros lenguajes más modernos como Java o la plataforma .Net de Microsoft se pseudocompilan en un lenguaje intermedio (IL) de modo que a pesar de no tener directamente el fichero ejecutable listo para portar, tengamos un paquete que puede ser ejecutado en la máquina de destino si tiene instaladas las herramientas de tiempo de ejecución de dicho lenguaje. Ambos escenarios tienen una ventaja común y es que el código, además de estar seguro en el contenedor (no puede verse si no es por medio de técnicas de ingeniería inversa), está optimizado y minimizado de manera que la aplicación utiliza el menor espacio posible y si dicha programación es correcta, utiliza los mínimos recursos necesarios de la máquina en la que se ejecuta. El escenario de JavaScript, sin embargo, es totalmente distinto. Aquí no disponemos de ninguna compilación del código, ni tan siquiera a un lenguaje intermedio. El código se transfiere directamente como si de contenido HTML se tratase y se puede ver fácilmente en el ordenador de destino con un par de clics de ratón. Asimismo, si incluimos comentarios o fragmentos de código que no utilizamos, deben ser igualmente transferidos al cliente, aunque nunca lleguen a ejecutarse, lo que hace especialmente peligroso este lenguaje de programación si no tenemos cuidado en disponer un código limpio y sin “basura”. U.D. IV – Web 2.0 70 Con el fin de mantener el tamaño del código al mínimo y mantener unos tiempos de descarga razonables, a continuación exponemos una serie de ideas o recomendaciones que deben seguirse al pie de la letra si queremos que nuestra aplicación funcione a la mayor velocidad posible. Esto que en principio puede parecernos poco relevante, toma mucha importancia cuando nuestra aplicación trabaje con varios ficheros de JavaScript y estos en su conjunto sumen varios cientos de líneas de código: 9 A menos que tengamos código dedicado para cada una de las páginas que vamos a utilizar, es conveniente colocar todo el código JavaScript en un mismo archivo y que este esté referenciado dentro de la página. Del mismo modo que las hojas de estilo en cascada, si extraemos todo el código, este sólo deberá descargarse una vez, con lo que preservaremos gran cantidad de ancho de banda y tráfico de servidor. 4.3.2_2 – Flujo de servidor en una página con todos los códigos incrustados 9 Deberemos extraer el código de nuestras páginas a ficheros JavaScript externos, evidentemente, pero deberíamos reducir también el número de archivos con fragmentos a incluir. Si tras hacer todas las divisiones de código entre páginas concluimos con que tenemos 20 archivos de JavaScript a incluir como referencia, algo indica que la cosa no está yendo del todo bien. Deberíamos plantearnos como referencia que hasta 5 archivos sería suficiente para casi cualquier aplicación. Si finalmente el número de archivos es elevado, deberíamos plantearnos fundir algunos entre sí para evitar el número de peticiones que se realizan al servidor. U.D. IV – Web 2.0 71 4.3.2_3 – Flujo de servidor en una página segmentada en varios archivos con JavaScript y CSS separados 9 En el caso de que utilicemos librerías, deberíamos utilizar las menos posibles ya que cada una tendrá su propio marco de trabajo para enviar órdenes al DOM. Si aplicamos varias librerías en la misma página, estaremos sobrecargándola de órdenes y código repetido que al final va a hacer la misma función. Utilizar una misma librería también tiene como ventaja que una actualización a una versión superior de la misma va a ser más sencilla y con menos problemas de intercompatibilidad entre funciones. 4.3.2_4 – jQuery, una de las mejores librerías de JavaScript del momento Muchas librerías se presentan en dos versiones de código: La completa con todos los comentarios del programador y el código explícito y una empaquetada y minimizada. Utiliza esta última cuando vayas a poner el código en producción, con la versión final de la aplicación. Mientras tanto, para poder depurarla mejor y localizar los diferentes errores que aparezcan, utiliza la versión estándar. Nos evitaremos quebraderos de cabeza y el código final será lo más limpio y ligero posible. U.D. IV – Web 2.0 72 Mantener las actualizaciones DOM al mínimo Evidentemente, si nuestra aplicación va a hacer algo que pueda considerarse importante, va a tener que modificar el DOM. No obstante hay que tener en cuenta que los cambios a realizar directamente en el DOM cuestan caros. Básicamente los navegadores de hoy en día tienen que realizar muchas operaciones para modificar la capa del DOM y es por esto que un sencillo cambio en el contenido de una página web es equivalente en ciclos de computación a otras tareas con un uso mucho más intensivo de CPU. Hay veces que incluso las llamadas que no hacen referencia al contenido de la página, sino al control de eventos son increíblemente lentas (con lentas nos referimos a milisegundos, claro…). Es por esto que hay que tener en cuenta estas particularidades y optimizar nuestra programación para que haga el mínimo número de cambios en el DOM: Imagina por un momento que tenemos una pequeña aplicación que va solicitando valores al usuario por medio de varios cuadros de texto y al final los muestra sumados como contenido de una etiqueta de tipo párrafo. Podríamos plantear el código JavaScript de dos maneras distintas: 9 9 Por un lado, podríamos colocar el valor del primer cuadro de texto como contenido dentro del párrafo y acumular sobre este todos los valores que se vayan solicitando. De este modo aprovecharíamos el elemento <p> como contenedor o variable que acumulará el sumatorio total. Otra solución pasaría por declarar una variable, ir acumulando sobre la misma los diferentes valores y finalmente acceder al elemento <p> e introducir en él el resultado de la operación. Aunque a simple vista parece más óptima la primera solución (se ahorra una variable y con ello memoria de ejecución), al navegador le va a costar más modificar el DOM en cada una de las sumas, por lo que nos quedaríamos con la segunda opción, que sería más rápida de ejecución. Hay que tener además especial cuidado en el uso de funciones o llamadas a document.all, ya que tiene que revisar todo el árbol de controles para devolvernos el que le solicitemos. Siempre va a ser más útil una llamada a document.getElementById(), ya que le indicaremos el elemento a obtener y nos evitaremos que el navegador tenga que revisar todo el DOM completamente para darnos el elemento solicitado. U.D. IV – Web 2.0 73 Cómo podemos minimizar nuestro código JavaScript Evidentemente el código JavaScript, al ser interpretado no nos va permitir la compilación del mismo, que nos permitiría reducir su tamaño considerablemente. En su lugar existen técnicas que aun sin poder compilar el código nos permiten reducir y de paso ofuscar nuestro código para que sea lo más pequeño posible y que a su vez no sea tan accesible para los usuarios, evitando la copia o modificación del mismo. Para realizar esta operación, el mejor recurso que podemos encontrar es el empaquetador de Dean Edwards. Dicho empaquetador se presenta como una página web en la que podemos escribir un código JavaScript y nos devuelve una versión paquetizada del mismo. 4.3.2_5 dean.edwards.name/packer/ un compresor de JavaScript Para acceder al mismo, deberemos introducir en nuestro navegador la siguiente dirección: http://dean.edwards.name/packer/ Una vez dentro, introduciremos en la primera de las ventanas que lo componen nuestro código JavaScript. Seleccionaremos las casillas “Base62 encode” y “Shrink variables” para maximizar su efecto de compresión. Al pulsar sobre el botón “Pack”, se ejecutará la compresión de nuestro código y en unos segundos, en la segunda ventana se nos mostrará la versión paquetizada y U.D. IV – Web 2.0 74 ofuscada del mismo, lista para que la insertemos en un archivo de JavaScript externo y que la adjuntemos a nuestra página. Como ejemplo de esta tecnología, vamos a procesar el siguiente código JavaScript y analizar sus resultados de compresión: // sample code var input, output; // notice the semi-colon at the END of function declarations onload = function() { input = document.getElementById("input"); output = document.getElementById("output"); clearAll(true); }; function packScript() { output.value = pack(input.value); }; function clearAll(focus) { output.value = input.value = ""; // the "if" statement is NOT terminated with a semi-colon if (focus) { input.focus(); } }; Al introducir este código y ejecutar la compresión, el resultado es el siguiente: eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c-)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('',2,0,''.split('|'),0,{})) Aunque a simple vista no lo parezca, el fragmento que aparece más arriba hace exactamente lo mismo que el anterior código. Está compuesto por la función de empaquetado y el código cifrado mediante dicha función, las variables ofuscadas y los comentarios y espacios eliminados. Como resultado podemos decir que, de un código original de 436 caracteres, nos hemos quedado con 254, esto es el 58,3% del tamaño original. Concluiremos entonces diciendo que es una buena práctica utilizar un compresor de JavaScript en nuestras aplicaciones, ya que minimiza el ancho de banda a utilizar, a U.D. IV – Web 2.0 75 la vez que protege nuestro código, pero dicha compresión debemos hacerla sólo cuando el código esté consolidado y sea estable, ya que realizar cambios una vez comprimido, como podemos ver en el fragmento del ejemplo, es tarea de locos. Lección 3 AJAX y Librerías Ajax es la tecnología base de las aplicaciones web 2.0. El significado de dicha palabra es Asynchronous JavaScript and XML y como su propio nombre indica va a basarse en el uso de llamadas asíncronas de JavaScript junto con un flujo de datos en XML para funcionar. Básicamente, la totalidad de tecnologías que conforman el Ajax están descritas en la siguiente relación: Objeto / Tecnología Uso XMLHttpRequest Es el objeto que va a utilizar el navegador para hacer las peticiones asíncronas por JavaScript XHTML y el DOM XHTML va a ser la representación de la página web que se va a mostrar y el DOM va a ser la API que utilizaremos para manipularla. JavaScript Lenguaje utilizado para hacer llamadas al XMLHttpRequest y procesar los resultados devueltos por el mismo XML El formato de fatos que se va a utilizar en el flujo del intercambio de datos cliente-servidor A pesar de que la tecnología Ajax en principio está pensada para que el intercambio de datos con el servidor sea en formato XML, podemos modificar esta directiva y utilizar el formato que consideremos más oportuno, como CSV, XHTML o incluso texto plano. Optimizar el flujo de datos está en nuestra mano. Si hacemos una llamada que devuelve un número entero desde el servidor, tal vez sería más oportuno utilizar el texto plano en lugar del XML… En este apartado, con el fin de seguir estándares y que lo que aprendamos lo podamos utilizar en escenarios más complejos, utilizaremos XML en las transferencias con el servidor. U.D. IV – Web 2.0 76 Mejorando la navegación y la interacción con el usuario AJAX supone una mejora del sistema de navegación y la velocidad de las respuestas hacia el usuario. Podríamos decir que mejora la experiencia del usuario ya que hace más breves los accesos al servidor y permite que de un modo más fluido para este se realicen las mismas labores. A continuación definiremos los pasos que se seguían con tecnologías web 1.0 para interactuar con el usuario: 1. El usuario hace una petición a una página, bien escribiendo su dirección en la barra del navegador, haciendo clic en un enlace o enviando los datos de un formulario 2. El servidor recibe la petición, procesa la página y la devuelve al cliente. Mientras tanto el navegador del cliente está “parado” esperando a recibir los datos a mostrar. 3. Se recibe la página, se le muestra al usuario y se espera a que este interactué de nuevo con algún control o enlace, volviendo en ese caso al punto 1 de nuevo Este proceso es muy simple y tiene sus ventajas, ya que la programación de este tipo de aplicaciones es más sencilla. Su problema está en el paso 2, ya que en este punto el usuario está esperando a que el servidor procese el contenido y no puede hacer nada mientras tanto salvo esperar a que se complete la respuesta. Esto en muchos casos es aceptable. Si estamos viendo un periódico online no va a haber ningún problema en esperar unos segundos desde que hacemos click en el nombre del artículo que queremos visitar hasta que lo podamos leer completamente. Ahora por un momento piensa qué pasaría en otro tipo de aplicaciones como, por ejemplo, Google Maps. El usuario hace zoom o selecciona una zona y el mapa se amplía suavemente. Si no fuera por el uso de la tecnología Ajax y Web 2.0, dicho mapa tendría que recargarse, el usuario debería esperar y una vez que se obtuviera la respuesta, el mapa debería redibujarse completamente antes de que permitiera realizar nuevas acciones al mismo. Por medio de la tecnología Ajax podemos hacer que el usuario pueda seguir viendo la página o trabajando sobre la misma mientras se envían y reciben datos al servidor en segundo plano. U.D. IV – Web 2.0 77 4.3.3_1 Esquema de funcionamiento clásico y con AJAX En el esquema que podemos ver, se comparan ambas tecnologías en paralelo. Por un lado, en el modelo clásico podemos ver lo reflejado al principio de este apartado: El interfaz del usuario dialoga directamente con el servidor web y de este modo por medio de peticiones y respuestas obtiene las páginas (HTML + CSS) directamente del mismo. En el modelo en Ajax, vemos que la interfaz del usuario (la página web) dispone de un pequeño motor Ajax, que no es más que una serie de funciones de JavaScript que se van a encargar de hacer peticiones al servidor para obtener respuestas en XML, que posteriormente procesarán y ubicarán en alguna zona de la página por medio de accesos al DOM. U.D. IV – Web 2.0 78 El objeto XMLHttpRequest Para definir el objeto XMLHttpRequest, vamos a tomar como referencia la definición de Wikipedia, que en su página http://es.wikipedia.org/wiki/XMLHttpRequest, define perfectamente el concepto del mismo: XMLHttpRequest (XHR), también referida como XMLHTTP (Extensible Markup Language / Hypertext Transfer Protocol), es una interfaz empleada para realizar peticiones HTTP y HTTPS a servidores Web. Para los datos transferidos se usa cualquier codificación basada en texto, incluyendo: texto plano, XML, JSON, HTML y codificaciones particulares específicas. La interfaz se presenta como una clase de la que una aplicación cliente puede generar tantas instancias como necesite para manejar el diálogo con el servidor. Este objeto fue desarrollado por Microsoft y lo implementó en la versión 5.0 de Internet Explorer en modo de objeto ActiveX, lo que viene a significar que puede utilizarse desde cualquier entorno que utilice esta tecnología, en este caso la práctica totalidad de entornos de desarrollo de Microsoft. Desde la versión 7 de Internet Explorer, dicha tecnología se ofrece directamente integrada en el navegador, por lo que no es necesario utilizar el objeto ActiveX nombrado anteriormente. De todos modos, como en otros navegadores dicha tecnología se implementa de otros modos, tendremos que tener en cuenta que la misma llamada asíncrona XML deberá ser invocada de modos distintos en función del agente del usuario o bien utilizar librerías que estandaricen dicha función. Desde el año 2004, XMLHttpRequest está soportado por la práctica totalidad de navegadores, aunque como comentamos, cada uno a su manera, por lo que tendremos que tener cuidado a la hora de invocarlo. El W3C presentó el 27 de septiembre de 2006 el primer borrador de una especificación estándar de la interfaz. Actualmente no hay una versión definitiva de la misma, pero el estado de borrador final hace que pensemos que la homogeneización de esta funcionalidad en los navegadores esté cerca. U.D. IV – Web 2.0 79 En las siguientes líneas tenemos un ejemplo de creación en JavaScript del objeto XMLHttpRequest salvando las diferencias entre los navegadores más comunes: var httpRequest; if (window.XMLHttpRequest) { //El explorador implementa la interfaz de forma nativa httpRequest = new XMLHttpRequest(); } else if (window.ActiveXObject) { //El explorador permite crear objetos ActiveX try { httpRequest = new ActiveXObject("MSXML2.XMLHTTP"); } catch (e) { try { httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } if (!httpRequest) { alert("No ha sido posible crear una instancia de XMLHttpRequest"); } Ejemplo de uso de la tecnología AJAX A continuación vamos a ver un ejemplo práctico del uso de tecnología Ajax. Crearemos una página con enlaces que carguen contenido externo, para ello dispondremos de una página principal de trabajo y dos más, que serán las que cargaremos dentro de la misma. Necesitaremos también un archivo de JavaScript, que contendrá todo el código de la aplicación Ajax. El documento principal HTML será como el que aparece a continuación: U.D. IV – Web 2.0 80 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"lang="es" xml:lang="es"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Tutorial de uso de AJAX</title> <script language="JavaScript" type="text/javascript" src="javascript.js"></script> <link href="estilos.css" rel="stylesheet" type="text/css"> </head> <body> <div id="menu"> <a href="javascript:llamarasincrono('documento1.htm', 'contenidos');">Cargar Documento 1</a> <a href="javascript:llamarasincrono('documento2.htm', 'contenidos');">Cargar Documento 2</a> </div> <div id="contenidos"> <h3>Aqui cargaremos el contenido de los documentos</h3> </div> </body> </html> Este documento lo guardaremos con el nombre ajax.html. Asimismo crearemos dos documentos adicionales en los que incluiremos código HTML tal y como aparecería dentro de la etiqueta <body>, es decir, sin cabeceras y sin etiquetas <head>, <html> o <body>. Una vez que los tengamos, los guardaremos con el nombre “documento1.htm” y “documento2.htm” respectivamente. Si no queremos complicarnos, podemos utilizar un código similar al que aparece a continuación: <h3>Título del contenido</h3> <p>Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. Contenido del parrafo1. </p> <p>Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. Contenido del parrafo2. </p> Para poder utilizar el objeto XMLHttpRequest tenemos que comprobar la disponibilidad del mismo en el navegador. Para ello seguiremos estas sencillas reglas: 9 En los navegadores basados en Mozilla, la referencia a utilizar es window.XMLHttpRequest. 9 En Internet Explorer tenemos que hacer uso de ActiveXObject, existiendo varias versiones denominadas Microsoft.XMLHTTP y Msxml2.XMLHTTP U.D. IV – Web 2.0 81 Crearemos entonces una función que compruebe mediante una sentencia condicional la creación de los objetos que hemos comentado. Al finalizar la misma podremos asegurarnos de que tenemos el objeto en modo totalmente funcional. Una vez que tengamos el objeto creado, dispondremos de diversos métodos y propiedades para comprobar el estado de los datos como las propiedades onreadystatechange, readyState, responseText, responseXML, status, statusText y los métodos abort(), getAllResponseHeaders(), getresponseHeader(string header), open(string url,string asynch), send(string), setHeader(string header,string value) Vamos a ver el ejemplo del código JavaScript resultante: // Documento JavaScript // Esta función cargará las paginas function llamarasincrono (url, id_contenedor) { var pagina_requerida = false; if (window.XMLHttpRequest) { // Si es Mozilla, Safari etc pagina_requerida = new XMLHttpRequest (); } else if (window.ActiveXObject) { // pero si es IE try { pagina_requerida = new ActiveXObject ("Msxml2.XMLHTTP"); } catch (e) { // en caso que sea una versión antigua try { pagina_requerida = new ActiveXObject ("Microsoft.XMLHTTP"); } catch (e) { } } } else return false; pagina_requerida.onreadystatechange = function () { // función de respuesta cargarpagina (pagina_requerida, id_contenedor); } pagina_requerida.open ('GET', url, true); // asignamos los métodos open y send pagina_requerida.send (null); } // todo es correcto y ha llegado el momento de poner la información requerida // en su sitio en la pagina xhtml function cargarpagina (pagina_requerida, id_contenedor) U.D. IV – Web 2.0 82 { if (pagina_requerida.readyState == 4 && (pagina_requerida.status == 200 || window.location.href.indexOf ("http") == - 1)) document.getElementById (id_contenedor).innerHTML = pagina_requerida.responseText; } Para finalizar y “vestir” nuestra aplicación, introduciremos las siguientes reglas de estilo en un archivo llamado estilos.css y lo ubicaremos en el mismo directorio que la aplicación: #menu{ float: left; width: 150px; height: 100px; border: 3px solid #ececff; padding: 7px; padding-left: 8px; border-right-color: #006; } #menu a{ padding: 3px 1px; display: block; width: 100%; text-decoration: none; font-weight: bold; border-bottom: 1px solid gray; } color: #606; #menu a:hover{ background-color: #99c; color: #fff; } body { background-color: #ececff; font-family: Geneva, Arial, Helvetica, sans-serif; } .titulos { color: #036; } #contenidos{ float:left; width:480px; min-height: 250px; border: 3px solid grey; margin-left: 10px; padding: 5px; padding-bottom: 8px; U.D. IV – Web 2.0 83 } background-color: #fff; Como ejercicio te proponemos que sigas los pasos del ejemplo y que crees tu primera aplicación web 2.0. Aunque no entiendas todos los pasos a la perfección, no te preocupes, más adelante iremos profundizando con otros ejemplos para que no te quede ninguna duda. U.D. IV – Web 2.0 84 Capítulo 4 Principios Básicos de Diseño A lo largo de este capítulo vamos a adentrarnos en la “pata” que nos falta para completar nuestra aplicación web 2.0. Durante el transcurso de las lecciones que hemos visto hasta ahora hemos aprendido a trabajar con páginas HTML, crear estilos en hojas CSS adjuntas de manera óptima para no cargar el servidor e incluso crear y optimizar el código JavaScript necesario para que dichas páginas cobren vida. Ahora bien, el ámbito de dichas páginas ahora mismo se queda en el ordenador del cliente. Podemos hacer operaciones con nuestros datos o los que nos proporciona el cliente, pero para que sean consideradas aplicaciones web 2.0, tenemos que “salir” a Internet y enviar y recibir datos desde un servidor externo. Para realizar esta tarea, vamos a hacer uso de los lenguajes de programación de servidor, en concreto PHP, que va a ser capaz de recibir los datos del cliente y devolver una respuesta en formato XML que podremos interpretar por medio de JavaScript en la página del cliente. Una vez que veamos las bases del lenguaje, veremos los diferentes dispositivos que nos vamos a encontrar en el camino y tomaremos unas leves nociones de accesibilidad para hacer que nuestra aplicación llegue al mayor número de gente posible. Al finalizar el estudio de estas lecciones serás capaz de: 9 Crear páginas dinámicas en lenguaje PHP 9 Acceder a una base de datos en un servidor y mostrar contenido de la misma de la manera más óptima posible 9 Conocer los diferentes dispositivos que se utilizan en Web 2.0 9 Utilizar los conceptos de accesibilidad, creando páginas que los navegadores adaptados podrán interpretar sin problemas U.D. IV – Web 2.0 85 Lección 1 Introducción a PHP PHP es un lenguaje de programación de lado de servidor. ¿Qué diferencias tiene con un lenguaje de programación "normal"? Para empezar a entender el concepto, vamos a referirnos a Wikipedia, que en su página http://es.wikipedia.org/wiki/Script_del_lado_del_servidor, nos define los lenguajes de programación de lado de servidor del siguiente modo: La programación del lado del servidor es una tecnología que consiste en el procesamiento de una petición de un usuario mediante la interpretación de un script en el servidor web para generar páginas HTML dinámicamente como respuesta Básicamente en el "saco" de los scripts de lado de servidor entrarían multitud de lenguajes de programación, como Perl, Python, CGI, Asp, ASP.Net... En nuestro caso vamos a estudiar el lenguaje PHP, uno de los más extendidos en parte por el gran soporte que se le da desde la comunidad y por supuesto por ser un lenguaje totalmente libre. Una vez más nos referiremos a Wikipedia, que en su página http://es.wikipedia.org/wiki/PHP nos define el lenguaje PHP del siguiente modo: PHP es un lenguaje de programación interpretado, diseñado originalmente para la creación de páginas web dinámicas. Es usado principalmente en interpretación del lado del servidor (server-side scripting) pero actualmente puede ser utilizado desde una interfaz de línea de comandos o en la creación de otros tipos de programas incluyendo aplicaciones con interfaz gráfica usando las bibliotecas Qt o GTK+. PHP es un acrónimo recursivo que significa PHP Hypertext Preprocessor (inicialmente PHP Tools, o, Personal Home Page Tools). Fue creado originalmente por Rasmus Lerdorf en 1994; sin embargo la implementación principal de PHP es producida ahora por The PHP Group y sirve como el estándar de facto para PHP al no haber una especificación formal. Publicado bajo la PHP License, la Free Software Foundation considera esta licencia como software libre. Actualmente PHP se encuentra en su versión 5 de desarrollo y la 6 verá la luz en breve con importantes mejoras. Entre las ventajas que tiene dicho lenguaje de programación, cabe destacar las siguientes: U.D. IV – Web 2.0 86 9 Es un lenguaje completamente multiplataforma 9 Está orientado al desarrollo de páginas web dinámicas con accesos a bases de datos 9 El código es invisible y está protegido del cliente, ya que se encuentra y ejecuta en el lado del servidor sin que en ningún momento se envíe por el canal de comunicación cliente-servidor 9 Capacidad de conectividad con bases de datos libres como mySQL 9 Es libre y trabaja con programación orientada a objetos 9 Dispone una biblioteca de funciones muy amplia y extendido 4.4.1_1 – Logotipo de PHP Por estas razones y muchas otras más que podríamos exponer, hemos elegido este lenguaje como punto de partida para la creación de la "parte de servidor" de nuestras aplicaciones Web 2.0. Vamos a empezar a conocerlo desde cero, como si lo fuéramos a utilizar para crear páginas dinámicas sencillas. Posteriormente esas páginas dinámicas las convertiremos en un flujo de datos XML que podremos interpretar por medio de AJAX y consumir en el navegador del cliente. Si deseas obtener más información sobre el lenguaje PHP, te animamos a que visites su web oficial, donde podrás encontrar mucha más información sobre la plataforma: http://php.net/ Aprendiendo a utilizar PHP Para comenzar, debemos fragmentos de PHP, ya que página, si bien no se van procesados en el servidor y del mismo. saber dónde y cómo debemos colocar nuestros estos deben ir incluidos junto al código HTML de la a enviar en ningún caso al cliente ya que serán este únicamente recibirá el resultado de la ejecución Para insertar un fragmento de PHP en un documento necesitaremos que se incluya dentro de las siguientes etiquetas: U.D. IV – Web 2.0 87 <? Código php ?> <?php Código php ?> <script language="php"> Código php </script> <% Código php %> Y para que el servidor identifique que se trata de una página que debe procesar antes de enviar al cliente, toda página que contenga código PHP deberá tener la extensión .php, por ejemplo index.php en lugar de index.htm 4.4.1_2 – Esquema de funcionamiento de PHP A continuación indicamos 4 normas básicas que debemos seguir al crear código PHP para evitar errores de ejecución: 9 Al igual que en javaScript, las sentencias deben terminar siempre con el carácter ";" 9 El contenido de funciones y estructuras de control (while, for, if, etc) debe encerrase entre { y } 9 Para indicar comentarios de texto, utilizaremos dos contrabarras "//" 9 Para mostrar mensajes en pantalle utilizaremos la funcion "echo('expresión')" o bien "print('expresión')" U.D. IV – Web 2.0 88 Variables en PHP En PHP disponemos de 5 tipos de variables a utilizar: 9 9 9 9 9 Números enteros Números de coma flotante Arrays Cadenas de caracteres Objetos Cualquier variable que se precie de tal en PHP deberá comenzar con el símbolo "$" y debe guardar relación entre mayusculas y minúsculas, ya que el lenguaje es "case sensitive". No es necesario declararlas, ya que se ajustan automáticamente al tipo que se le asigne y si en el futuro se le asigna un valor distinto, la variable cambiará junto con el tipo: En el siguiente fragmento de PHP asignaremos una cadena de caracteres a una variable y posteriormente modificaremos dicho valor, introduciendo un número entero. Finalmente mostraremos por pantalla el valor final de la variable: <? $ejemplo="Texto de la variable"; $ejemplo=3; echo $ejemplo; ?> PHP puede utilizar del mismo modo que JavaScript variables locales y globales, si bien, además de ajustar automáticamente el ámbito de las mismas en función de dónde estén descritas, nos permite definir los indicadores "global" y "static", que como su nombre indican, harán que una variable cambie su ámbito a variable global o a un tipo en el que el contenido no varía en sucesivas llamadas a la función. U.D. IV – Web 2.0 89 En el ejemplo que tenemos a continuación, la variable $valor irá acumulando el valor que se le asigne en cada llamada. De este modo por cada una de las llamadas que hagamos, se incrementará en 1 su valor almacenado. function incrementar () { static $valor; $valor++ echo $valor; echo "-"; } incrementar(); incrementar(); No podemos cambiar el ámbito de una variable cuando definimos el valor asociado a la misma, de este modo el ejemplo global $edad=25; sería incorrecto También disponemos del array $GLOBALS, que contiene los valores de las variables globales. Para acceder a dicho elemento, utilizaremos la sintaxis $GLOBALS[valor]; Vectores o Arrays Los vectores en PHP pueden contener datos de diferentes tipos. Los índices asociados pueden ser numéricos, de texto o incluso combinaciones de los mismos en arrays multidimensionales. En el caso de que utilicemos texto para identificar un vector, deberemos entrecomillarlo con comillas simples. U.D. IV – Web 2.0 90 En PHP declararíamos y mostraríamos un vector de la siguiente manera: <? $cliente['nombre']="Homer"; $cliente['apellido']="Simpson"; echo $cliente['nombre']; echo $cliente['apellido']; ?> Un vector multidimensional sin embargo, se construiría así: <? ?> $cliente[0]['nombre']="Homer "; $cliente[0]['apellido']="Simpson"; $cliente[1]['nombre']="Bart "; $cliente[1]['apellido']="Simpson"; echo echo echo echo echo $cliente[0]['nombre']; $cliente[0]['apellido']; "<br>"; $cliente[1]['nombre']; $cliente[1]['apellido']; Cadenas de caracteres En PHP tenemos dos modos de indicar cadena de caracteres, con comillas simples o dobles. En el caso de que utilicemos comillas simples, el uso es el mismo que en cualquier otro lenguaje de programación, pero si utilizamos comillas dobles, el contenido de las variables que indiquemos en la misma, van a ser procesados y expandidos en la misma. En este caso, si queremos colocar un literal '$valor', tendremos que especificarlo colocando una barra '\' antes del nombre de la variable. <? $valor=25; echo "El valor de la variable \$valor es $valor"; ?> Esto mostraría: El valor de la variable $valor es 25 U.D. IV – Web 2.0 91 Operadores PHP utiliza operadores muy similares a los que podemos encontrar en el lenguaje C. En la siguiente tabla se muestra una relación de las más utilizados ordenados por tipo: Declaración Aritméticos Asignación Bit Comparación Ejecución Incremento/Decremento Lógico Cadenas U.D. IV – Web 2.0 Significado suma resta producto (multiplicación) división resto de la división simple con operador and or xor not desp. izda. desp. dcha. igual menor menor o igual mayor mayor o igual distinto idéntico (valor y tipo, PHP 4) Ejecución preincremento predecremento posincremento posdecremento No Y O Xor Concatenación Ejemplo + * / % = op= & | ^ ~ <<nº >>nº == < <= > >= != === 'orden' ++$var --$var $var++ $var-! and o && or o || Xor . 92 Funciones En PHP podemos declarar funciones según la siguiente sintaxis: function nombre_funcion ($argumento, $argumento, $argumento, ...) { global $variables global global $variables global global $variables global ... $variables $variables $variables instrucciones return valor } Algunas consideraciones sobre las funciones: 9 Si no queremos devolver ningún valor en la función (convirtiéndola en este caso en un procedimiento), simplemente debemos omitir la línea "return valor". 9 Todas las variables que definamos en una función son variables locales salvo que indiquemos antes de las mismas el parámetro 'global', pasando a ser en este punto variables globales. La siguiente función devuelve la concatenación de una cadena de caracteres: <? { function concatenar ($a, $b) $cadenaCompleta = $a.$b; return $cadenaCompleta; } ?> Estructuras de control en PHP U.D. IV – Web 2.0 93 En PHP, como en todos los lenguajes de programación, disponemos de instrucciones que nos van a permitir modificar el flujo del programa principal realizando acciones condicionales o haciendo bucles sobre ciertas instrucciones. Vamos a ver las más comunes y cómo se utilizan: if - else - elseif Esta estructura nos va a permitir tomar decisiones dentro del programa. Su estructura sería la siguiente: if (condicion) { bloque instrucciones 1 } else { bloque instrucciones 2 } De este modo, si se cumple la condición, se ejecutará el bloque de instrucciones 1; en el caso contrario, será el bloque 2 el que se ejecutará en lugar del primero. En el bloque de instrucciones 2 colocamos una nueva estructura if - else, podemos "comprimir" la estructura del siguiente modo: if (condicion) { bloque instrucciones 1 } elseif { bloque instrucciones 2 } else { bloque instrucciones 3 } while La sentencia 'while' nos permite repetir un bloque de instrucciones mientras se cumpla la condición de control que especifiquemos. Su estructura es la siguiente: while (condicion) { bloque de instrucciones } U.D. IV – Web 2.0 94 El bucle while que tenemos a continuación se ejecutará hasta que la variable $total tome como valor el número 10: <?php $total = 0; while ($total < 10) { $total++; } ?> do - while La estructura do - while es muy similar al caso que acabamos de estudiar, si bien en esta variante, el conjunto de instrucciones que indiquemos se va a ejecutar por lo menos una vez y la condición se comprobará al final de la misma. Su estructura sería la siguiente: do { bloque de instrucciones } while (condicion) En el ejemplo del caso anterior: <?php $total = 0; do { $total++; } while ($total < 10) ?> for La estructura de bucle for nos permite repetir un conjunto de instrucciones durante un número de veces que definiremos previamente. Utilizaremos esta estructura cuando, de antemano, sepamos cuantas veces debemos repetir una instrucción o bloque de instrucciones. U.D. IV – Web 2.0 95 Su sintaxis: for ($variable=valor_inicial;$variable<límite;$variable++) { bloque de instrucciones } Este bucle se repetiría 10 veces antes de continuar con el resto de instrucciones: <?php for ($indice=0;$indice<10;$indice++) { echo ("El valor de la variable \$indice es $indice<br/>"); } ?> switch La estructura switch es una variación de las sentencias if - else - elseif y nos permite establecer un marco de selecciones previas a la ejecución de contenidos. De este modo podemos seleccionar una variable o condición y según el valor que esta toma, realizar unas instrucciones u otras. Su sintaxis es la siguiente: switch ($variable) { case valor1: bloque break; case valor2: bloque break; case valor3: bloque break; default: bloque break; } U.D. IV – Web 2.0 de instrucciones; de instrucciones; de instrucciones; de instrucciones; 96 En el siguiente ejemplo suponemos que tenemos una variable llamada $tiempo que toma los valores de 1 a 4 en función del estado meteorológico. Por medio de la estructura switch mostraremos por pantalla el estado del tiempo actual: <? switch ($tiempo) { case 1: echo "Soleado"; break; case 2: echo "Nublado"; break; case 3: echo "Lluvia"; break; case 4: echo "Viento"; break; }?> U.D. IV – Web 2.0 97 Lección 2 Acceso a Datos con PHP y MySQL En el capítulo anterior hemos aprendido a utilizar PHP como lenguaje de servidor, permitiéndonos crear contenido dinámico que es enviado al cliente directamente, de un modo protegido, ágil y rápido, pero... ¿Qué mejoras tiene esto (aparte de proteger el código) con respecto a JavaScript? 4.4.2_1 – MySQL, base de datos libre de código abierto La principal mejora que nos proporcionan los lenguajes de servidor es que nos permiten trabajar con bases de datos, permitiendo explotar dichos datos de manera remota y en tiempo real, además de muchas otras mejoras que pueden brindar a nuestro sitio web, entre las que podríamos poner como ejemplo: 9 Rotación de banners. Supongamos que tenemos un sitio en el que colocamos banners publicitarios. Si disponemos de una base de datos, podemos seleccionar uno distinto en cada una de las ejecuciones de la página para mostrar al visitante. También podemos contar el número de veces que el banner ha sido impreso y de este modo podríamos hacer hasta el seguimiento de los clicks en cada uno de ellos, reportando información al cliente. Para agregar, cambiar o editar los banners todo lo que tendríamos que hacer es cambiar la base de datos y el script colocará los banners correctamente en todas las páginas del sitio. 9 Foros. Cientos de foros (tablones de mensajes) en Internet se realizan usando PHP y MySQL. Este tipo de páginas son mucho más eficientes que otros sistemas de publicación y ofrecen una amplia variedad de opciones. Todas las páginas en el foro pueden ser actualizadas automáticamente por el cambio de una secuencia de comandos. 9 Sitios web. Si disponemos de un sitio web y queremos cambiar el diseño del mismo o los contenidos nos va a costar bastante si tenemos que ir una a una por todas las páginas del mismo. Con PHP y MySQL podríamos tener una página de plantilla y toda la información en base de datos, de modo que para generar el contenido se extraería la información desde la base de datos y se fundiría con la plantilla. De este modo, para modificar las páginas de contenido tan sólo deberíamos cambiar la plantilla y todo nuestro sitio se modificaría en consecuencia... En nuestro curso de desarrollo de aplicaciones Web 2.0 vamos a utilizar la base de datos MySQL, que del mismo modo que PHP, forma parte del denominado software libre. Ambos combinan a la perfección y PHP lleva ya incluidas de serie funciones de acceso a datos de este motor, así que será más que sencillo el uso y explotación del U.D. IV – Web 2.0 98 mismo. En las siguientes secciones vamos a ver cómo podemos crear y explotar una sencilla base de datos con el uso de PHP y MySQL. Aunque todas las tareas de administración de base de datos pueden hacerse directamente a través de scripts PHP, es aconsejable utilizar la administración de phpMyAdmin. La mayoría de los servicios de hosting que ofrecen MySQL como base de datos lo incluyen por defecto, ya que nos proporciona mucha libertad a la hora de administrar y crear contenido Crear una tabla en MySQL El primer paso a la hora de explotar datos y trabajar con bases de datos es la creación de una tabla. Una tabla es una parte de la base de datos preparada para almacenar información y en la que aparecerán una serie de campos que nosotros previamente definiremos. Cada tabla será distinta y almacenará una serie de datos relacionados, de este modo podemos tener una tabla de clientes, una de productos, otra de almacenes... cada una de ellas contendrá los datos necesarios para almacenar cada uno de los elementos para los que ha sido creada. Esto puede parecer un poco extraño visto así, pero con un ejemplo de creación de datos en MySQL lo vamos a ver bastante más claro: Crear una tabla en phpMyAdmin es sencillo, basta con escribir el nombre, seleccionar el número de campos que va a contener y hacer clic en el botón correspondiente. Tras hacer esto, se nos mostrará una pantalla de configuración donde deberemos crear y definir cada uno de los campos que va a contener dicha tabla. ¡Cuando hayamos finalizado esta edición ya tendremos nuestra tabla creada! U.D. IV – Web 2.0 99 4.4.2_2 y 4.4.2_3 – Interfaz de phpMyAdmin para la creación de una tabla U.D. IV – Web 2.0 100 MySQL nos proporciona diferentes tipos de datos para formatear los campos que creemos. Normalmente los nombres de cada uno de ellos son autoexplicativos, pero si quieres obtener más información sobre los mismos, puedes visitar la página oficial de referencia en la siguiente dirección: http://dev.mysql.com/doc/refman/5.1/en/datatypes.html Crea en MySQL una nueva tabla llamada "contactos" que utilizaremos posteriormente para almacenar información de personas. Contendrá los siguientes campos: 9 "id" de tipo "INT" y longitud "6" (identificador único para cada registro) 9 "nombre" de tipo "VARCHAR" y longitud 9 "apellidos" de tipo "VARCHAR" y longitud 15 9 "telefono" de tipo "VARCHAR" y longitud 20 9 "fax" de tipo "VARCHAR" y longitud 20 9 "email" de tipo "VARCHAR" y longitud 30 9 "web" de tipo "VARCHAR" y longitud 30 Al crear el campo "id", marca la casilla "AUTO_INCREMENT" y selecciona en "Índice" la opción "PRIMARY", de este modo nos aseguraremos de que los registros se indexan correctamente y de que toman valores correlativos Insertar datos desde PHP Ya hemos creado nuestra primera tabla con el uso del gestor phpMyAdmin, pero la "gracia" de todo esto es poder acceder desde PHP a los datos que contiene ahora mismo. En las siguientes líneas vamos a ver cómo podemos abrir la tabla y obtener los datos que contiene. El primer paso a la hora de explotar los datos de una o varias tablas es establecer una conexión con la base de datos con la que queremos trabajar. Este paso es verdaderamente importante, ya que si no estamos conectados a una base de datos, nuestras consultas y acciones no tendrán lugar y se nos devolverá un error de sistema. Es una buena práctica en el uso de bases de datos especificar el nombre de usuario, contraseña y nombre de la base de datos a acceder en la primera línea del código o en un fichero externo que gestione las conexiones, de modo que si cambiamos de hosting, usuario o base de datos, sólo deberemos modificar estos valores para poder volvernos a conectar a la misma: U.D. IV – Web 2.0 101 $usuario = "usuario"; $password = "contraseña"; $baseDatos = "nombre_de_base_de_datos"; A simple vista puede parecer un problema de seguridad el indicar los datos de acceso a la base de datos en el código de la aplicación, pero si recordamos, el código PHP no se envía al cliente en ningún momento. Un hipotético problema sería indicarlos en JavaScript (hipotético porque evidentemente no es capaz de trabajar con bases de datos y nunca los indicaremos) ya que el cliente podría acceder a los mismos, pero en PHP podemos respirar tranquilos, ya que el código está en lugar seguro en el disco duro del servidor. Una vez definidos el usuario y contraseña, ejecutaremos la orden que nos devolverá la conexión a base de datos, que en PHP se formularía de la siguiente manera: mysql_connect (localhost, $usuario, $ password); Hecho esto, consideraríamos la conexión abierta y procederíamos a trabajar con las distintas instrucciones de acceso a datos que nos brinda PHP. Una vez que hayamos finalizado, ejecutaremos la siguiente instrucción para cerrar la conexión que hemos utilizado: mysql_close (); Es importante cerrar las conexiones una vez utilizadas, por lo que todo acceso a base de datos que hagamos desde PHP debería acabar con dicha instrucción. Si nos dejamos conexiones abiertas es posible que en algún momento nuestra aplicación se ralentice o nos devuelva errores derivados de la imposibilidad de abrir más conexiones a datos, por lo que debemos poner mucho cuidado en el mantenimiento de conexiones a MySQL. Después de haber conectado al servidor de base de datos, debemos seleccionar la base de datos a utilizar. Debe ser una base de datos sobre la que tengamos permiso de acceso o de lo contrario recibiremos errores de acceso. @ mysql_select_db ($baseDatos) or die ("No se pudo seleccionar la base de datos"); Esta sentencia ejecutaría la preselección de base de datos y en el caso de que no la encontrara o no pudiera asociar la conexión a la misma, mostraría el mensaje de error que le indicamos. Llegado a este punto, con la conexión abierta y la base de datos seleccionada, podemos empezar a hacer consultas a la base de datos sin problema. Hay dos maneras de hacer consultas a MySQL y van a depender de si esperamos un valor como retorno o simplemente estamos ejecutando una función de inserción o borrado que no devuelve valor alguno. Si no esperamos valores de retorno, ejecutaremos la siguiente orden: mysql_query ($consulta); U.D. IV – Web 2.0 102 Siendo $consulta una variable en la que tendremos almacenada como cadena la consulta SQL a ejecutar. Vamos a ver esto como un ejemplo de inserción de datos desde PHP en nuestra tabla de contactos: Supongamos que queremos insertar un nuevo registro en nuestra tabla con los siguientes datos: Nombre: Homer Apellidos: Simpson Teléfono: 978 987 898 Fax: 987 382 432 Email: [email protected] Web: http://www.simpsons.com Para introducir esto en base de datos, desde PHP ejecutaríamos la siguiente sentencia: $sql = "INSERT INTO contactos VALUES ('',' Homer ',' Simpson ', 978 987 898', 987 382 432', ‘[email protected]’, ‘http://www.simpsons.com’)"; mysql_query ($sql); Como podemos ver en el ejemplo, para insertar datos en una tabla utilizaremos la sentencia INSERT INTO… VALUES y le indicaremos el nombre de tabla y los valores de los datos a anexar en dicha tabla. En la base de datos hemos definido el primero de los campos como autoincremental y es por esto que no indicamos el valor a incluir en dicho campo. El valor se generará automáticamente al insertar el registro y tomará un valor correlativo al último registro incluido. Leer datos desde PHP Acabamos de insertar un nuevo registro en nuestra tabla “contactos” y podemos repetir la operación tantas veces como sea necesario, bien escribiendo el valor de los campos directamente o tomándolo como respuesta a una petición del usuario. Ahora bien, si queremos hacer algo más que introducir datos en una tabla, necesitaremos conocer las instrucciones SQL de obtención de datos de la misma. Para obtener datos de una tabla utilizaremos la sentencia de SQL llamada “select”. Dicha sentencia tiene una sintaxis muy sencilla y responde al siguiente esquema: SELECT [campos a obtener o * si queremos todos] FROM [nombre de la tabla] WHERE [condicion] ORDER BY [campos] Adicionalmente podemos expresar condiciones para no obtener todos los registros o recibirlos con un orden específico, para ello utilizaremos la clausula WHERE y ORDER BY, que son de cumplimentación opcional y que veremos más adelante. U.D. IV – Web 2.0 103 En nuestro caso, para obtener todos los registros de la tabla de contactos, utilizaríamos la siguiente instrucción: SELECT * FROM contactos; Que introducida en el lenguaje PHP lista para ejecutar quedaría como aparece a continuación: $sql = "SELECT * FROM contactos"; $resultado = mysql_query ($sql); En este caso ejecutaremos la misma orden “mysql_query”, pero como va a devolvernos un valor, tenemos que asignar una variable para que almacene dicho valor (en este caso los registros de la tabla) y posteriormente podamos recorrerlos o realizar operaciones con ellos. Para poder continuar leyendo los registros, debemos saber el número de elementos del que disponemos. Para ello haremos uso de la orden mysql_numrows, que nos devolverá el número de registros que tenemos como resultado. $num = mysql_numrows ($resultado); Ahora que ya tenemos los registros y el número de ellos, podemos pasar a crear un bucle que recorra todos los elementos devueltos de modo que podamos procesarlos y, en este caso, mostrarlos por pantalla: for ($i=0; $i<$num; i++) { CÓDIGO } El único elemento que nos falta para completar el programa y conseguir mostrar los elementos por pantalla es el código necesario para, desde un registro de base de datos, extraer los valores correspondientes a cada uno de los campos a variables que podamos utilizar en nuestra representación en PHP. Esto lo haremos por medio de la función mysql_result, que tiene la siguiente sintaxis: $variable = mysql_result ($resultado, $i, "nombre de campo"); U.D. IV – Web 2.0 104 Uniendo todo lo visto hasta ahora, el código resultante que extraería todos los registros de la base de datos sería el siguiente: <?php $usuario = "usuario"; $password = "contraseña"; $baseDatos = "nombre_de_base_de_datos"; mysql_connect (localhost, $usuario, $password); @mysql_select_db ($baseDatos) or die ("No se pudo seleccionar la base de datos"); $sql = "SELECT * FROM contactos"; $resultado = mysql_query ($ consulta); $num = mysql_numrows ($result); mysql_close(); for ($i=0; $i<$num; i++) { $nombre = mysql_result ($resultado, $ i, "nombre"); $apellidos = mysql_result ($resultado, $ i, "apellidos"); $telefono= mysql_result ($resultado, $ i, "telefono"); $fax = mysql_result ($resultado, $ i, "fax"); $email = mysql_result ($resultado, $ i, "email"); $web = mysql_result ($resultado, $ i, "web"); echo "$nombre $apellidos, teléfono: $telefono, fax: $fax, e-Mail: $email, Web: $web"; } ?> Otras operaciones de acceso a datos: actualizar y eliminar Acabamos de insertar registros en la base de datos con éxito, asimismo los hemos mostrado por pantalla en un ejemplo sencillo. Las bases de datos permiten realizar multitud de operaciones con los registros que contienen las tablas, pero ahora mismo vamos a ver solamente un par de ellas que son necesarias para crear aplicaciones con funcionalidad completa: La operación de actualización de registros se ejecuta por medio de la sentencia “UPDATE”, que tiene el siguiente formato sintáctico: UPDATE [nombre_de_la_tabla] SET [campo]=[valor], [campo]=[valor], [campo]=[valor], [campo]=[valor]… WHERE [condicion] De este modo podemos cambiar el valor de uno o varios campos de base de datos, dejando el resto no afectados como si nunca se hubiera ejecutado ninguna actualización. Asimismo es necesario en este caso indicar una condición que describa los registros que van a ser afectados por el cambio, ya que si no informamos de ninguna, todos los registros de la tabla se cambiarán a los valores que indiquemos. U.D. IV – Web 2.0 105 Un ejemplo típico de actualización de registros de una tabla sería el del cambio del teléfono de uno de nuestros contactos. En primer lugar tendríamos el nuevo teléfono, que debemos actualizar, pero necesitaríamos una condición de modo que el registro estuviera completamente identificado y aislado. Para esta función está creado el primero de los campos de la tabla, el que definimos como “id” y es un autoincremental. Si localizamos el registro a modificar y en este verificamos el valor que el campo “id” ha tomado, podremos seleccionarlo inequívocamente en la función de actualización. Imagina por un momento que el usuario llamado “Homer Simpson” ha cambiado su teléfono. Si tras verificar la base de datos, sabemos que su valor “id” es 3, podríamos ejecutar la siguiente sentencia para actualizarlo: $sql = "UPDATE contactos SET telefono=’555 987 876’ WHERE id=3"; mysql_query ($sql); La otra función necesaria para “cerrar el círculo” de las bases de datos es la referente al borrado de los registros existentes. La orden en cuestión en este punto es DELETE y su sintaxis es la siguiente (muy parecida a UPDATE, por cierto): DELETE FROM [nombre_de_la_tabla] WHERE [condición] Una vez más es totalmente necesario el uso de la condición para seleccionar los registros afectados, ya que de otro modo la tabla completa será borrada para siempre. Ahora pongámonos en el caso de que deseemos eliminar a “Homer Simpson” de nuestra lista de contactos. Si tras verificar la base de datos, sabemos que su valor “id” es 3, podríamos ejecutar la siguiente sentencia para actualizarlo: $sql = "DELETE FROM contactos WHERE id=3"; mysql_query ($sql); U.D. IV – Web 2.0 106 Lección 3 Minimización de Tráfico Como hemos visto en lo que llevamos de curso, la tecnología AJAX nos va a permitir una comunicación más fluida con el usuario, ya que las peticiones al servidor (o por lo menos la mayor parte de las mismas) se van a realizar en segundo plano. 4.4.3_1 – AJAX, una tecnología my potente, aunque con un consumo elevado… Esto puede parecer perfecto, pero tiene un pequeño problema asociado, y es que aunque las peticiones se realicen en segundo plano, se siguen ejecutando y esto supone un consumo de ancho de banda que tenemos que considerar para no abusar del mismo, haciendo una aplicación que lejos de ser más rápida y ágil, hará que nuestros usuarios se desesperen con los tiempos de espera entre cargas. Actualmente un gran número de usuarios dispondrán de conexiones de banda ancha asociadas a una tarifa plana, por lo que el tráfico en sí puede no ser tan problema, pero ¿qué pasa con los usuarios móviles o con aquellos que siguen teniendo conexiones reducidas? Un gran número de usuarios en la actualidad se conectan a la red por medio de dispositivos móviles o módems inalámbricos, en los cuales el ancho de banda está limitado por la tarifa asociada a los mismos. U.D. IV – Web 2.0 107 4.4.3_2 – No podemos olvidarnos de los usuarios con dispositivos móviles Esto nos sugiere que si queremos que nuestra aplicación llegue al mayor número de usuarios posible, deberemos optimizarla para que el tráfico que genere esté lo más optimizado posible. Para ello disponemos de una serie de técnicas que enumeramos a continuación: 9 9 9 9 9 Hacer las peticiones y respuestas XML lo más concisas posibles Combinar múltiples peticiones en una sola Procesar en el servidor siempre que sea posible No abusar de peticiones AJAX si no es totalmente necesario Optimizar el número de registros enviados al cliente por medio de filtrados en el servidor Vamos ahora a ver una por una estas técnicas y explicarlas para que puedas entenderlas sin problemas. Hacer las peticiones y respuestas XML lo más concisas posibles Evidentemente, si conseguimos que nuestras peticiones y respuestas sean lo más concisas y breves posibles, estaremos minimizando el tráfico desde y hacia el servidor. El problema de todo esto es que XML es un lenguaje muy sencillo de utilizar, pero en ocasiones lleva más información de marcaje de etiquetas que de contenido en sí. Vamos a ver un ejemplo real de un fichero XML entendible por una máquina y un ser humano: U.D. IV – Web 2.0 108 <carroDeCompra> <idUsuario>1234567890</idUsuario> <elementos> <elemento> <idElemento>abc123</idElemento> <cantidad>1</cantidad> </elemento> <elemento> <idElemento>def456</idElemento> <cantidad>32</cantidad> </elemento> <elemento> <idElemento>ghi789</idElemento> <cantidad>20</cantidad> </elemento> </elementos> </carroDeCompra> La gran ventaja de la que dispone este fichero es que es entendible fácilmente por un programador o una máquina, pero tiene un tamaño demasiado grande para los datos que contiene. En concreto dicho archivo consumiría 344 Bytes de ancho de banda al enviarse o recibirse por medio de un canal. Acortando los nombres de las etiquetas podríamos reducirlo considerablemente a un formato similar a este: <c> <i>1234567890</i> <d> <e> <i>abc123</i> <c>1</c> </e> <e> <i>def456</i> <c>32</c> </e> <e> <i>ghi789</i> <c>20</c> </e> </d> </c> U.D. IV – Web 2.0 109 Este archivo nos proporcionaría la misma información, pero a un coste mucho menor de ancho de banda que el caso anterior, ya que de este modo solamente consumiríamos 150 Bytes en lugar de los 344 del ejemplo anterior. Esto supondría reducir el ancho de banda de transferencia a la mitad, con el consecuente aumento de velocidad en más de un 200% sobre nuestra aplicación. El problema que tendría sería que ya no es tan fácil de entender por un usuario, pero teniendo en cuenta que quien lo va a tener que interpretar es una máquina, no vamos a tener ninguna pega si esta está bien programada. Si queremos ir un paso más allá, XML nos permitiría comprimir aun más la respuesta, utilizando en este caso los atributos de los elementos. Por medio de esta técnica, el documento generado quedaría del siguiente modo: <c i=”1234567890”> <e i=”abc123” c=”1”/> <e i=”def456” c=”32”/> <e i=”ghi789” c=”20”/> </c> En este caso sería más complicado de entender por una persona, pero la máquina podría seguir entendiéndolo perfectamente. Además, esta versión ocuparía sólo 90 Bytes de ancho de banda, alcanzando una relación de mejora cercana al 400% con respecto al documento original. Para finalizar con la optimización, si además eliminamos los espacios del documento, tendríamos la siguiente cadena, perfectamente interpretable y comprimida al máximo: <c i=”1234567890”><e i=”abc123” c=”1”/><e i=”def456” c=”32”/><e i=”ghi789” c=”20”/></c> En este caso estaríamos utilizando 87 Bytes, alcanzando ya el máximo nivel de optimización sin pérdida alguna de información en el documento. Muchos programadores argumentan que el uso de nombres de elementos y atributos sencillos en XML es una técnica muy poco útil, ya que la mejora que permiten en cuanto al ahorro del ancho de banda no es nada comparable con la que se puede alcanzar con el uso de otro tipo de transferencias basadas en elementos binarios. El W3C está estudiando y estandarizando estos métodos y técnicas para conseguir el mayor nivel de rendimiento posible. U.D. IV – Web 2.0 110 Si quieres saber más sobre las optimizaciones en formato binario que están siendo propuestas y estudiadas por el W3C, puedes dirigirte a la siguiente página: http://www.w3.org/XML/Binary/ En cualquier caso, si lo consideramos oportuno y la optimización es un elemento crítico en nuestra aplicación, podemos plantearnos el uso de otros formatos de transferencia para comunicarnos con el servidor, como podría ser el texto plano o formatos propietarios que podamos diseñar. El uso de XML dentro del marco de trabajo de AJAX está recomendado únicamente por razones de compatibilidad entre aplicaciones. Combinar múltiples peticiones en una sola Combinar múltiples peticiones también puede ayudarnos a preservar ancho de banda en nuestras comunicaciones. En cada una de las peticiones que realizamos se incluyen bytes adicionales con metainformación de cabeceras y otros elementos de control necesarios para que dichas peticiones se ejecuten correctamente. Si conseguimos combinar varias peticiones en una sola, estaremos ahorrando bastante flujo de datos, ya que solo una cabecera será enviada en una petición que contendrá todos los datos necesarios. Supongamos que tenemos un formulario que el usuario debe rellenar. Si estamos corrigiendo la ortografía, podemos enviar al servidor lo escrito en el cuadro cada vez que el usuario introduzca un espacio. Esto va a generar una petición por cada una de las palabras que escribe. Si por el contrario esperamos al que el usuario abandone el cuadro de texto haciendo click fuera del mismo o pulsando la tecla del tabulador, enviaremos una única petición que contendrá todo el texto. Si en el cuadro de texto el usuario ha escrito 50 palabras, reduciremos a 1 el número total de peticiones, ahorrándonos 49 veces el ancho de banda que consumiría dicho control. U.D. IV – Web 2.0 111 Muchas veces por el uso de este método sacrificaremos algo de funcionalidad, pero el rendimiento se verá mejorado enormemente. Está en manos del programador localizar el punto medio entre funcionalidad y rendimiento para que nuestras aplicaciones dispongan de funcionalidades atractivas a la vez que preserven el ancho de banda disponible. Procesar en el servidor siempre que sea posible Procesar el código en el servidor es un método tradicional en contra de las tecnologías basadas en AJAX. El uso de nuevas tecnologías es posible teniendo en cuenta que los clientes donde se ejecutan los fragmentos de JavaScript son bastante potentes y pueden manejar los procesos sin mayor problema. Debemos tener en cuenta, no obstante, que algunos clientes como PDA's y otros dispositivos antiguos no son capaces de trabajar con algunas partes de AJAX y en consecuencia no sería posible trabajar con ellos en entornos web 2.0 Una tarea bastante común que suele ser realizada en el cliente es el procesado de una hoja de datos XML por medio de una hoja de transformación XSLT. Este proceso lo veremos más adelante, pero básicamente debemos entender que su finalidad es la combinación de dos documentos, uno que contiene datos puros (XML) y otro con las reglas que definen cómo se tienen que mostrar dichos elementos en la página (XSLT). Pues bien, los navegadores modernos tienen la capacidad de ejecutar este proceso de combinación ellos mismos, pero para esto necesitan obtener el documento XML y el XSLT por separado. Si previamente realizamos la combinación en el servidor, seguramente ahorraremos ancho de banda en mayor o menor medida, porque a pesar de que la página generada ocupará más que la suma de las hojas XML y XSLT, para enviarla será necesario realizar dos peticiones distintas y ejecutar la lógica de combinación en el cliente. Este método está recomendado para aumentar el rendimiento en dispositivos más lentos, ya que además de reducir el consumo de ancho de banda, evitamos que estos tengan que realizar procesos adicionales. U.D. IV – Web 2.0 112 No abusar de peticiones AJAX si no es totalmente necesario Evitar el uso de peticiones innecesarias es también una técnica recomendada para mejorar el uso del ancho de banda. Solamente por el hecho de que podamos realizar peticiones al servidor en segundo plano sin que el usuario se "entere", no es motivo para que tengamos que hacerlas indiscriminadamente. A continuación exponemos algunos ejemplos de por qué no debemos abusar de las peticiones XML: 9 Tráfico de red excesivo: Como hemos comentado con anterioridad, no todos los clientes van a disponer de una conexión de banda ancha sin límite de consumo, así que cuantas menos peticiones hagamos, menor ancho de banda consumiremos. 9 Demasiado flujo de información ralentiza la experiencia de usuario: Pongámonos en el ejemplo de un cuadro de texto predictivo, de modo que cuando comenzamos a introducir información se realizan peticiones para darnos pistas de las palabras completas que vamos a colocar. Este elemento es una gran ayuda en muchos casos, pero tampoco deberíamos incluirlo en todos los cuadros de texto que nos encontremos. Imagina por un momento que en un formulario de contacto lo colocamos para el campo "nombre", "apellidos", "dirección"... Ejecutaríamos demasiadas llamadas al servidor para sugerir al usuario opciones para ¿colocar su nombre? ¿Apellidos?... datos que de seguro sabe de antemano y que no va a seleccionar de ninguna lista que le coloquemos. 9 Eliminar la posibilidad de corrección de errores: En la mayoría de los formularios, la información se envía al servidor cuando se hace click sobre el botón creado a tal efecto. Si enviamos cada uno de los campos en el momento que son cumplimentados, además de generar un elevado número de peticiones, podemos malgastar ciclos de computación, ya que muchos usuarios revisan y corrigen los campos antes de hacer click en el botón de envío de formulario. Si los hemos enviado previamente, deberemos actualizar la base de datos en cada uno de los cambios que el usuario haga a los campos que ha introducido previamente. 9 Espiar al usuario: Si un formulario de acceso a una página o aplicación está enviando información continua cuando el usuario la escribe en un cuadro de texto, puede ser considerado spywware. Imagina por un momento que tenemos un cuadro de usuario y otro de contraseña. Podríamos programar peticiones para que en cada una de las pulsaciones de teclado se envié al servidor la información de dichos campos. Si el usuario no recuerda la contraseña y teclea varias antes de recordarla, podríamos almacenar dichos intentos y luego utilizarlos de forma fraudulenta junto con su login para entrar en otras páginas o servicios que el usuario tenga contratados, suplantando así su identidad. U.D. IV – Web 2.0 113 Optimizar el número de registros enviados al cliente Muchas veces podemos abusar del tráfico XML enviando un gran grupo de registros al cliente, que posteriormente deber ser filtrado en el mismo por medio de técnicas de JavaScript. Esto a veces supone una mejora en la funcionalidad, ya que los filtrados en cliente muestran los resultados muy rápido (si nuestro dispositivo tiene la suficiente capacidad de proceso, claro), pero otras veces es un problema cuando el número de registros enviados es muy elevado. Para resolver este problema podemos hacer uso de técnicas de selección de base de datos a la hora de extraer los registros de las tablas. Para ello realizaremos un par de ajustes cuando vayamos a ejecutar la clausula de acceso a datos "SELECT": 9 Evitaremos el uso de "SELECT *" y en su lugar indicaremos sólo los campos que necesitamos obtener 9 Utilizaremos la parte "WHERE" para definir el filtrado de datos que nos permitirá obtener sólo los registros que necesitemos. Si queremos obtener sólo el teléfono correspondiente a "Homer Simpson" de nuestra tabla de contactos, la clausula SELECT que deberíamos ejecutar sería la siguiente: SELECT telefono FROM contactos WHERE nombre = "Homer" and apellidos = "Simpson" De este modo obtendríamos únicamente el campo "telefono" del registro seleccionado, evitando procesar información adicional que descartaríamos en la presentación de la página y preservando una vez más el ancho de banda. U.D. IV – Web 2.0 114 Lección 4 Dispositivos La tecnología evoluciona día tras día, y cada vez son más los usuarios que navegan por la red utilizando dispositivos especiales. Teléfonos móviles, ordenadores de tipo netbook, pantallas de TV, videoconsolas… son solo uno ejemplos de los diferentes dispositivos que al fin y al cabo, por el hecho de tener acceso a la red y un navegador HTML, van ser usuarios potenciales de nuestras aplicaciones. Serán usuarios potenciales porque, hoy en día la mayor parte de los navegadores de los que disponen estos aparatos son compatibles con la tecnología JavaScript y junto a esta con el objeto XMLHttpRequest, corazón de la tecnología AJAX y Web 2.0 Dicho esto es humano pensar que dispondrán de mayor o menor velocidad de acceso a la red, memoria de procesamiento y otros factores que pueden determinar la velocidad de uso de nuestra aplicación, pero además dichos dispositivos tienen un hándicap muy importante, que es la resolución de pantalla sobre la que pueden mostrar el contenido. Los netbooks están dotados de pantallas de 1024x600 píxeles, por lo que no tendremos que realizar ninguna adaptación para que nuestra aplicación se muestre correctamente en estos aparatos. Los teléfonos móviles en el mejor de los casos tienen pantallas con resolución de 480x320 en formato vertical, por lo que si queremos que estos usuarios puedan acceder a nuestras aplicaciones tendremos que tener en cuenta este detalle… 4.4.4_1 – Algunos ejemplos de dispositivos móviles U.D. IV – Web 2.0 115 Si hemos sido audaces y hemos separado la capa de diseño totalmente de nuestra aplicación, podremos hacer uso de las hojas de estilo para crear una versión adaptada a estos dispositivos. Esta versión junto con un script de detección de agente será suficiente para crear una aplicación web 2.0 compatible con plataformas móviles. En las siguientes secciones vamos a ver como ejemplo cómo podemos adaptar una página web estándar a versión móvil, en concreto a la plataforma iPhone. Todo lo que veamos en este punto es perfectamente aplicable a cualquier desarrollo web 2.0, ya que están basados en la misma tecnología que las páginas web estándar. Definiendo los tipos de dispositivos Como hemos comentado con anterioridad, los dispositivos móviles tienen, en el mejor de los casos una resolución de 480x320 píxeles. Al decir en el mejor de los casos, tenemos que entender que habrá móviles “avanzados” que cumplan dicha característica, pero sin embargo otros no tendrán dicha resolución y por tanto, necesitarán versiones adaptadas para los mismos. 4.4.4_2 – No todos los dispositivos móviles poseen las mismas características Teniendo en cuenta los dispositivos que actualmente hay en el mercado, podemos hacer una división de los mismos por sus características en tres tipos diferentes: 1. Dispositivos con pantallas cuya anchura está entre 320 y 480 píxeles, que soportan hojas de estilo CSS y que permitan definir estas en función de la pantalla. En este grupo incluiremos el iPhone y otros móviles de última generación. Nos referiremos a este grupo como “grupo iPhone” y estos equipos permitirán utilizar todas las optimizaciones que diseñemos. 2. Dispositivos que soportan CSS en función de la pantalla con resoluciones menores de 320 píxeles de ancho. Deberemos crear hojas de estilo U.D. IV – Web 2.0 116 específicas para que estos aparatos puedan acceder al contenido con normalidad. 3. Dispositivos que no soporten CSS. Estos dispositivos renderizarán tan sólo el contenido HTML. No vamos a realizar optimizaciones especiales para estos, ya que si nuestra página contiene HTML o XHTML válido, por muchas hojas de estilo u optimizaciones que realicemos, el contenido se mostrará del mismo modo. Consideraciones de diseño Ahora llega el momento de que nos planteemos cómo será nuestra web adaptada a dispositivos móviles. Si pensamos que tenemos que introducir el mismo contenido que la habitual estaríamos incurriendo en un error, ya que la “gracia” que tienen este tipo de páginas es la agilidad a la hora de obtener la información y sobre todo el nivel de optimización de la misma para reducir los tiempos de carga y el consumo de ancho de banda. Supondremos entonces que tenemos una web con la siguiente topología: 4.4.4_3 – Esquema de la web y regiones que migraremos al formato móvil U.D. IV – Web 2.0 117 En el esquema que hemos definido, hemos marcado con borde rojo aquellas secciones que adaptaremos a la versión móvil y en gris las que vamos a excluir de la misma. La web adaptada quedaría entonces como aparece a continuación: 4.4.4_4 – Esquema de la web adaptada a dispositivo móvil Además de estos ajustes, el cuadro de información de contacto lo adaptaremos para que pueda utilizar funcionalidades específicas del iPhone, como que los usuarios puedan llamarnos pulsando sobre un botón o que accedan a su aplicación de GPS con los datos de nuestra ubicación para que puedan recibir información de ruta. U.D. IV – Web 2.0 118 Implementación Para introducir los cambios que hemos definido, el primer paso es definir la anchura de la ventana de navegación y que esta coincida con la del dispositivo en el que se va a visualizar. Para hacer esto, insertaremos la siguiente línea en nuestra plantilla de XHTML: <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" /> El siguiente paso es crear las hojas de estilo para cada uno de los diferentes dispositivos que van a visualizar la página. Para ello crearemos un nuevo archivo llamado movil.css, que contendrá los estilos de la página general para que se ajusten a una anchura de entre 320 y 480 píxeles. Podríamos definir no obstante una única hoja de estilo preparada para pantallas de 480 píxeles o menos y agrupar en uno los dos primeros grupos de dispositivos, pero la experiencia de usuario en estos últimos va a mejorar enormemente si creamos una versión específica para ellos. <link media="only screen and (max-device-width: 480px) and (min-device-width: 320px)" href="movil.css" type="text/css" rel="stylesheet" /> Sólo los dispositivos que permitan utilizar hojas de estilo específicas para cada visualización podrán interpretar esta referencia de estilos. Esto incluye el iPhone y otros dispositivos que forman el primer gran grupo. El siguiente paso a seguir es crear la hoja de estilo para los dispositivos del segundo grupo, los que interpretan hojas de estilo, permiten que estas se referencien selectivamente y posean resoluciones menores de 320 píxeles. Crearemos la versión de nuestra web correspondiente en el archivo movilSimple.css y lo referenciaremos del siguiente modo: <link media="handheld, only screen and (max-device-width: 319px)" href=" movilSimple.css" type="text/css" rel="stylesheet" /> U.D. IV – Web 2.0 119 Desarrollo del sitio Una vez que tenemos definidas las referencias a los archivos CSS de cada una de las versiones, es el momento de repasar todos los estilos de la web y generar dichas hojas de estilo. Básicamente contendrán cambios en las imágenes de fondo de las capas, cambios de flotación, anchura y comandos de visibilidad para ocultar aquellos bloques que hayamos decidido excluir de dicha visualización. Para finalizar y mejorar la experiencia de los usuarios de iPhone, añadiremos un fragmento de JavaScript que nos permitirá ocultar la barra de navegación mientras se carga el contenido de la página: <script type="application/x-javascript"> if (navigator.userAgent.indexOf('iPhone') != -1) { addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); } function hideURLbar() { window.scrollTo(0, 1); } </script> Pruebas y resolución de errores Para ejecutar la batería de pruebas necesaria para el correcto ajuste y visualización de la página, podemos recurrir a emuladores de iPhone o Android, que podemos encontrar en las siguientes direcciones: 9 http://developer.apple.com/iphone/ (Emulador de iPhone – requiere licencia) 9 http://code.google.com/android/ (Emulador de Android de Google) Si no queremos utilizar estos emuladores que requieren licencias y/o instalación, podemos acceder a la siguiente dirección y probar uno que el navegador Ópera nos brinda gratuitamente y que emula el navegador Opera Mini: 9 http://www.opera.com/mini/demo/ U.D. IV – Web 2.0 120 El producto final Tras toda la inserción de códigos y elementos, la sección <head> de nuestra página quedaría del siguiente modo: <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" /> <link media="Screen" href="style.css" type="text/css" rel="stylesheet" /> <link media="only screen and (max-device-width: 480px) and (min-device-width: 320px)" href="movil.css" type="text/css" rel="stylesheet" /> <link media="handheld, only screen and (max-device-width: 319px)" href="mobile_simple.css" type="text/css" rel="stylesheet" /> <script type="application/x-javascript"> if (navigator.userAgent.indexOf('iPhone') != -1) { addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); } function hideURLbar() { window.scrollTo(0, 1); } </script> Con esto nos aseguraremos de que nuestra web se visualiza correctamente, y lo que es más importante: no será una versión hecha específicamente para dispositivos móviles, sino que directamente transformaremos la web original en tiempo real al formato de los mismos, de modo que si actualizamos una sección o contenido que aparezca, instantáneamente será visible en la versión móvil. Al crear la versión para móviles de nuestra web cambiando sólo las hojas de estilo y ocultando bloques, nos beneficiamos de que ambas páginas comparten el mismo contenido, por lo que no habrá que hacer actualizaciones en paralelo. U.D. IV – Web 2.0 121 Contenido específico para iPhone Cuando hemos comenzado la migración de nuestra web, hemos propuesto la introducción de un cuadro específico para usuarios de iPhone. Por medio de dicho cuadro nos vamos a beneficiar de las propiedades de este dispositivo como teléfono y GPS, permitiendo de este modo por la pulsación de un botón el hacer una llamada o marcar en la aplicación de mapas del dispositivo la ubicación de nuestra ubicación. Para introducir esta funcionalidad, incluiremos este fragmento de código en el pie de la web: <div class="iphone"> <ul> <li id="iphone_llamar"> <a href="tel:976123456">Realizar una llamada</a> </li> <li id="iphone_mapa"> <a href="http://maps.google.com/maps?f=q&source=s_q&hl=en&geo code=&q=nombre+de+ubicacion&ie=UTF8&ll=0,0&spn=0,0&z=7&i wloc=A">Localízanos en el Mapa</a> </li> </ul> </div> Algunas consideraciones sobre este código: 9 Todo el código se encuentra localizado en una capa que pertenece a la clase “iphone”. Como disponemos de varias hojas de estilo para cada versión de la web, podemos ocultar esta capa en la versión estándar para ordenadores y mostrarla sólo cuando utilicemos la hoja de estilo móvil.css 9 Para realizar una llamada en el iPhone, utilizaremos el enlace “tel:numero_de_telefono”. Esto nos permite que el dispositivo entre en modo teléfono y automáticamente realice una llamada al número que le indiquemos. 9 En enlace al mapa está formulado de modo que es totalmente transparente entre dispositivos. Si lo abrimos desde un PC nos llevará a Google Maps y nos marcará la ubicación del elemento. Si hacemos click sobre el mismo desde el iPhone, será la aplicación de mapas incluida la que se abrirá y nos mostrará los detalles del punto seleccionado. U.D. IV – Web 2.0 122 Lección 5 Accesibilidad Para comenzar a hablar sobre la accesibilidad web debemos primero definir el concepto que vamos a tratar en las siguientes páginas. Para ello, haremos uso una vez más de Wikipedia, que en su página http://es.wikipedia.org/wiki/Accesibilidad_web nos define la Accesibilidad Web de la siguiente manera: La accesibilidad web se refiere a la capacidad de acceso a la Web y a sus contenidos por todas las personas independientemente de la discapacidad (física, intelectual o técnica) que presenten o de las que se deriven del contexto de uso (tecnológicas o ambientales). Esta cualidad está íntimamente relacionada con la usabilidad. Asimismo y en un lenguaje más coloquial y entendible, continúa: Cuando los sitios web están diseñados pensando en la accesibilidad, todos los usuarios pueden acceder en condiciones de igualdad a los contenidos. Por ejemplo, cuando un sitio tiene un código XHTML semánticamente correcto, se proporciona un texto equivalente alternativo a las imágenes y a los enlaces se les da un nombre significativo, esto permite a los usuarios ciegos utilizar lectores de pantalla o líneas Braille para acceder a los contenidos. Cuando los vídeos disponen de subtítulos, los usuarios con dificultades auditivas podrán entenderlos plenamente. Si los contenidos están escritos en un lenguaje sencillo e ilustrados con diagramas y animaciones, los usuarios con dislexia o problemas de aprendizaje están en mejores condiciones de entenderlos. De este modo, vemos que es muy importante si queremos llegar al mayor número de personas el que nuestra aplicación esté optimizada a este respecto. La accesibilidad es un concepto tabú para muchos diseñadores web, ya que creen que si una web es accesible no pueden utilizar nada de diseño en la misma, pero esto es un completo error, ya que si desde un principio formamos nuestro código adecuadamente y tomamos alternativas accesibles al uso de ciertos objetos, con muy poco esfuerzo adicional conseguiremos una web perfectamente accesible a mucho más público del que en un principio estaría destinada. U.D. IV – Web 2.0 123 Guías generales de accesibilidad Para que nuestras páginas sean accesibles hay varios elementos o reglas que deberían cumplir. Más adelante nos adentraremos en los estándares que una vez más nos vienen de la mano del W3C, pero antes de ver estandarizaciones, prioridades y requerimientos técnicos, vamos a indicar unas pautas sencillas de accesibilidad. 4.4.5_1 –“Accesibilidad en la Web” un interesante blog sobre accesibilidad U.D. IV – Web 2.0 124 4.4.5_2 –Ejemplo de web con funciones interesantes para discapacitados (columna derecha) Si nuestra aplicación cumple estas 9 pautas, a buen seguro que también cumplirá el 80% de las especificaciones "estandarizadas" que veremos más adelante: 9 Imágenes y animaciones: En cada una de las imágenes que coloquemos en nuestra aplicación colocaremos el atributo "alt", de modo que los navegadores que no son capaces de visualizarlas pueden mostrar el texto que indique el contenido de las mismas. 9 Mapas de imagen: Del mismo modo que en las imágenes estándar, si utilizamos imágenes "mapeadas", definiremos el atributo "alt" en cada una de sus zonas, indicando el contenido de las mismas. 9 Multimedia: En el caso de la inserción de elementos multimedia, insertaremos subtítulos y descripciones de los mismos. 9 Enlaces de hipertexto: En los enlaces es una buena práctica incluir textos descriptivos, de modo que evitaremos los enlaces del tipo "click aquí" y en su lugar colocaremos el correspondiente "haga click para descargar el archivo 'Documento de especificaciones.doc'" 9 Organización de las páginas: Otra buena práctica es utilizar los elementos HTML para lo que han sido creados. Deberemos utilizar correctamente los encabezados y listas para que se correspondan con títulos y listas reales de la página. Utilizaremos asimismo toda la potencia de CSS para separar la capa de diseño de la de datos. 9 Figuras y diagramas: Cuando los coloquemos, los definiremos en la página o mediante el atributo "longdesc" 9 Scripts, applets y plug-ins: Como los navegadores adaptados no van a ser capaces de procesarlos correctamente, debemos ofrecer contenido U.D. IV – Web 2.0 125 alternativo que sí pueda ser procesado. Por ejemplo, si tenemos una galería de imágenes con animación, para la versión accesible ofreceremos una imagen fija. de este modo, si el navegador no puede mostrar animaciones, siempre podrá ofrecer al usuario una imagen con el contenido fijo. Si tampoco es capaz de mostrarla y hemos definido un texto alternativo a la misma, no habrá ningún problema en informar al usuario del mismo. 9 Marcos: Si es posible evitaremos el uso de marcos en nuestra página, y en el caso de tener que utilizarlos obligatoriamente, definiremos correctamente los nombres y descripciones de los mismos 9 Tablas: Evitaremos el uso de tablas para disponer su contenido y en su lugar trabajaremos con capas CSS para la maquetación. Las tablas solo las colocaremos en nuestro HTML cuando tengamos que definir relaciones de datos WCAG – Web Content Accesibility Guidelines Evidentemente, cumpliendo los consejos que hemos visto en secciones anteriores, nuestra aplicación podrá ser utilizada por un grupo de usuarios en el que podríamos incluir personas con discapacidad, pero ¿qué normas debemos seguir para que nuestras páginas puedan considerarse "certificadas" en accesibilidad? El W3C a través de las denominadas Web Content Accesibility Guidelines, nos propone una vez más un grupo de directivas o pautas a seguir que nos permitirán asegurarnos de que nuestra página web o aplicación cumple un determinado grado de adaptación a personas con discapacidad. 4.4.5_3 – Icono de conformidad con el nivel “Doble A” del WCAG La función principal de estas guías de accesibilidad para el contenido web es enfocar el diseño de las páginas y aplicaciones web a un punto sostenible y accesible para el mayor número de personas. Técnicamente la especificación WCAG consiste en 14 pautas que debemos seguir para considerar nuestro diseño de aplicación como accesible. Asimismo, dichas pautas establecen soluciones y consejos a seguir para cumplirlas. Cada una de estas pautas está subdividida en tres puntos o niveles de prioridad que describimos a continuación: 9 Prioridad 1: Son aquellos puntos que un desarrollador Web tiene que cumplir ya que, de otra manera, ciertos grupos de usuarios no podrían acceder a la información del sitio Web. 9 Prioridad 2: Son aquellos puntos que un desarrollador Web debería cumplir ya que, si no fuese así, sería muy difícil acceder a la información para ciertos grupos de usuarios. 9 Prioridad 3: Son aquellos puntos que un desarrollador Web debería cumplir ya que, de otra forma, algunos usuarios experimentarían ciertas dificultades para acceder a la información. U.D. IV – Web 2.0 126 En función de estos puntos de verificación se establecen los tres niveles de conformidad o certificación: 9 Nivel de Conformidad "A": todos los puntos de verificación de prioridad 1 se satisfacen. 9 Nivel de Conformidad "Doble A": todos los puntos de verificación de prioridad 1 y 2 se satisfacen. 9 Nivel de Conformidad "Triple A": todos los puntos de verificación de prioridad 1,2 y 3 se satisfacen. Vamos a especificar ahora las pautas o requisitos que nuestra aplicación debería cumplir para obtener los niveles de conformidad "A", "Doble A" u "Triple A" respectivamente. En las siguientes páginas encontrarás el listado oficial de pautas de accesibilidad de las especificaciones WCAG ordenadas por prioridad. Al ordenarlas por prioridad obtendremos un checklist muy valioso, ya que podremos aplicarlo por separado a la hora de preparar una aplicación para que tenga un determinado nivel de cumplimiento. Las normas que recogemos a continuación están extraídas directamente de las especificaciones WCAG, disponibles en la página: http://www.w3.org/TR/WCAG/ Hemos utilizado una notación de modo que el primer número de referencia indicará el identificador de la pauta a la que está referenciada, y el segundo el orden de dicha recomendación dentro de la pauta original. Puntos de verificación Prioridad 1 – Nivel de conformidad “A” 1.1 Proporcione un texto equivalente para todo elemento no textual (Por ejemplo, a través de "alt", "longdesc" o en el contenido del elemento). Esto incluye: imágenes, representaciones gráficas del texto, mapas de imagen, animaciones (Por ejemplo, GIFs animados), "applets" y objetos programados, "ascii art", marcos, scripts, imágenes usadas como viñetas en las listas, espaciadores, botones gráficos, sonidos (ejecutados con o sin interacción del usuario), archivos exclusivamente auditivos, banda sonora del vídeo y vídeos. 2.1 Asegúrese de que toda la información transmitida a través de los colores también esté disponible sin color, por ejemplo mediante el contexto o por marcadores. 4.1 Identifique claramente los cambios en el idioma del texto del documento y en cualquier texto equivalente (por ejemplo, leyendas). 6.1 Organice el documento de forma que pueda ser leído sin hoja de estilo. Por ejemplo, cuando un documento HTML es interpretado sin asociarlo a una hoja de estilo, tiene que ser posible leerlo. U.D. IV – Web 2.0 127 6.2 Asegúrese de que los equivalentes de un contenido dinámico son actualizados cuando cambia el contenido dinámico. 7.1 Hasta que las aplicaciones de usuario permitan controlarlo, evite provocar destellos en la pantalla. 14.1 Utilice el lenguaje apropiado más claro y simple para el contenido de un sitio. Y si utiliza imágenes y mapas de imagen (Prioridad 1) 1.2 Proporcione vínculos redundantes en formato texto para cada zona activa de un mapa de imagen del servidor. 9.1 Proporcione mapas de imagen controlados por el cliente en lugar de por el servidor, excepto donde las zonas sensibles no puedan ser definidas con una forma geométrica. Si se utilizan tablas: 5.1 En las tablas de datos, identifique los encabezamientos de fila y columna. 5.2 Para las tablas de datos que tienen dos o más niveles lógicos de encabezamientos de fila o columna, utilice marcadores para asociar las celdas de encabezamiento y las celdas de datos. Si se utilizan marcos: 12.1 Titule cada marco para facilitar su identificación y navegación. Si se utilizan "applets" y "scripts" 6.3 Asegure que las páginas sigan siendo utilizables cuando se desconecten o no se soporten los scripts, applets u otros objetos programados. Si esto no es posible, proporcione información equivalente en una página alternativa accesible. En casos de multimedia: 1.3 Hasta que las aplicaciones de usuario puedan leer en voz alta automáticamente el texto equivalente de la banda visual, proporcione una descripción auditiva de la información importante de la banda visual de una presentación multimedia. 1.4 Para toda presentación multimedia tempodependiente (por ejemplo, una película o animación) sincronice alternativas equivalentes (por ejemplo, subtítulos o descripciones de la banda visual) con la presentación. Si no es posible cumplir las normas indicadas... 11.4 Si, después de los mayores esfuerzos, no puede crear una página accesible, proporcione un vínculo a una página alternativa que use tecnologías W3C, sea accesible, tenga información (o funcionalidad) equivalente y sea actualizada tan a menudo como la página (original) inaccesible. U.D. IV – Web 2.0 128 Puntos de verificación Prioridad 2 – Nivel de conformidad “Doble A” 2.2 Asegúrese de que las combinaciones de los colores de fondo y primer plano tengan el suficiente contraste para que sean percibidas por personas con deficiencias de percepción de color o en pantallas en blanco y negro [Prioridad 2 para las imágenes. Prioridad 3 para los textos]. 3.1 Cuando exista un marcador apropiado, use marcadores en vez de imágenes para transmitir la información. 3.2 Cree documentos que estén validados por las gramáticas formales publicadas. 3.3 Utilice hojas de estilo para controlar la maquetación y la presentación. 3.4 Utilice unidades relativas en lugar de absolutas al especificar los valores en los atributos de los marcadores de lenguaje y en los valores de las propiedades de las hojas de estilo. 3.5 Utilice elementos de encabezado para transmitir la estructura lógica y utilícelos de acuerdo con la especificación. 3.6 Marque correctamente las listas y los ítems de las listas. 3.7 Marque las citas. No utilice el marcador de citas para efectos de formato tales como sangrías. 6.5 Asegúrese de que los contenidos dinámicos son accesibles o proporcione una página o presentación alternativa. 7.2 Hasta que las aplicaciones de usuario permitan controlarlo, evite el parpadeo del contenido (por ejemplo, cambio de presentación en periodos regulares, así como el encendido y apagado). 7.4 Hasta que las aplicaciones de usuario proporcionen la posibilidad de detener las actualizaciones, no cree páginas que se actualicen automáticamente de forma periódica. 7.5 Hasta que las aplicaciones de usuario proporcionen la posibilidad de detener el redireccionamiento automático, no utilice marcadores para redirigir las páginas automáticamente. En su lugar, configure el servidor para que ejecute esta posibilidad. 10.1 Hasta que las aplicaciones de usuario permitan desconectar la apertura de nuevas ventanas, no provoque apariciones repentinas de nuevas ventanas y no cambie la ventana actual sin informar al usuario. 11.1 Utilice tecnologías W3C cuando estén disponibles y sean apropiadas para la tarea y use las últimas versiones que sean soportadas. U.D. IV – Web 2.0 129 11.2 Evite características desaconsejadas por las tecnologías W3C. 12.3 Divida los bloques largos de información en grupos más manejables cuando sea natural y apropiado. 13.1 Identifique claramente el objetivo de cada vínculo. 13.2 Proporcione metadatos para añadir información semántica a las páginas y sitios. 13.3 Proporcione información sobre la maquetación general de un sitio (por ejemplo, mapa del sitio o tabla de contenidos). 13.4 Utilice los mecanismos de navegación de forma coherente. Si se utilizan tablas: 5.3 No utilice tablas para maquetar, a menos que la tabla tenga sentido cuando se alinee. Por otro lado, si la tabla no tiene sentido, proporcione una alternativa equivalente (la cual debe ser una versión alineada). 5.4 Si se utiliza una tabla para maquetar, no utilice marcadores estructurales para realizar un efecto visual de formato. Si se utilizan marcos: 12.2 Describa el propósito de los marcos y cómo éstos se relacionan entre sí, si no resulta obvio solamente con el título del marco. Si se utilizan formularios: 10.2 Hasta que las aplicaciones de usuario soporten explícitamente la asociación entre control de formulario y etiqueta, para todos los controles de formularios con etiquetas asociadas implícitamente, asegúrese de que la etiqueta está colocada adecuadamente. 12.4 Asocie explícitamente las etiquetas con sus controles. Si se utilizan "applets" y "scripts" 6.4 Para los scripts y applets, asegúrese de que los manejadores de eventos sean independientes del dispositivo de entrada. 7.3 Hasta que las aplicaciones de usuario permitan congelar el movimiento de los contenidos, evite los movimientos en las páginas. 8.1 Haga los elementos de programación, tales como scripts y applets, directamente accesibles o compatibles con las ayudas técnicas [Prioridad 1 si la funcionalidad es importante y no se presenta en otro lugar; de otra manera, Prioridad 2]. U.D. IV – Web 2.0 130 9.2 Asegúrese de que cualquier elemento que tiene su propia interfaz pueda manejarse de forma independiente del dispositivo. 9.3 Para los "scripts", especifique manejadores de evento lógicos mejor que manejadores de evento dependientes de dispositivos. Puntos de verificación Prioridad 3 – Nivel de conformidad “Triple A” 4.2 Especifique la expansión de cada abreviatura o acrónimo cuando aparezcan por primera vez en el documento. 4.3 Identifique el idioma principal de un documento. 9.4 Cree un orden lógico para navegar con el tabulador a través de vínculos, controles de formulario y objetos. 9.5 Proporcione atajos de teclado para los vínculos más importantes (incluidos los de los mapas de imagen de cliente), los controles de formulario y los grupos de controles de formulario. 10.5 Hasta que las aplicaciones de usuario (incluidas las ayudas técnicas) interpreten claramente los vínculos contiguos, incluya caracteres imprimibles (rodeados de espacios), que no sirvan como vínculo, entre los vínculos contiguos. 11.3 Proporcione la información de modo que los usuarios puedan recibir los documentos según sus preferencias (por ejemplo, idioma, tipo de contenido, etc.). 13.5 Proporcione barras de navegación para destacar y dar acceso al mecanismo de navegación. 13.6 Agrupe los vínculos relacionados, identifique el grupo (para las aplicaciones de usuario) y, hasta que las aplicaciones de usuario lo hagan, proporcione una manera de evitar el grupo. 13.7 Si proporciona funciones de búsqueda, permita diferentes tipos de búsquedas para diversos niveles de habilidad y preferencias. 13.8 Localice la información destacada al principio de los encabezamientos, párrafos, listas, etc. 13.9 Proporcione información sobre las colecciones de documentos (por ejemplo, los documentos que comprendan múltiples páginas). 13.10 Proporcione un medio para saltar sobre un ASCII art de varias líneas. 14.2 Complemente el texto con presentaciones gráficas o auditivas cuando ello facilite la comprensión de la página. 14.3 Cree un estilo de presentación que sea coherente para todas las páginas. U.D. IV – Web 2.0 131 Y si utiliza imágenes o mapas de imagen (Prioridad 3) 1.5 Hasta que las aplicaciones de usuario interpreten el texto equivalente para los vínculos de los mapas de imagen de cliente, proporcione vínculos de texto redundantes para cada zona activa del mapa de imagen de cliente. Si se utilizan tablas: 5.5 Proporcione resúmenes de las tablas. 5.6 Proporcione abreviaturas para las etiquetas de encabezamiento. 10.3 Hasta que las aplicaciones de usuario (incluidas las ayudas técnicas) interpreten correctamente los textos contiguos, proporcione un texto lineal alternativo (en la página actual o en alguna otra) para todas las tablas que maquetan texto en paralelo, en columnas de palabras. Si se utilizan formularios: 10.4 Hasta que las aplicaciones de usuario manejen correctamente los controles vacíos, incluya caracteres por defecto en los cuadros de edición y áreas de texto. Si hemos observado las normas que se nos proponen, podemos concluir que si nuestra aplicación respeta todo lo que hemos visto en lo que llevamos de curso (correcto formato de etiquetas HTML, uso de hojas de estilo en cascada, validación de código...), cumpliríamos la mayoría de las pautas que se proponen para conseguir la categoría "A". Con un poco de esfuerzo y cuidado a la hora de presentar los contenidos, podríamos llegar al nivel "Doble A" sacrificando alguna pequeña funcionalidad. Para llegar al nivel "Triple A" deberemos mermar en exceso el diseño y la funcionalidad de la aplicación, así que de no ser que sea un requerimiento específico de nuestra aplicación y que lo tengamos en cuenta desde el principio, no deberíamos pretender llegar hasta este nivel de cumplimiento, ya que es demasiado "caro" de conseguir. La mayoría de páginas y aplicaciones que podemos ver por la red ni tan siquiera cumplen el nivel de accesibilidad "A" plenamente. Si preparamos nuestra página teniendo en cuenta las reglas que hemos visto, podemos implantar el nivel "A" e incluso el "Doble A" sin demasiado esfuerzo. U.D. IV – Web 2.0 132 Validación de contenido accesible Una vez que tengamos finalizada nuestra página o aplicación, deberíamos verificarla y validarla por medio de herramientas creadas a tal efecto. Hay muchos parámetros de la accesibilidad que no pueden ser comprobados por validadores automatizados, como por ejemplo el contraste de texto con el fondo o la claridad y simplicidad del diseño, pero para todo lo demás podemos hacer uso de las páginas que encontraremos en las siguientes direcciones: 9 9 9 9 9 http://www.accesible.com.ar/examinator http://www.tawdis.net http://wave.webaim.org http://www.ocawa.com/en/Test-your-web-site.htm http://www.smartlabsoftware.com/wai-validator.htm Por medio del uso de estos validadores, recibiremos una puntuación y una serie de recomendaciones a seguir para hacer de nuestra página o aplicación un producto lo más accesible posible. En cualquier caso y como hemos indicado anteriormente, muchas veces el desarrollador se centra en conseguir un nivel determinado de accesibilidad sin importarle el recorte de funcionalidad que esto puede llegar a suponer. 4.4.5_4 – eXaminator, un interesante validador de accesibilidad U.D. IV – Web 2.0 133 La implementación de debe plantearse desde comience a escribirse. de recortes, ya que accesibles. accesibilidad en una página o programa es una tarea que un principio, antes incluso que el código fuente de la misma Si lo hemos hecho de este modo, no tendremos problemas desde un principio habremos pensado en tecnologías 4.4.5_5 – t.a.w., otro buen ejemplo de validador de accesibilidad Si tenemos que eliminar demasiadas funcionalidades para que nuestra página o aplicación se valide contra un determinado nivel de accesibilidad, tal vez deberíamos preguntarnos si es realmente necesario y/o útil llegar hasta ese punto... U.D. IV – Web 2.0 134 Capítulo 5 XSLT y XForms Ahora llega el momento de adentrarnos en dos tecnologías que nos van a permitir manipular y obtener información en base a archivos XML: XSLT y XForms. En la primera parte de esta lección veremos el funcionamiento de las hojas de transformación XSLT y cómo podemos utilizarlas para "convertir" un archivo XML a otro distinto, que puede obedecer a otro tipo de definición de documento o incluso generar una página completa en XHTML válido en base a un XML que contenga un conjunto de registros. En la segunda parte introduciremos el funcionamiento de XForms, otro elemento clave en las tecnologías XML y que ha sido definido por el W3C como "el futuro de los formularios web". Este elemento nos permitirá ahorrarnos líneas de código HTML, aumentando a la vez la separación de capas de diseño y la funcionalidad que ofreceremos a los usuarios de nuestra aplicación por medio de los formularios. Al finalizar el estudio de esta lección serás capaz de: 9 Entender y utilizar la tecnología XSLT para transformar documentos XML en otros distintos 9 Crear y utilizar formularios web basados en XForms U.D. IV – Web 2.0 135 Lección 1 Hojas de Transformación XSLT XSLT es un lenguaje de programación que forma parte de la trilogía de XML, compuesta por las Hojas de Estilo CSS (que ya hemos visto con anterioridad), el propio lenguaje de transformación XSLT (XML Stylesheets Language for Transformation) y XSL:FO (Formatting Objects), elemento que no vamos a cubrir en este curso. Con las hojas de transformación XSLT vamos a convertir documentos XML en otros documentos XML. Así pues podremos realizar transformaciones tan variopintas como crear documentos que respondan a otro tipo de definición (DTD) o convertir un archivo con información XML sobre elementos de datos en una página XHTML perfectamente formada. Este último será el ejemplo que veremos a lo largo de la lección. 4.5.1_1 – Funcionamiento de las Hojas de Transformación XSLT Lo que van a conseguir en esencia las hojas de transformación es separar aun más la información de la presentación en HTML. Si anteriormente hemos utilizado las hojas de estilo para separar el diseño del código HTML, con XSLT separaríamos las etiquetas HTML del contenido que incluyen. Podemos además utilizar diferentes hojas de transformación para un mismo documento XML, por lo que las posibilidades pueden ser infinitas. Actualmente hay varias versiones del estándar XSLT: la versión 1.0, que es la que implementan la mayoría de los procesadores y que es denominada como "recomendación" por el W3C, y la versión 2.0 del 27 de Enero de 2007. Entre ellas hay diferencias importantes entre las que destacan el tratamiento uniforme de los árboles, uso de múltiples documentos de salida y funciones definibles por el usuario. U.D. IV – Web 2.0 136 Hojas de Transformación XSLT básicas Vamos a comenzar con un ejemplo de documento XML sencillo: <?xml version="1.0" encoding='ISO-8859-1'?> <?xml-stylesheet href="ejemploBasico.xsl" type="text/xsl"?> <sucursal> <nombre>Avenida de Valencia</nombre> <telefono>976 123 456</telefono> </sucursal> En este documento encontraríamos los datos referentes a una sucursal bancaria. Para convertir este documento XML en otro compatible con la especificación HTML, utilizaríamos la siguiente hoja de transformación: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match='/'> <html> <head> <title>Sucursales bancarias</title> </head> <body> <h1><xsl:apply-templates /></h1> </body> </html> </xsl:template> </xsl:stylesheet> Pon a prueba la tecnología XSLT. Guarda el primer fragmento (XML) como un archivo llamado "ejemploBasico.xml" y el segundo como "ejemploBasico.xsl". Si ahora abres el primero de ellos en tu navegador, verás que se genera un documento HTML con la información de la sucursal bancaria. El código del documento XML contiene una etiqueta llamada "sucursal" que incluye en su interior dos más: "nombre" y "telefono". En la cabecera del documento se incluye la etiqueta que define que dicho documento está en formato XML y la correspondiente que indica qué hoja de transformación se debe aplicar para la correcta visualización del documento. En cuanto a la hoja de transformación, decir que su esqueleto es un documento HTML estándar, al cual en un punto determinado se le añade el contenido dinámico U.D. IV – Web 2.0 137 fruto de la incorporación de los datos del archivo XML. En este caso la hoja XSLT es una simple plantilla que nos va a ayudar a generar el contenido final. Las dos primeras líneas incluyen información de codificación y definición de documento que utilizaremos como elemento raíz del mismo. A continuación definimos el contenido que va a colocarse "tal cual" (el código HTML) y por último hacemos referencia a una orden que se encarga de aplicar la plantilla que viene dada desde el documento XML. Esta etiqueta se "dispara" cuando encuentra otra etiqueta en el documento XML que corresponda a lo que hay en su atributo "match". Como en este caso no hemos incluido ningún en dicho atributo, tomará el nodo raíz de XML como punto de partida para generar contenido. Hojas de Transformación XSLT avanzadas Ahora vamos a complicar ligeramente el ejemplo que hemos visto, añadiéndole datos sobre diferentes productos de inversión. Si incluimos tres productos en la sucursal anterior, el documento XML que contendría toda la información sería como el que aparece a continuación: <?xml version="1.0" encoding='ISO-8859-1'?> <?xml-stylesheet href="ejemploAvanzado.xsl" type="text/xsl"?> <sucursal> <nombre>Avenida de Valencia</nombre> <telefono>976 123 456</telefono> <producto> <codigo>1</codigo> <rentabilidad>2%</rentabilidad> <nombre>Deposito jubilación</nombre> </producto> <producto> <codigo>2</codigo> <rentabilidad>2,5%</rentabilidad> <nombre>Plan tranquilidad</nombre> </producto> <producto> <codigo>3</codigo> <rentabilidad>4%</rentabilidad> <nombre>Rendimiento 2010</nombre> </producto> </sucursal> U.D. IV – Web 2.0 138 Este documento transformación: lo procesaríamos por medio de la siguiente hoja de <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match='/'> <html> <xsl:apply-templates /> </html> </xsl:template> <xsl:template match='sucursal'> <head> <title><xsl:value-of select='nombre' /></title> </head> <body> <h1><xsl:value-of select='nombre' /> </h1> <h2>Teléfono: <xsl:value-of select='telefono' /></h2> <h2>Nuestras mejores ofertas financieras</h2> <table> <tr><th>Código</th><th>Rentabilidad</th><th>nombre</th></tr> <xsl:apply-templates select='producto' /> </table> </body> </xsl:template> <xsl:template match='producto'> <tr><xsl:apply-templates /></tr> </xsl:template> <xsl:template match='codigo|rentabilidad|nombre'> <td><xsl:apply-templates /></td> </xsl:template> </xsl:stylesheet> Si bien en la anterior hoja de estilo XSLT disponíamos de una plantilla, en esta tenemos cuatro diferentes. Cada una de las plantillas existentes trata elementos de diferente profundidad dentro del árbol del documento XML. El primer elemento procesaría la raíz del XML, el segundo se aplicaría a los elementos de tipo "sucursal", el tercero a los de tipo "producto" y por último los elementos de tipo "codigo", "rentabilidad" y "nombre" se procesan por la plantilla que aparece al final. En la primera de las plantillas solamente tenemos la apertura y cierre del documento HTML. En la segunda de las plantillas colocamos el contenido necesario para que aparezca la información de la sucursal y en la tercera y la cuarta introduciremos los elementos HTML necesarios para que se genere una tabla con información de los tipos de productos de los que disponemos. U.D. IV – Web 2.0 139 Cabe destacar que el orden en el que se incluyen los elementos es el mismo en el que aparecen en el documento XML, lo que se denomina orden de documento. 4.5.1_2 – Nuestro ejemplo avanzado de XSLT en acción Del mismo modo que el ejemplo anterior puedes probar lo que ves en estas líneas en tu navegador. Guarda el primer fragmento (XML) como un archivo llamado "ejemploAvanzado.xml" y el segundo como "ejemploAvanzado.xsl". Una vez que los tengas, abre el primero de ellos en tu navegador y verás el resultado. U.D. IV – Web 2.0 140 Lección 2 XForms Como hemos comentado en la introducción de la lección, XForms es la nueva generación de formularios web, o por lo menos la evolución de los mismos. Por medio de uso de la tecnología XML, vamos a poder construir formularios de un modo fácil y sobre todo repetible desde el punto de vista de la programación. Algunas de las características que hacen que los XForms sean un elemento a considerar en el desarrollo de nuestra aplicación son las siguientes: 9 Separan el modelo de datos de su diseño visual, permitiendo definir un archivo con los controles y etiquetas asociados a los mismos 9 Dotan de mayor potencia al formulario y nos facilitan el trabajo con los formularios y elementos que en ellos aparecen. Por otro lado tenemos que definir el concepto de instancia de datos que no es más que un modelo de datos que viene a reflejar la estructura de datos que se va a utilizar en el formulario. 4.5.1_3 – Esquema de funcionamiento de XForms Ambos elementos: controles de formulario y la instancia de datos son ligados mediante un procesador XForms el cual define como se envían y reciben dichos datos a través del navegador del usuario. U.D. IV – Web 2.0 141 Estos conceptos son algo ambiguos y complejos de entender a la primera. En el resto de la lección vamos a ver un ejemplo de formulario XForms desde cero. Vamos a ver cómo tenemos que crearlo y cómo funcionaría en el marco de nuestro explorador web. Nuestro formulario en XForms En la tarea de crear nuestro propio formulario, vamos a empezar definiendo el documento XHTML. Para ello tenemos que crear la misma estructura, pero añadiendo antes del nombre de las etiquetas una cadena que defina el espacio de nombres en sobre el que vamos a trabajar. En nuestro caso utilizaremos la cadena 'h': <h:html xmlns:h="http://www.w3.org/1999/xhtml"> <h:head> <h:title>Ejemplo de formulario XForms</h:title> </h:head> <h:body> </h:body> </h:html> Con este pequeño gesto vamos a diferenciar el contenido HTML estándar de las etiquetas XForms, que iremos viendo más adelante. El siguiente paso o elemento a incluir es el espacio de nombres de XForms, que está definido en http://www.w3.org/2002/XForms <h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/2002/XForms"> Vamos a crear un elemento sencillo con un pequeño formulario de búsqueda. Dentro de este formulario colocaremos dos campos de entrada de texto y un botón que ejecute el proceso de búsqueda. Para añadir los campos de entrada de texto utilizaremos el elemento <input> de XForms: <input> <label>Nombre:</label> </input> <h:br/> <input> <label>Apellido:</label> </input> Dentro de cada uno de los elementos <input> podemos añadir dos nodos secundarios: 9 El elemento <label>: Para indicar el nombre que se colocará como prefijo en el campo de entrada U.D. IV – Web 2.0 142 9 El elemento <hint>: Al colocarlo aparecerá una ventana emergente con ayuda cuando vayamos a rellenar el campo. Finalmente, para añadir el botón de búsqueda utilizaremos el elemento <submit>. Este elemento tiene asociado un atributo que es "submission", en el cual especificaremos la dirección de envío de dicho formulario: <submit submission="buscar"> <label>Enviar</label> </submit> 4.5.1_4 – El formulario que vamos a construir funcionando en un navegador Enlazando el formulario con el modelo de datos Como hemos dicho en la introducción, XForms separa los datos de la presentación. El modelo de dato que vamos a utilizar se va a definir dentro de la etiqueta <model>. Un modelo contendrá una instancia del mismo (definida por el elemento <instance>), la cual contendrá los datos. Veamos ahora cómo quedaría nuestro formulario con el nombre y apellido incluidos como modelo del mismo: <model> <instance> U.D. IV – Web 2.0 143 <data xmlns=""> <nombre>Homer</nombre> <apellido>Simpson</apellido> </data> </instance> </model> Si dentro del formulario queremos hacer referencia a algún elemento del modelo utilizaremos el atributo "ref" dentro del control visual. De este modo, el código del formulario nos quedaría del siguiente modo: <input ref="nombre"> <label>Nombre:</label> </input> <h:br/> <input ref="apellido"> <label>Apellido:</label> </input> Dentro del elemento modelo también definiremos la acción que el formulario debe ejecutar cuando se haga click sobre el botón de "Enviar". Para indicar esto, utilizaremos el elemento <submission> del siguiente modo: <submission action="http://www.midominio.com/busqueda.php" method="post" id="buscar"/> Como podemos ver en el ejemplo, el elemento <submission> tiene varios atributos. Vamos a definirlos y ver para qué sirven: 9 action: Define la dirección URL de la página o recurso al que se van a enviar los datos 9 method: Indica el protocolo a utilizar en la serialización de los datos. Normalmente suele ser "GET" o "POST" 9 id: Un identificador único que será utilizado por el elemento que dispongamos como botón para referenciar al elemento <submission> y que de este modo pueda usarlo. Con la inclusión de este elemento tendríamos ya nuestro XForm listo para funcionar. El código resultante del mismo sería el que aparece a continuación: <h:html xmlns:h=http://www.w3.org/1999/xhtml xmlns="http://www.w3.org/2002/XForms"> <h:head> <h:title>Ejemplo de formulario XForms</h:title> <model> <instance> U.D. IV – Web 2.0 144 <data xmlns=""> <nombre>Homer</nombre> <apellido>Simpson</apellido> </data> </instance> <submission action="http://www.midominio.com/busqueda.php" method="post" id="buscar"/> </model> </h:head> <h:body> <h:h1>Mi primer formulario XForms</h:h1> <h:p> <input ref="nombre"> <label>Nombre:</label> <hint>Introduce el nombre de la persona a localizar</hint> </input> <h:br/> <input ref="apellido"> <label>Apellido:</label> <hint>Introduce el apellido de la persona a localizar</hint> </input> <h:br/> <submit submission="busqueda"> <label>Buscar</label> </submit> <h:br/><h:br/> <h:hr/> </h:p> </h:body> </h:html> Si quieres probar este formulario, puedes hacerlo desde Mozilla Firefox, que dispone de un plugin capaz de procesar estos elementos y que puedes descargar en la siguiente dirección: https://addons.mozilla.org/firefox/824/. Una vez descargado e instalado, tan sólo deberás copiar el ejemplo y guardarlo como un archivo con extensión ".xhtml" para que puedas ejecutarlo en el mismo y ver cómo funciona. U.D. IV – Web 2.0 145 Capítulo 6 HTTP y URI A lo largo de este capítulo vamos a conocer un poco más de cerca dos tecnologías o elementos que envuelven Internet y en las que nuestras aplicaciones Web 2.0 van a apoyarse totalmente: El protocolo HTTP y las URI’s En la primera parte del mismo daremos un vistazo al protocolo HTTP, estudiaremos cómo funciona internamente y cómo se realizan las peticiones al servidor por medio de estas “reglas de juego”. Nos adentraremos además en los diferentes mensajes de estado y error que nos retorna, para que cuando veamos que en nuestro navegador se nos informa de un error 404 o un error 500 sepamos exactamente qué nos quiere decir. Más adelante veremos el funcionamiento de las URI’s y cómo nuestras aplicaciones e incluso nosotros mismos las utilizamos día a día cada vez que intentamos acceder a una página web. Aprenderemos a interpretarlas y “diseccionarlas”, sacándoles todo el jugo y entendiendo para qué sirven cada una de sus partes. Al finalizar el estudio de esta lección serás capaz de: 9 Entender el funcionamiento del protocolo HTTP e interpretar sus respuestas 9 Interpretar URI’s e identificar cada una de sus partes U.D. IV – Web 2.0 146 Lección 1 El protocolo HTTP Las siglas HTTP significan “Hypertext Transfer Protocol” que dicho en la lengua de Cervantes vendría a indicar “Protocolo de Transferencia de Hipertexto”. Es un protocolo basado en la tecnología TCP/IP y se utiliza para entregar virtualmente todo tipo de ficheros y datos, lo que podríamos llamar recursos. Estos recursos comprenderían páginas web, archivos de imágenes, resultados de peticiones o cualquier otro dato que se pueda enviar o recibir a través de un navegador. Un navegador, dicho sea de paso funciona internamente como cliente de HTTP, ya que es capaz de enviar y recibir peticiones a un servidor HTTP, comúnmente llamado “Servidor Web”. Una vez que este recibe la petición, devuelve la respuesta a la misma al cliente. El puerto estándar de comunicaciones para este protocolo en un ordenador suele ser el 80, pero por motivos de seguridad o si en una misma máquina existen varios servidores diferentes, puede modificarse al 8080 o uno de la elección del técnico de sistemas que configure dicha máquina Hay tres características importantes del protocolo HTTP que debemos conocer: 9 El protocolo HTTP no preserva las conexiones. Una vez que una petición se realiza, el cliente se desconecta del servidor y espera una respuesta. El servidor debe restablecer la conexión para enviar dicha respuesta de vuelta al cliente 9 El protocolo HTTP es independiente del medio. Cualquier tipo de datos puede ser enviado por medio de dicho protocolo siempre y cuando ambas partes sepan cómo manejar y procesar el contenido. El determinar cómo se maneja este contenido es labor de los tipos MIME. 9 El protocolo HTTP no conserva el estado. Esto es un resultado directo de la primera de las características que hemos indicado. El servidor y el cliente están conectados en el momento que realizan un intercambio de datos, pero en el momento que este acaba, ambas máquinas se desconectan de la conexión. Por esta razón ni el cliente ni el navegador pueden compartir información entre diferentes peticiones realizadas en una página o aplicación web. U.D. IV – Web 2.0 147 A continuación se muestra un diagrama en el que podemos ver el papel que juega el protocolo HTTP en la comunicación: 4.6.1_1 – El protocolo HTTP en el marco de la comunicación Web Estructura de los mensajes HTTP Como la mayoría de los protocolos, HTTP utiliza un modelo cliente-servidor: un cliente HTTP abre la conexión y envía un mensaje a un servidor HTTP, el servidor entonces lo procesa y devuelve una respuesta a dicha petición, habitualmente conteniendo el recurso solicitado en la misma. Después de finalizarla, el servidor cierra la conexión. El formato de los mensajes de petición y respuesta es similar entre ambos y posee la siguiente estructura: 9 9 9 9 Una línea inicial <salto de línea> Una o más líneas de cabecera<salto de línea> Una línea en blanco<salto de línea> Un mensaje opcional en el contenido como una página web, un archivo o lo que se haya solicitado Vamos a desgranar esta petición HTTP y a estudiar en profundidad todas sus partes: Línea inicial: Petición La primera línea es diferente en la petición y en la respuesta. En el caso de la petición, posee tres partes, separadas por espacios: 9 El nombre del método HTTP 9 La ruta local del recurso solicitado U.D. IV – Web 2.0 148 9 La versión de HTTP que se está utilizando Este es un ejemplo de la línea inicial del mensaje de petición: GET /path/to/file/index.html HTTP/1.0 El método GET es el más común utilizado. Otros métodos posibles son POST, HEAD, etc. La ruta es la parte de la URL después del nombre del host (lo veremos en la segunda parte de este capítulo) La versión HTTP siempre está formada del siguiente modo: “HTTP/x.x” Línea inicial: Respuesta La línea inicial de la respuesta, llamada “línea de estado” tiene también tres partes, separadas por espacios: 9 La versión de HTTP que está siendo utilizada 9 Un estado de respuesta que define el resultado de la petición 9 Una descripción en inglés del estado devuelto Estos son un par de ejemplos de la línea inicial del mensaje de respuesta: HTTP/1.0 200 OK o HTTP/1.0 404 Not Found Líneas de cabecera Las cabeceras indican información sobre la petición, la respuesta o el objeto enviado en el cuerpo del mensaje. El nombre de la cabecera no es sensible a las mayúsculas y puede contener un número de espacios indeterminado entre el carácter “:” y el valor. U.D. IV – Web 2.0 149 Ejemplos de líneas de cabecera: User-agent: Mozilla/3.0Gold o Last-Modified: Fri, 31 Dec 1999 El cuerpo del mensaje Un mensaje HTTP puede contener un conjunto de datos enviados después de las líneas de cabecera. En una respuesta sería el punto donde el elemento solicitado por el cliente es enviado al mismo o bien si la petición ha resultado en error, el punto donde se indicará el error detallado. En el caso de una petición, contendría archivos adjuntos en un formulario para enviar al servidor para su procesamiento. Si un mensaje HTTP incluye un cuerpo con contenido, normalmente se incluyen unas líneas en la cabecera que describen el contenido que nos vamos a encontrar, en particular: 9 El tipo de contenido enviado, que indica el tipo MIME del contenido que se encuentra en el cuerpo del mensaje 9 La longitud en bytes del contenido que se envía 4.6.1_2 – Una petición HTTP hecha arte Los métodos HTTP: GET, POST y HEAD El protocolo HTTP dispone de tres métodos principales, que son los que definimos a continuación: U.D. IV – Web 2.0 150 GET: Esta método indica que se desea obtener cualquier tipo de información indicada en la URI solicitada. Si la URI solicitada apunta a un proceso de datos, se iniciará dicho proceso y se devolverá la respuesta del mismo. El método GET se puede utilizar para enviar formularios, pero en ese caso los datos se enviarán directamente como parte de la URI HEAD: El método HEAD es idéntico al GET que acabamos de ver, sólo que en este caso le indica al servidor que le devuelva únicamente las cabeceras del mensaje. Esto es útil para conocer las características de un archivo sin tener que descargarlo (tipo de archivo, tamaño…) preservando ancho de banda en la operación. POST: Este método es utilizado para hacer llegar datos al servidor de algún modo. Suele utilizarse cuando creamos formularios que deben cargar archivos adjuntos o cuando queremos proteger dichos datos de su aparición directa en la URI de petición. Códigos de estado de las peticiones HTTP Como hemos visto anteriormente, las peticiones HTTP provocan respuestas, y una parte muy importante de las mismas es el estado de dicha respuesta. Tenemos que tener en cuenta que cuando se produzca un error se nos va a devolver una respuesta desde el servidor. Si no la interpretamos adecuadamente no sabremos qué nos está devolviendo y podemos caer en el error de dar una respuesta por correcta cuando en realizad el servidor nos retorna un fallo interno… A continuación aparece una relación de estados de servidor y el significado de los mismos. No es necesario aprenderlos de memoria, pero conocerlos nos va a ayudar a entender mejor lo que un servidor quiere indicarnos: 1xx (Respuesta provisional) Códigos de estado que indican una respuesta provisional y requieren que el solicitante realice una acción para poder continuar. Código Descripción 100 (Continuar) El solicitante debe continuar con la solicitud. El servidor muestra este código para indicar que ha recibido la primera parte de una solicitud y que está esperando el resto. 101 (Cambiando de protocolos) El solicitante ha pedido al servidor que cambie los protocolos y el servidor está informando de que así lo hará. U.D. IV – Web 2.0 151 2xx (Correcto) Códigos de estado que indican que el servidor ha procesado la solicitud correctamente. Código Descripción 200 (Correcto) El servidor ha procesado la solicitud correctamente. 201 (Creado) La solicitud se ha procesado correctamente y el servidor ha creado un nuevo recurso. 202 (Aceptado) El servidor ha aceptado la solicitud, pero todavía no la ha procesado. 203 (Esta información no concede autorización) El servidor ha procesado la solicitud correctamente, pero muestra información que puede proceder de otra fuente. 204 (Sin contenido) El servidor ha procesado la solicitud correctamente, pero no muestra ningún contenido. 205 (Restablecer contenido) El servidor ha procesado la solicitud correctamente, pero no muestra ningún contenido. A diferencia de la respuesta 204, esta requiere que el solicitante restablezca la vista del documento (por ejemplo, borrar los datos de un formulario para introducir nueva información). 206 (Contenido parcial) El servidor ha procesado una solicitud GET parcial correctamente. 3xx (Redirigido) Es necesario llevar a cabo acciones adicionales para completar la solicitud. Código Descripción 300 (Varias opciones) El servidor puede realizar varias acciones de acuerdo con la solicitud. 301 (Movido permanentemente) La página solicitada se ha movido definitivamente a una ubicación nueva. 302 (Movido temporalmente) El servidor responde a la solicitud con una página de otra ubicación, pero el solicitante debe seguir utilizando la ubicación original para solicitudes futuras. 303 (Ver otra ubicación) El servidor muestra este código cuando el solicitante debe realizar una solicitud GET independiente a una ubicación diferente para poder obtener la respuesta. 304 (No modificado) La página solicitada no ha sufrido cambios desde la última solicitud.. 305 (Usar proxy) El solicitante sólo puede acceder a la página solicitada mediante un proxy 307 (Redireccionamiento temporal) El servidor responde a la solicitud con una página de otra ubicación, pero el solicitante debe seguir U.D. IV – Web 2.0 152 utilizando la ubicación original para solicitudes futuras. 4xx (Error de solicitud) Los códigos de estado siguientes indican que puede haberse producido un error en la solicitud que impidió al servidor procesarla. Código Descripción 400 (Solicitud incorrecta) El servidor no ha entendido la sintaxis de la solicitud. 401 (No autorizado) La solicitud requiere autenticación. 403 (Prohibido) El servidor ha rechazado la solicitud. 404 (No se encuentra) El servidor no encuentra la página solicitada. 405 (Método no permitido) No se permite el método especificado en la solicitud. 406 (Inaceptable) No se puede ofrecer la página solicitada con las características de contenido requeridas. 407 (Se requiere autenticación de proxy) Este código de estado es similar al 401 (No autorizado), aunque en este caso se especifica que el solicitante debe autenticarse mediante un proxy. 408 (El tiempo de espera de la solicitud ha caducado) Se ha excedido el tiempo de espera de respuesta de la solicitud. 409 (Conflicto) El servidor ha detectado un conflicto al llevar a cabo la solicitud, por lo que debe incluir la información correspondiente en la respuesta. 410 (No disponible permanentemente) El servidor muestra esta respuesta cuando el recurso solicitado se ha eliminado definitivamente 411 (Requiere longitud) El servidor no aceptará la solicitud sin el campo válido "Content-Length" (longitud del contenido) en la cabecera. 412 (Error de condición previa) El servidor no cumple con una de las condiciones previas que el solicitante ha especificado en la solicitud. 413 (Entidad de solicitud demasiado larga) El servidor no puede procesar la solicitud porque es demasiada larga. 414 (URI solicitada demasiado larga) La URI solicitada (generalmente una URL) es demasiado larga para que el servidor la procese. 415 (Tipo de soporte incompatible) La solicitud se encuentra en un formato que la página solicitada no admite. 416 (Intervalo solicitado no válido) El servidor muestra este código de estado cuando se realiza una solicitud de un rango que no se encuentra disponible para la página. 417 (Error de expectativa) El servidor no puede cumplir los requisitos del campo de expectativa de solicitud en la cabecera. U.D. IV – Web 2.0 153 5xx (Error del servidor) Los códigos de estado siguientes indican que se ha producido un error interno del servidor al intentar procesar la solicitud. Código Descripción 500 (Error interno del servidor) Se ha producido un error en el servidor y no puede completar la solicitud. 501 (No implementado) El servidor no dispone de las funciones necesarias para completar la solicitud. 502 (Pasarela incorrecta) Al actuar como pasarela o proxy, el servidor ha recibido una respuesta no válida del servidor ascendente. 503 (Servicio no disponible) El servidor no está disponible en estos momentos, debido a tareas de mantenimiento o a una sobrecarga. 504 (El tiempo de espera de la pasarela ha caducado) Al actuar como pasarela o proxy, el servidor no ha recibido una solicitud puntual del servidor ascendente. 505 (Versión de HTTP no compatible) El servidor no es compatible con la versión del protocolo HTTP utilizada en la solicitud. U.D. IV – Web 2.0 154 Lección 2 URI – Uniform Resource Identifier URI es el acrónimo de “Uniform Resource Identifier”, identificador uniforme de recurso. Referenciándonos a Wikipedia y a su página definiremos http://es.wikipedia.org/wiki/Uniform_Resource_Identifier, coloquialmente el nombre URI del siguiente modo: Un URI es una cadena de caracteres que identifica inequívocamente un recurso (servicio, página, documento, dirección de correo electrónico, enciclopedia, etc.). Normalmente estos recursos son accesibles en una red o sistema. Una URI está formada por varios elementos que vamos a explicar a continuación en base al siguiente ejemplo: http://www.dominio.com/paginas/contenidos?nombre=libro#aplicacionesWeb Esquema: La sección “esquema” indica cómo debe interpretarse el recurso al que referencia. Para HTTP el esquema es http, para FTP su esquema es ftp. En nuestro caso, el esquema sería “http” Autoridad: la parte de autoridad viene a indicar el nombre de dominio o dirección IP que identifica la máquina en la que se encuentra dicho recurso. En nuestro caso, la autoridad correspondiente sería www.dominio.com Ruta: la parte de ruta coincide con el sistema de ficheros del servidor, indicando el lugar donde está el recurso que solicitamos. En nuestro caso sería “/paginas/contenidos” Consulta: el parámetro o parámetros que enviaremos al recurso solicitado para que procese y nos devuelva el contenido generado en función de los mismos. En el caso de nuestro ejemplo sería “nombre=libro” Fragmento: con esta parte indicamos un recurso secundario. En el caso de una página web, seleccionaríamos la sección o párrafo al que queremos acceder. En el ejemplo sería “Aplicaciones Web” Si deseas obtener más información sobre la especificación URI, puedes acceder a la URI: http://www.ietf.org/rfc/rfc3986.txt, donde se recoge la especificación completa de este elemento. U.D. IV – Web 2.0 155 Capítulo 7 XML A lo largo de las anteriores lecciones hemos estudiado los distintos elementos y herramientas de los que nos vamos a servir para crear nuestras aplicaciones Web 2.0. Todas ellas sirven para procesar peticiones del cliente, recibir datos del servidor, dar estilos y formato al contenido, etc. Un elemento clave en este conjunto es el método de envío y recepción de los mensajes que componen el flujo de información de la aplicación. Como bien sabrás, este método de envío se va a servir del lenguaje XML para “serializar” la información (poderla incluir en un flujo) y enviarla o recibirla desde el servidor hasta el cliente. En las próximas lecciones vamos a estudiar en profundidad el estándar XML desde sus bases. En la primera de ellas vamos a estudiar la estructura del documento XML y de las diferentes etiquetas que podemos utilizar. Más adelante veremos cómo podemos plantear nuestro propio tipo de documento XML y lo definiremos creando una Definición de Tipo de Documento (DTD) que podremos utilizar más adelante. Para finalizar, en la última parte de este capítulo, volveremos una vez más a la programación en PHP para que, a través de ejemplos prácticos, aprendamos a crear nuestros propios archivos XML extrayendo información directamente desde base de datos, sentando en este punto una de las funcionalidades que más utilizaremos cuando creemos nuestra aplicación web. Al finalizar el estudio de estas lecciones, serás capaz de: 9 Identificar y entender los elementos que componen de un documento XML 9 Crear nuevos tipos documentos y utilizarlos en nuestros archivos XML 9 Utilizar el lenguaje PHP para extraer y generar archivos XML desde base de datos U.D. IV – Web 2.0 156 Lección 1 Fundamentos de XML El lenguaje XML, cuyo significado es "lenguaje extensible de etiquetas" (eXtensible Markup Language en inglés), es un lenguaje diferente a los que hemos tratado hasta el momento. Se diferencia del HTML en que este último es un lenguaje de marcado y XML no lo es. XML es un meta-lenguaje que nos permite definir lenguajes de marcado un función de unos usos determinados. Para denifir el lenguaje XML, vamos a referenciarnos a Wikipedia, que en su página http://es.wikipedia.org/wiki/Extensible_Markup_Language, define el lenguaje XML del siguiente modo: XML, siglas en inglés de Extensible Markup Language (lenguaje de marcas extensible), es un metalenguaje extensible de etiquetas desarrollado por el World Wide Web Consortium (W3C). Es una simplificación y adaptación del SGML y permite definir la gramática de lenguajes específicos (de la misma manera que HTML es a su vez un lenguaje definido por SGML). Por lo tanto XML no es realmente un lenguaje en particular, sino una manera de definir lenguajes para diferentes necesidades. Algunos de estos lenguajes que usan XML para su definición son XHTML, SVG, MathML. Teniendo en cuenta que XML es un metalenguaje que nos permite definir lenguajes, los elementos que lo componen pueden o no darnos información sobre su estructura física o presentación, por lo que no podemos presuponer como lo hacíamos en HTML que los elementos pueden mostrarse directamente. U.D. IV – Web 2.0 157 4.7.1_1 - Icono de ejemplo del lenguaje XML Para finalizar esta introducción, diremos que XML no ha nacido como un lenguaje para la Red, sino que se propone como un lenguaje de bajo nivel (de aplicación, no programación) para el intercambio de información con estructuras definidas entre diferentes aplicaciones y/o plataformas. Lo podemos utilizar en bases datos, editores de texto y en casi cualquier aplicación o aplicaciones que podamos imaginarnos. 4.7.1_2 – Ejemplo de estructura Web 2.0, en este caso utilizando XML y Flash como consumidor del contenido dinámico Estructura de un documento XML Un documento XML posee una estructura lógica y otra física: 9 Físicamente, el documento está compuesto por unas unidades denominadas entidades. Una entidad puede hacer referencia a otra, causando que esta se incluya en el documento. Cada documento comienza con una entidad "documento", también llamada "raíz". 9 A nivel lógico, el documento está compuesto de declaraciones, elementos, comentarios, referencias a caracteres e instrucciones de procesamiento, todos ellos indicados de forma explícita. Tanto la estructura lógica como la física deben encajar correctamente. Podemos hacer una división de documentos XML en dos grupos: aquellos documentos que se encuentren bien formados y los válidos: U.D. IV – Web 2.0 158 Bien formados: Cuando nos referimos a documentos "bien formados" englobaremos a todos los que cumplen las especificaciones del lenguaje en relación a las reglas sintácticas, sin estar sujetos a unas especificaciones de tipo de documento. Para hacernos a una idea esto sería lo mismo que tener un documento XHTML con todos los elementos bien colocados, respectando las aperturas y los cierres, pero utilizando atributos como "hspace" o "align", que en la especificación estricta están "prohibidos" Válidos: Como podemos suponer, los documentos válidos serán aquellos que están bien formados y que siguen una estructura concreta de tipo de documentos. En nuestro caso de XHTML serían aquellos que el validador del W3C indicaría como correctos. He aquí un ejemplo de documento XML: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ficha> <nombre>Homer</nombre> <apellido>Simpson</apellido> <direccion>742 Evergreen Terrace</direccion> </ficha> La primera línea incluida nos indica que el contenido que aparece a continuación está en formato XML. Esta línea es opcional, pero al incluirla indicamos a la aplicación encargada de procesar este documento los siguientes datos que pasaremos como atributo: version: Indica la versión de XML usada en el documento. encoding: La forma en que se ha codificado el documento. Admite cualquiera y debemos colocar aquella que hemos utilizado. En este caso hemos utilizado UTF-8, una de las más extendidas. standalone: Indica si el documento va acompañado de una Definición de Tipo de Documento DTD ("no"), o no lo necesita ("yes"). Este parámetro es opcional, ya que si utilizamos alguna DTD, deberemos incluir su referencia posteriormente. U.D. IV – Web 2.0 159 La declaración de tipo de documento (DTD) La declaración de tipo de documento o DTD define el tipo de documento que estamos utilizando y vamos a necesitarla para que dicho documento sea procesado correctamente. Deberemos indicar una DTD válida que defina los datos que nuestro documento XML contiene. En esta directiva, como comentamos, definiremos el tipo de documento y la URI en la que podemos encontrar la información sobre el mismo por medio de los siguientes elementos: 9 Un identificador público (PUBLIC): que hace referencia a dicha DTD. 9 Identificador universal de recursos (URI): precedido de la palabra SYSTEM. Las siguientes definiciones de tipo de documento serían perfectamente válidas para un archivo XML <!DOCTYPE MENSAJE SYSTEM "mensaje.dtd"> <!DOCTYPE HTML PUBLIC "-/ /W3C/ /DTD HTML 3.2 Final/ /EN"> <!DOCTYPE ETIQUETA SYSTEM "http://midominio.com/DTDs/etiqueta"> Documentos XML bien formados Como hemos comentado con anterioridad, un documento XML estará bien formado si cumple las especificaciones XML que se indican a continuación: Estructura jerárquica de elementos Los documentos XML deben incluir una estructura correcta a la hora de delimitar la apertura, cierre y anidación de las etiquetas que contiene. No debemos mezclar aperturas de unas etiquetas con cierres de otras y viceversa. Toda etiqueta que se incluya debe estar correctamente abierta y cerrada, y si contiene otras en su interior, deben cerrarse antes que acabe la etiqueta padre. A continuación mostramos un ejemplo incorrecto y otro correcto en un documento XML: <li> En HTML <b> podemos cruzar <i> etiquetas </b> </i>. <li> En XML debemos <b> respetar <i> la estructura </i> jerárquica </b>. </li> U.D. IV – Web 2.0 160 4.7.1_3 – Ejemplo de un fallo causado por no respetar la estructura jerárquica Etiquetas vacías En HTML podemos incluir elementos sin contenido. En XML podemos hacerlo, pero con la condición de que cerremos la etiqueta y que no se quede huérfana. Para crear una etiqueta con estas características, incluiremos la barra "/" antes de finalizarla. <li>En HTML podemos <br> utilizar etiquetas sin cerrar </li> <li>En XML debemos <br/> cerrar todas las etiquetas que creemos </li> Un solo elemento raíz Los documentos XML sólo permiten un único elemento raíz. El resto de elementos se anidarán y pertenecerán al mismo. La jerarquía de un documento XML bien formado sólo puede contener un elemento inicial. U.D. IV – Web 2.0 161 Valores de atributos Los valores de los atributos que adjuntemos a nuestras etiquetas XML siempre deben estar localizados entre comillas simples (') o dobles ("). La primera línea de este ejemplo no es válida, ya que indica atributos sin las comillas obligatorias. En el segundo ejemplo hemos solucionado dicho error: <a href=http://www.midominio.com/> <a href="http://www.midominio.com/"> Nombres Al utilizar el lenguaje XML, es necesario asignar nombres a las estructuras, etiquetas, tipos, entidades... En XML los nombres tienen algunas características que debemos conocer antes de utilizarlos correctamente: 9 No podemos crear nombres que comiencen con la cadena "xml", "xML", "XML" o cualquier otra variante de la misma. 9 Podemos utilizar letras y guiones en cualquier parte del nombre 9 Podemos incluir dígitos, guiones y caracteres de puntuación, pero el nombre no puede empezar por ninguno de estos. 9 El resto de caracteres como símbolos y espacios en blanco no se pueden utilizar para definir nombres. Marcado y datos Las etiquetas, referencias y declaraciones se denominan en lenguaje técnico "marcas". Por medio de las marcas el procesador de texto XML es capaz de entender el documento que se contiene. El resto de documento contenido entre estas marcas son los datos, que una vez interpretados en su contexto, serán entendibles por las personas. El reconocimiento de las marcas que componen un documento XML es sencillo: empiezan con "<" y acaban con ">", o bien, en el caso de que sean referencias a entidades, empezarán con el carácter "&" y terminarán con ";". La jerarquía de un documento XML bien formado sólo puede contener un elemento inicial. U.D. IV – Web 2.0 162 Elementos Como hemos visto en el apartado anterior, todos los elementos XML pueden tener contenido (textos y otros caracteres) o ser elementos vacios. Un elemento con contenido sería, por ejemplo: <nombre>Homer Simpson</nombre> <llamada tipo="interna" numero="976123456">Hola, ¿cómo estás?</llamada> Un elemento siempre va a comenzar con su <etiqueta>, que puede contener atributos o no, y terminará con el correspondiente </etiqueta> que debe tener el mismo nombre. Como hemos visto con anterioridad, al contrario que en HTML, en XML siempre se debe "cerrar" un elemento. El símbolo "<" siempre se interpreta como inicio de una etiqueta XML. Si lo estamos utilizando para otro fin (comparación en XSLT, por ejemplo), el documento no estará bien formado. En este caso, para utilizar símbolos reservados, haremos uso de las entidades predefinidas, que veremos más adelante. Un elemento vacío no tiene contenido, por ejemplo: <datos NIF="A2513658"/> <salto-de-linea/> Como en este caso carecen de contenido, utilizando las reglas de formación de XML, incluiremos la barra "/" al final de los mismos. Si bien en HTML podíamos utilizarlos sin cerrar, al utilizar XHTML, que recordemos que es una reformulación compatible con XML, nos veremos obligados a utilizarlas si queremos tener un documento válido y bien formado. U.D. IV – Web 2.0 163 Atributos Como hemos comentado, los elementos pueden tener atributos, que podemos utilizar a modo de incorporar características o propiedades a los elementos que contiene un documento. Por ejemplo, un elemento "sopa" puede tener un atributo "tipo" y un atributo "calidad", con valores "instantánea" y "excelente" respectivamente. <sopa tipo="instantánea" calidad="excelente">Sopa maravilla</sopa> Cuando interpretemos un documento XML, en su Definición de Tipo de Documento (DTD), se especificarán los atributos que pueden tener cada tipo de elemento, así como sus valores y tipos de valor posible. De este modo si nuestro lector se referencia a dicha definición, podrá interpretar correctamente los valores que se les asignen. Como parte de la especificación, debemos recordar que los atributos deberán ir entrecomillados con comillas simples ' o dobles ", de modo que el procesador de XML puede localizarlos y delimitarlos adecuadamente. Si estamos utilizando un atributo en cuyo interior incluimos alguna comilla simple, su delimitado contendrá comillas dobles y viceversa. <tablón clase="pino" longitud='2,5"'/> <literal contenido="'¿Cómo estás?', añadió"/> Cuando estamos modelando elementos en XML podemos optar por utilizar atributos o bien crear nuevos elementos dentro del mismo que contengan los valores de las diferentes características que contiene. Podemos utilizar indistintamente un modelo u otro, pero es recomendable que una vez que lo hayamos seleccionado, utilicemos siempre el mismo sistema para no dar lugar a errores. U.D. IV – Web 2.0 164 <perro><nombre>Sparky</nombre><raza>Dálmata</raza></perro> <perro raza="Dálmata">Sparky</perro> <perro raza="Dálmata" nombre="Sparky"/> Entidades Predefinidas En XML 1.0, disponemos de cinco entidades para representar caracteres especiales. Recordemos que ciertos caracteres están reservados para el uso e interpretación del lenguaje. Si queremos utilizarlos sin incurrir en errores de formación de documento, deberemos utilizar la entidad predefinida correspondiente a cada uno de ellos. Las entidades predefinidas de XML son las que aparecen a continuación: 9 9 9 9 9 &amp; equivalente a "&" &lt; equivalente a "<" &gt; equivalente a ">" &apos; equivalente a "'" &quot; equivalente a '"' Secciones CDATA En el caso de que tengamos que, por alguna razón, indicar datos que no deber ser procesados por XML, utilizaremos la construcción CDATA. Su funcionamiento es muy simple y hace que el contenido entre su apertura y cierre sea procesado tal cual como si se tratase de un contenido de una etiqueta, evitando en esa zona el uso de las entidades predefinidas de XML. Esto es especialmente útil cuando un "humano" intenta leer un contenido que contendría bastantes entidades predefinidas y no quiere "morir en el intento". U.D. IV – Web 2.0 165 Veamos un ejemplo del uso de CDATA. En el primer caso colocaremos el código con entidades predefinidas de XML y en el segundo haremos uso de CDATA para hacer más fácil su entendimiento: <miEjemplo> &lt;html> &lt;head>&lt;title>Rock &amp; Roll&lt;/title>&lt;/head> &lt;/html> </miEjemplo> <ejemplo> <![CDATA[ <html> <head><title>Rock & Roll</title></head> </html> ]]> </ejemplo> La cadena CDATA comenzará por el uso de la etiqueta reservada "<![CDATA[" y finalizará con "]]>" No podemos incluir cadenas CDATA anidadas en su interior. Comentarios XML nos permite insertar comentarios en su interior del mismo modo que HTML. Para ellos utilizaremos la cadena "<!--" e incluiremos los comentarios que consideremos oportunos en su interior, una vez que los hayamos terminados, utilizaremos el segmento de cierre "-->". La siguiente línea conforma un comentario en XML <!-- Esto es un comentario --> Podemos introducir comentarios en cualquier parte del documento excepto en el contenido de las declaraciones y etiquetas XML. Del mismo modo que la etiqueta CDATA, no podemos anidar comentarios dentro de los comentarios. U.D. IV – Web 2.0 166 Lección 2 Características de XML A lo largo de esta lección vamos a ver cómo crear nuestros propios tipos de documento. Al crear uno de ellos, vamos a definir nuestro propio lenguaje de marcado para una valoración específica. Para que nos hagamos una idea, podemos crear un DTD que defina una tarjeta de visita. A partir de este DTD tendríamos definidos unos elementos XML que nos permitirían definir con todo lujo de detalles nuestras tarjetas de visita. En la DTD vamos a definir los elementos, atributos y entidades que son válidas en nuestro lenguaje, así como si existen limitaciones para combinarlos. Cuando un documento se ajuste a su DTD, lo consideraremos un documento “válido”, que como sabemos nada tiene que ver con que esté “bien formado”. Un documento "bien formado", recordemos que simplemente respeta la estructura y sintaxis definida por la especificación de XML. Un documento "bien formado" puede además ser "válido" si cumple las reglas de una DTD determinada. Pueden existir documentos sin una DTD asociada. En este caso sólo podrán ser “bien formados” si definen una estructura XML, pero en ningún caso podrán ser “válidos” o “no válidos”. Cuando creemos nuestra propia DTD, podemos hacerlo en un fichero externo o dentro del mismo documento. Como el caso de las hojas de estilo, si nuestra DTD se encuentra en un fichero externo, tendremos el beneficio de que podemos reutilizarla en varios documentos. Veamos un ejemplo de DTD <! DOCTYPE etiqueta[ <!ELEMENT etiqueta (nombre, calle, ciudad, pais, codigo)> <!ELEMENT nombre (#PCDATA)> <!ELEMENT calle (#PCDATA)> <!ELEMENT ciudad (#PCDATA)> <!ELEMENT pais (#PCDATA)> <!ELEMENT codigo (#PCDATA)> ]> <etiqueta> <nombre>Homer Simpson</nombre> <calle>742 Evergreen Terrace</calle> <ciudad>Springfield</ciudad> <pais>Estados Unidos</pais> <codigo>123456</codigo> </etiqueta> U.D. IV – Web 2.0 167 La declaración del tipo de documento empieza en la primera línea y termina con "]>". Las declaraciones DTD son las líneas que empiezan con "<!ELEMENT" y se denominan declaraciones de tipo elemento. También se pueden declarar atributos, entidades y anotaciones para una DTD. En el ejemplo que acabamos de ver, todas las declaraciones de DTD residen en el mismo documento. Como comentamos con anterioridad, podemos hacer que las declaraciones DTD residan en documentos externos del mismo modo que las hojas de estilo. En ese caso las referenciaríamos del siguiente modo: <?xml version="1.0"?> <!DOCTYPE coche SYSTEM "http://www.miDominio.com/dtd/ficha.dtd"> <ficha> <nombre>...</ nombre > ... </ ficha > Declaraciones Tipo Elemento Cuando definimos un elemento, definimos la base de las marcas XML y a la vez forzamos a que todos los elementos de este tipo tengan que ajustarse a nuestro DTD para que dicho documento sea considerado válido. Las declaraciones de los elementos deben empezar con la cadena "<!ELEMENT" seguida por el identificador que estamos declarando. Seguido a las mismas, especificaremos el contenido de los mismos. Por ejemplo: <!ELEMENT ficha (nombre, direccion, telefono)> En este ejemplo que acabamos de ver, el elemento <ficha> puede contener los elementos <nombre>, <direccion> y <telefono>, que estarán definidos también en la DTD y podrán contener más elementos en su interior si así lo definimos. U.D. IV – Web 2.0 168 Si seguimos la definición que acabamos de crear, este ejemplo de documento XML será considerado válido: <ficha> <nombre>...</nombre> <direccion >...</ direccion > < telefono >...</ telefono > </ficha> Sin embargo este no lo sería: <ficha> <párrafo>…</párrafo> <nombre>...</nombre> <direccion >...</ direccion > < telefono >...</ telefono > </ficha> Cuando especificamos el contenido que van a llevar las diferentes etiquetas, podemos utilizar cuatro tipos: EMPTY: El elemento no va a tener contenido. Suele usarse para los atributos. <!ELEMENT línea-horizontal EMPTY> ANY: Puede tener cualquier tipo de contenido. No es recomendable su uso ya que es preferible especificar bien el contenido de los documentos XML <!ELEMENT de-todo-tipo ANY> U.D. IV – Web 2.0 169 MIXED: Puede tener caracteres o más elementos en su interior. <!ELEMENT textos (#PCDATA)> <!ELEMENT parrafo (#PCDATA|textos)*> En el ejemplo, el primer elemento definido (<textos>) puede contener datos de carácter (#PCDATA). Y el segundo elemento (<parrafo>) puede contener tanto datos de carácter (#PCDATA) como subelementos de tipo <textos>. ELEMENT: Sólo puede contener sub-elementos especificados previamente en la especificación de contenido. <!ELEMENT correo (remitente, destino, cuerpoMensaje)> Para declarar que uno de nuestros elementos va a contener otros elementos definidos, se especifica un modelo de contenido en lugar de una especificación de contenido mixto o una de las claves ya descritas. Modelos de contenido Cuando definimos un modelo de contenido estamos definiendo un patrón que establece los sub-elementos que son aceptados y el orden de los mismos. Si planteamos un modelo sencillo, únicamente definiríamos un tipo de sub-elemento: <!ELEMENT ficha (nombre)> Esto indica que <ficha> sólo puede contener un elemento del tipo <nombre>. <!ELEMENT ficha (nombre, direccion)> La coma, en este caso, denota una secuencia. Es decir, el elemento <ficha> debe contener un <nombre> seguido de un elemento del tipo <direccion>. <!ELEMENT ficha (nombre | direccion)> U.D. IV – Web 2.0 170 La barra vertical "|" indica en este caso una opción. Es decir, <ficha> puede contener elementos de tipo <nombre> o de tipo <dirección> las diferentes opciones pueden agruparse por medio del uso de paréntesis. <!ELEMENT ficha (nombre, (direccion | telefono))> En este último caso, el elemento <ficha> contendrá un elemento de tipo <nombre>, que a su vez irá seguido de un elemento <direccion> o un <telefono>. Además de los casos que acabamos de ver, cada parte de contenido puede llevar un indicador de frecuencia del modo que describimos a continuación: 9 ? Opcional (0 o 1 vez) 9 * Opcional y repetible (0 o más veces) 9 + Necesario y repetible (1 o más veces) <!ELEMENT ficha (nombre?, (direccion+, telefono)*)> En este caso, <ficha> puede tener <nombre> o no (pero sólo uno), y puede tener cero o más conjuntos <direccion><telefono>, <direccion><direccion><telefono>, etc. Declaraciones de lista de atributos Como hemos visto, los atributos nos permiten añadir información adiciona la los elementos que contiene un documento XML. La principal diferencia entre los elementos y los atributos es que los atributos no pueden contener subelementos y los elementos sí. Utilizaremos los atributos cuando queramos introducir información corta, sencilla y desestructurada. <correo servicio="smtp"> <de>Homer Simpson</de> <a>Marge Simpson</a> <contenido idioma="español"> Hola, ¿cómo estás? ... </contenido> </correo> U.D. IV – Web 2.0 171 Otra diferencia entre los atributos y los elementos, es que cada uno de los atributos sólo se puede especificar una vez, y en cualquier orden. Si queremos crear el DTD del ejemplo que acabamos de ver, podríamos indicar lo siguiente: <!ELEMENT correo (de, a, contenido)> <!ATTLIST correo servicio (SMTP | IMAP) SMTP> <!ELEMENT contenido (#PCDATA)> <!ATTLIST contenido idioma CDATA #REQUIRED> Las declaraciones de los atributos empiezan con "<!ATTLIST", y a continuación del espacio en blanco indicaremos el identificador del elemento al que se aplica el atributo. Una vez hecho esto, incluiremos el nombre del atributo, su tipo y su valor por defecto. En el ejemplo anterior, el atributo "servicio" puede estar en el elemento <correo> y puede tener el valor "SMTP" o "IMAP", siendo "SMTP" el valor por defecto si no especificamos el atributo. El atributo "idioma", pertenece al elemento contenido y contendrá datos de tipo CDATA. Cuando indicamos la palabra #REQUIRED, forzamos a que dicho atributo sea de cumplimentación obligatoria y no deberemos especificar un valor por defecto. Tipos de atributos Atributos CDATA y NMTOKEN Los atributos CDATA (Character DATA) son los más sencillos que vamos a encontrar en el marco de XML y pueden contener prácticamente cualquier tipo de contenido. Sin embargo los atributos NMTOKEN (NaMe TOKEN) son similares a estos, pero solamente aceptan los caracteres válidos para nombrar elementos (letras, números, puntos, guiones y los dos puntos). <!ATTLIST ficha fecha CDATA #REQUIRED> <ficha fecha="25 de Enero de 2010"> <!ATTLIST ficha fecha NMTOKEN #REQUIRED> < ficha fecha="15-12-1999"> U.D. IV – Web 2.0 172 Atributos enumerados y notaciones Los atributos enumerados son aquellos que únicamente pueden contener un valor de entre un número reducido de opciones que deberemos definir dentro del mismo. <!ATTLIST correo servicio (SMTP | IMAP) SMTP> Cuando queremos que el contenido del atributo se ajuste a una notación específica utilizaremos el tipo NOTATION: <!ATTLIST correo fecha NOTATION (ISO-DATE | EUROPEAN-DATE) #REQUIRED> Para declarar las notaciones, se utiliza el elemento "<!NOTATION" con una definición externa de la notación. La definición externa puede ser pública o un identificador del sistema al igual que hacíamos cuando definíamos los propios DTD’s. <!NOTATION HTML SYSTEM "http://www.w3.org/Markup"> <!NOTATION HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> Atributos ID e IDREF El tipo ID permite que un tipo determinado que definiremos tenga un nombre único. Este nombre podrá ser referenciado por un atributo de otro elemento que sea de tipo IDREF. Esto podemos utilizarlo para implementar un sencillo sistema de hipervínculos en un documento: <!ELEMENT enlace EMPTY> <!ATTLIST enlace destino IDREF #REQUIRED> <!ELEMENT capitulo (parrafo)*> <!ATTLIST capitulo referencia ID #IMPLIED> En este caso, una etiqueta tal como <enlace destino="miApartado"> haría referencia a un <capitulo referencia="miApartado">, de forma que si lo disponemos de este modo, nuestro procesador XML sería capaz de crear un hipervínculo u otro tipo de automatismo. U.D. IV – Web 2.0 173 Declaración de entidades Cuando tenemos que hacer referencia a elementos que no deben ser procesados como elementos XML estándar, hacemos uso de las entidades. En nuestro DTD declararemos las entidades mediante el uso de "<!ENTITY" Una entidad sencilla puede ser, por ejemplo, una abreviatura que se utiliza como una forma corta de algunos textos. Al usar una referencia a esta entidad, el analizador sintáctico reemplaza la referencia con su contenido. En la mayoría de las ocasiones es una referencia a un objeto externo o local. Las entidades pueden ser: 9 Internas o Externas 9 Analizadas o No analizadas 9 Generales o Parámetro Entidades generales internas Son las más sencillas y denotan abreviaturas en el texto. Al colocarlas en un elemento y ser procesado su contenido, son remplazadas con el contenido original: <!DOCTYPE texto [ <!ENTITY ovni "Objeto Volador No Identificado"> ]> <texto><titulo>Un día en la vida de un &ovni</titulo></texto> Entidades generales externas analizadas Las entidades externas obtienen su contenido en cualquier otro sitio del sistema, ya sea otro archivo del disco duro, una página web o un objeto de una base de datos. Cuando hagamos referencia al contenido de una entidad, utilizaremos la palabra SYSTEM seguida de un URI (Universal Resource Identifier) <!ENTITY prueba SYSTEM "http://www.midominio.com/prueba.xml"> U.D. IV – Web 2.0 174 Entidades no analizadas Cuando el contenido de la entidad sea un archivo no procesable (un archivo ejecutable, un archivo de imagen, etc.), el procesador XML no debería intentar interpretarlo como si fuera texto XML. Este tipo de entidades siempre son las denominadas generales y externas. <!ENTITY logo SYSTEM "http://www.miservidor.com/logo.gif"> Entidades parámetro internas y externas Se denominan entidades parámetro a aquellas que sólo pueden usarse en la DTD para ayudar a su definición, pero no en el documento XML. Sobre todo se utilizan para agrupar elementos dejar un código más limpio en el DTD. Se diferencian de las generales, en que para hacer referencia a las mismas se usa el símbolo "%" en lugar de "&": <!DOCTYPE texto [ <!ENTITY % elemento-ovni "<!ELEMENT OVNI (#PCDATA)>"> ... %elemento- ovni; ]> En el caso de que sea externa: <!DOCTYPE texto [ <!ENTITY % elemento- ovni SYSTEM " ovni.ent"> ... %elemento- ovni; ]> U.D. IV – Web 2.0 175 Ejemplo de DTD Para finalizar esta lección vamos a ver un DTD que resumiría todos los elementos vistos hasta ahora. En nuestro caso vamos a definir un DTD que nos defina un lenguaje de marcado para albergar datos de personas con direcciones de e-mail. El fichero listaContactos.dtd podría ser similar al que aparece a continuación: <?xml encoding="UTF-8"?> <!ELEMENT listaContactos (ficha)+> <!ELEMENT ficha (nombre, email*, relacion?)> <!ATTLIST ficha id ID #REQUIRED> <!ATTLIST ficha sexo (hombre | mujer) #IMPLIED> <!ELEMENT nombre (#PCDATA)> <!ELEMENT email (#PCDATA)> <!ELEMENT relacion EMPTY> <!ATTLIST relacion amigo-de IDREFS #IMPLIED enemigo-de IDREFS #IMPLID> Basándonos en este DTD, podríamos escribir nuestro XML de la siguiente manera: <?xml version="1.0"?> <!DOCTYPE listaContactos SYSTEM "listaContactos.dtd"> <listaContactos> <persona sexo="hombre" id="homer"> <nombre>Homer Simpson</nombre> <email>[email protected]</email> <relacion amigo-de="marge"> </persona> <persona sexo="mujer" id="marge"> <nombre>Marge Simpson</nombre> <email>[email protected]</email> </persona> </listaContactos> U.D. IV – Web 2.0 176 Lección 3 Creación de documentos XML desde PHP En esta lección vamos a finalizar el estudio de las tecnologías XML con la explicación de un caso práctico de creación de un documento XML directamente desde MySQL con la inestimable ayuda del lenguaje de programación PHP. Una vez que obtengamos el archivo XML resultante, lo utilizaremos para lo que necesitemos. Podríamos asignarlo a un blog, una ventana de chat o incluso a elementos más grandes, como por ejemplo un gestor de contenidos que reciba información que le enviemos a través de este medio… La mayoría de los desarrolladores extraen los datos directamente de MySQL y los envían directamente a otras aplicaciones por medio del uso de un script de servidor (sin pasarlo a un documento XML). Esto no es necesariamente incorrecto, pero si extraemos y explotamos los datos de este modo, podremos tener problemas a la larga cuando tengamos que realizar cambios sobre los mismos, ya que este modelo no permite muchas actualizaciones. 4.7.3_1 – Esquema del uso de PHP para interactuar con MySQL y crear un archivo XML Muchas veces parece que el uso de XML es un paso intermedio que podría ser evitable, y en efecto puede ser visto así, pero si conseguimos crear un documento bien formado con las especificaciones de nuestra base de datos y el cliente final cambia de especificación, nuestros datos seguirán siendo siempre válidos y podremos olvidarnos de realizar ajustes en esta parte. Cuando utilizamos XML, inconscientemente estamos obteniendo ventajas derivadas del mismo. Vamos a tener nuestros datos organizados, si utilizamos tecnologías clientes que puedan consumir XML, la integración con los mismos va a ser muy sencilla e incluso podremos utilizar estos datos para realimentar cualquier aplicación que diseñemos en PHP ya que del mismo modo que es capaz de crear documentos XML, puede consumirlos sin mayores problemas. U.D. IV – Web 2.0 177 Configuración de MySQL En el ejemplo que vamos a ver extraeremos los datos desde nuestra base de datos sin tener que realizar ningún tipo de cambio. Lo único que vamos a tener que crear es un script PHP que se encargará de obtener los datos de una tabla y presentarlos en el en formato correcto. En cualquier caso, vamos a ver la estructura de la tabla que utilizaremos como ejemplo, que esta vez contiene las entradas de un blog: Fecha Texto 19/08/2007 Bienvenido a mi nuevo blog. Espero que sea un punto de referencia en el mundo de la programación PHP y que con él puedas aprender muchas cosas. 8/10/2008 En esta entrada veremos la integración de PHP con MySQL y XML, para que podamos extraer los datos de una tabla sin problemas 24/01/2010 Cuando tengamos los datos en formato XML, podremos utilizarlos en nuestras aplicaciones Web 2.0 Como podemos ver en el ejemplo, nuestra estructura de datos va a ser sencilla. Dispondremos de una tabla en la que almacenaremos las entradas de un blog. Cada una de estas contendrá una fecha de publicación y un texto. En las próximas secciones vamos a ver cómo podemos manipular estos con PHP para extraer su contenido y formatearlo en un documento XML. Diseñando nuestro script PHP El código que aparece a continuación es el ejemplo completo que realiza la extracción de datos y procesado de los mismos en un archivo de datos XML. Si entiendes PHP a un nivel más alto, directamente podrás comprobar qué y cómo lo hace. En cualquier caso, una vez mostrado iremos explicando cada una de sus secciones: U.D. IV – Web 2.0 178 <?php header("Content-type: text/xml"); $host = "localhost"; $usuario = "nombreUsuario"; $pass = "contraseñaMySQL"; $baseDatos = "pruebas"; $linkID = mysql_connect($host, $usuario, $pass) or die("No es posible conectarse al servidor de MySQL."); mysql_select_db($baseDatos, $linkID) or die("No se encuentra la base de datos seleccionada."); $query = "SELECT fecha, texto FROM blog ORDER BY date DESC"; $resultID = mysql_query($query, $linkID) or die("Error al obtener los datos de la tabla."); $xml_output = "<?xml version=\"1.0\"?>\n"; $xml_output .= "<entradas>\n"; for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){ $row = mysql_fetch_assoc($resultID); $xml_output .= "\t<entrada>\n"; $xml_output .= "\t\t<fecha>" . $row[fecha] . "</fecha>\n"; // Creando las entidades XML necesarias para evitar errores de proceso $row[‘texto’] = str_replace("&", "&", $row['texto']); $row[‘texto’] = str_replace("<", "<", $row['texto']); $row[‘texto’] = str_replace(">", "&gt;", $row['texto']); $row[‘texto’] = str_replace("\"", "&quot;", $row['texto']); $xml_output .= "\t\t<texto>" . $row['texto'] . "</texto>\n"; $xml_output .= "\t</entrada>\n"; } $xml_output .= "</entradas>"; echo $xml_output; ?> La primera parte del código es la encargada de conectarse a la base de datos como ya hemos visto en capítulos anteriores, aunque en este caso utilizamos una explicación más detallada de mensajes de error más propia de una aplicación real que de un ejemplo sencillo. La primera línea de código es la que indica al navegador y cualquier otro programa que vaya a utilizar este archive cómo debe trabajar con el mismo. Básicamente indicaremos en este punto de que se trata de un archivo XML y que no va a ser un archivo HTML estándar, como sería lo normal: U.D. IV – Web 2.0 179 header("Content-type: text/xml"); En de de de las siguientes líneas tras la cabecera se encuentran las variables y los elementos conexión a la base de datos. Como estos elementos se definieron ya en el tema acceso a datos desde PHP, no vamos a profundizar demasiado en la explicación los mismos: $host = "localhost"; $usuario = "nombreUsuario"; $pass = "contraseñaMySQL"; $baseDatos = "pruebas"; Una vez definidos los parámetros de conexión, podemos conectarnos al servidor MySQL sin mayor problema por medio de la creación de la conexión al mismo y la selección de la base de datos de trabajo: $linkID = mysql_connect($host, $usuario, $pass) or die("No es posible conectarse al servidor de MySQL."); mysql_select_db($baseDatos, $linkID) or die("No se encuentra la base de datos seleccionada."); Las siguientes líneas son muy sencillas de entender ya que contienen la consulta SQL que queremos ejecutar para obtener el contenido de la base de datos. Una vez definida, se utiliza la función mysql_query para ejecutarla y almacenar el contenido de la misma en la variable $resultID $query = "SELECT fecha, texto FROM blog ORDER BY date DESC"; $resultID = mysql_query($query, $linkID) or die("Error al obtener los datos de la tabla."); U.D. IV – Web 2.0 180 Llegados a este punto ya hemos obtenido correctamente los registros desde la base de datos y es el momento de empezar a construir nuestro archivo XML de salida. El procesado de documentos XML desde PHP es una tarea que puede realizarse de muchos modos diferentes. En este caso vamos a crearnos una nueva variable y sobre ella iremos componiendo nuestro archivo paso a paso. Podríamos crearlo utilizando funciones de librería, pero en cualquier caso el producto final y lo que es más importante, su funcionalidad no va a variar independientemente de que utilicemos un método u otro. Para comenzar la creación de la variable que contendrá el documento XML, introduciremos un par de líneas que nos permitirán crear la primera línea y el nodo raíz de documento respectivamente: $xml_output = "<?xml version=\"1.0\"?>\n"; $xml_output .= "<entradas>\n"; En las siguientes líneas vamos a realizar un bucle que recorrerá todos los registros que hemos extraído desde base de datos. Para conocer el número de elementos que hemos “traído”, utilizaremos una vez más la función mysql_num_rows(), que nos devolverá dicho elemento. Una vez dentro del bucle, utilizaremos la función mysql_fetch_assoc(), que extrae el registro actual de la base de datos a un vector que podremos procesar para la creación de nuestro documento. Una vez que tenemos creado el vector que contiene los campos del registro actual, es sencillo acceder al mismo y por medio de operaciones de manejo y concatenación de cadenas, crear nuestro archivo XML. Para acceder a cada uno de los campos obtenidos, simplemente indicaremos $nombreDelVector[‘nombreDelCampo’]. Debemos indicar del mismo modo que los caracteres “\t” introducidos en la cadena que va a conformar el archivo XML de salida no son más que saltos de línea, que nos ayudarán a que dicha salida sea lo más limpia y formateada posible. Para finalizar el procesado de este bucle debemos tener cuidado con los caracteres especiales de XML. Si recordamos las dos lecciones anteriores, ciertos caracteres llamados “entidades predefinidas” como pueden ser “<” y “&” deben ser reescritos para que el lenguaje XML no los interprete como elementos propios. Esto lo haremos utilizando estas funciones de manejo de cadenas: U.D. IV – Web 2.0 181 $row[‘texto’] $row[‘texto’] $row[‘texto’] $row[‘texto’] = = = = str_replace("&", "&", $row['texto']); str_replace("<", "<", $row['texto']); str_replace(">", "&gt;", $row['texto']); str_replace("\"", "&quot;", $row['texto']); Para finalizar el bucle, cerraremos la etiqueta que estamos generando y volveremos a realizar el mismo proceso para cada uno de los registros que componen nuestra tabla de datos. for($x = 0 ; $x < mysql_num_rows($resultID) ; $x++){ $row = mysql_fetch_assoc($resultID); $xml_output .= "\t<entrada>\n"; $xml_output .= "\t\t<fecha>" . $row[fecha] . "</fecha>\n"; // Creando las entidades XML necesarias para evitar errores de proceso $row[‘texto’] = str_replace("&", "&", $row['texto']); $row[‘texto’] = str_replace("<", "<", $row['texto']); $row[‘texto’] = str_replace(">", "&gt;", $row['texto']); $row[‘texto’] = str_replace("\"", "&quot;", $row['texto']); $xml_output .= "\t\t<texto>" . $row['texto'] . "</texto>\n"; $xml_output .= "\t</entrada>\n"; } Finalmente, una vez acabado el bucle cerraremos el elemento raíz de XML: $xml_output .= "</entradas>"; E imprimiremos la variable completa para que sea enviada en el contenido del documento: U.D. IV – Web 2.0 182 echo $xml_output; Una vez ejecutado este código, el archivo XML que obtendríamos quedaría como aparece a continuación: <?xml version="1.0"?> <entradas> <entrada> <fecha>19/08/2007</fecha> <texto>Bienvenido a mi nuevo blog. Espero que sea un punto de referencia en el mundo de la programación PHP y que con él puedas aprender muchas cosas.</texto> </entrada> <entrada> <fecha>8/10/2008</fecha> <texto>En esta entrada veremos la integración de PHP con MySQL y XML, para que podamos extraer los datos de una tabla sin problemas</texto> </entrada> <entrada> <fecha>24/01/2010</fecha> <texto>Cuando tengamos los datos en formato XML, podremos utilizarlos en nuestras aplicaciones Web 2.0</texto> </entrada> </entradas> Variaciones y mejoras Imaginemos ahora que tenemos que añadir un nuevo campo en nuestra base de datos, y en consecuencia, debemos enviarlo en el archivo XML final que se genera por medio del script PHP. Para ello deberíamos, una vez añadido en la tabla de la base de datos, hacer dos pequeñas modificaciones: La primera de ellas sería incluir el campo en la clausula SELECT para que sea obtenido desde la base de datos. Esto podríamos evitarlo colocando un SELECT *, pero como vimos en los temas de optimización, no es muy recomendable el uso de esta instrucción, ya que si en un futuro la tabla incluye más campos que no U.D. IV – Web 2.0 183 queremos procesar ni extraer en el archivo XML, también los obtendremos, lo que supondrá un desperdicio de memoria en el proceso de los mismos. La estructura que incluye la clausula SELECT quedaría entonces del siguiente modo: $query = "SELECT fecha, texto, autor FROM blog ORDER BY date DESC"; Una vez que ya disponemos del campo en el vector que utilizamos en PHP, incluirlo en el archivo XML de salida sería tan sencillo como incluir esta línea tras la introducción del texto del blog $xml_output .= "\t\t<autor>" . $row[‘autor’] . "</autor>\n"; En este caso el archivo XML devuelto quedaría del siguiente modo: <?xml version="1.0"?> <entradas> <entrada> <fecha>19/08/2007</fecha> <texto>Bienvenido a mi nuevo blog. Espero que sea un punto de referencia en el mundo de la programación PHP y que con él puedas aprender muchas cosas.</texto> <autor>José Manuel</autor> </entrada> <entrada> <fecha>8/10/2008</fecha> <texto>En esta entrada veremos la integración de PHP con MySQL y XML, para que podamos extraer los datos de una tabla sin problemas</texto> <autor>Miguel</autor> </entrada> <entrada> <fecha>24/01/2010</fecha> <texto>Cuando tengamos los datos en formato XML, podremos utilizarlos en nuestras aplicaciones Web 2.0</texto> <autor>Pedro</autor> </entrada> </entradas> U.D. IV – Web 2.0 184 Otra posible mejora a realizar sería introducir el número de elementos que queremos mostrar, limitando en ese caso el número de registros que son devueltos desde base de datos. Imaginemos por un momento que este documento XML va a ser procesado por un control AJAX de modo que en la página de inicio de una web corporativa mostremos las 3 últimas entradas del blog. Podemos obtener todos los registros y luego por medio de JavaScript tomar sólo los tres primeros, pero esto supondría que en el XML viajarían todos los que haya en la tabla y eso, cuando tengamos 500 entradas, puede ser un problema de tráfico considerable. Par hacer que nuestro script PHP sólo obtenga y envíe un número de registros determinado, sólo deberíamos modificar la clausula SELECT de base de datos del siguiente modo: $query = "SELECT fecha, texto, autor FROM blog ORDER BY date DESC LIMIT 0,3”; El único elemento que ha cambiado en este caso ha sido al final de la clausula, donde hemos añadido el parámetro LIMIT 0,3. Esto indica a MySQL que sólo debe devolvernos los 3 primeros resultados de la clausula SELECT que le enviamos, independientemente del número total de registros obtenidos. U.D. IV – Web 2.0 185 Capítulo 8 Sindicación En este capítulo nos vamos a adentrar en el mundo de la sindicación de contenidos, o dicho de otra manera más coloquial, cómo podemos “aprovechar” la información de otros sitios web (o del nuestro propio) para utilizarla en otros sitios web o en aplicaciones de escritorio. Cuando visitamos direcciones de Internet podemos “tomar prestado” su contenido e incluirlo en nuestro sitio por técnicas de copiar y pegar. Ahora bien, gracias a las técnicas de sindicación, si nosotros lo creemos oportuno, podemos publicar un archivo (una vez más en lenguaje XML) de tal modo que la información que queramos compartir se encuentre en el mismo. ¿Qué ventajas tiene esto? Desde luego muchísimas. Otros sitios web podrán alimentarse de nuestros contenidos y mostrarlos automáticamente como si fueran de ellos mismos, e incluso nosotros podremos integrar información de terceros en nuestro sitio web respetando la maquetación y reglas de estilo del mismo. Ahora bien, la mayor ventaja o funcionalidad que nos brida la sindicación de contenidos es la notificación a usuarios de las actualizaciones del mismo. Si un usuario se “suscribe” a nuestro archivo de sindicación, en el momento que actualicemos nuestra web, dicho archivo mostrará la nueva información. Si el usuario se ha suscrito a nuestra web través de una herramienta que cada media hora revisa si hay contenido nuevo, podemos asegurarnos de que el usuario va a enterarse muy pronto de que debe visitarnos para conocer nuestras novedades… La sindicación es un tema sencillo, ya que no es más que publicar contenidos en formato XML, pero que nos proporciona un gran abanico de posibilidades. En este capítulo vamos a explicar las más comunes y los formatos más utilizados. Al finalizar el estudio de este capítulo, serás capaz de: 9 Entender qué es la sindicación y para qué sirve 9 Crear tu propio feed RSS para publicar en un sitio web 9 Suscribirte a diferentes feeds desde tu navegador para estar al día de las novedades de un sitio web U.D. IV – Web 2.0 186 Lección 1 Sindicación ¿Qué es la sindicación de contenidos? Para comenzar, vamos a definir la sindicación de contenidos. Para ello, vamos a referenciarnos a Wikipedia, que en su página http://es.wikipedia.org/wiki/Redifusi%C3%B3n_web define la Redifusión Web (otra manera de llamar a la sindicación de contenido) del siguiente modo: Redifusión web (o sindicación web) es el reenvío o reemisión de contenidos desde una fuente original (sitio web de origen) hasta otro sitio web de destino (receptor) que a su vez se convierte en emisor puesto que pone a disposición de sus usuarios los contenidos a los que en un principio sólo podían tener acceso los usuarios del sitio web de origen. Habitualmente esta redifusión web se lleva a cabo mediante un contrato o licencia entre las partes: sitio web de origen y sitio web de destino. La redifusión de contenidos no es nada nuevo y hablando a nivel general, se puede aplicar tanto en la televisión, en la prensa, en la radio y “recientemente” se ha popularizado en Internet para contenidos web. En Internet se conoce mucho más bajo el anglicismo “sindicación de contenidos” que proviene de la palabra inglesa “syndication”. U.D. IV – Web 2.0 187 4.8.1_1 – Logotipo de sindicación RSS ¿Quién no lo ha visto en alguna web? Para aprovechar el potencial de la sindicación de contenidos web, haremos uso de los estándares más comunes, como son RSS (Really Simple Sindication) y Atom 4.8.1_2 – Esquema básico de funcionamiento de la sindicación de contenidos La fuente de sindicación: Feed RSS y Atom La fuente web (también llamada “web feed” o “feed” a secas) es el medio en el que vamos a distribuir nuestros contenidos. Básicamente se tratará de un fichero XML con un formato específico que podremos utilizar para incluir aquellos contenidos que queramos compartir con otros usuarios. Como hemos comentado anteriormente, los formatos más comunes de web feeds son RSS y Atom. Para decirlo de una manera un poco más coloquial, una fuente web pone a disposición contenidos a través de un fichero con contenido en XML. RSS y Atom son dos estándares de canales de información que contienen la “última” información de un sitio web que se actualiza frecuentemente. Como podemos suponer, esto es especialmente útil en periódicos online, blogs… Evidentemente en esta funcionalidad, como no podía ser de otro modo, se ha optado por la publicación de los contenidos en formato XML. Ahora no vamos a U.D. IV – Web 2.0 188 describir todas las ventajas que ellos supone, ya que lo hemos visto en anteriores capítulos, pero podemos quedarnos con que en este caso se ha optado por el XML sobre todo por la compatibilidad entre plataformas que nos proporciona. Actualmente y con la nube de términos que rodea a la Web 2.0, es muy común que se confunda el término fuente web con RSS, pero son dos cosas totalmente diferentes: RSS fue el primer estándar en sindicación de contenidos, que vio la luz en 1999 cuando en Netscape deciden iniciar con la sindicación de contenidos en su portal my.netscape.com En aquel momento se hablaba indistintamente de RSS o web feed, ya que no existía ningún otro tipo de formato disponible para realizar tareas de sindicación. Más adelante apareció un nuevo formato de sindicación de contenidos, llamado Atom, por lo que ya se fue separando el binomio web feed y RSS para dejar lugar a otros estándares de sindicación. Hay que tener claro en este caso que la fuente web o “web feed” es el fichero XML mientras que Atom y RSS son el formato o el estándar XML del fichero. Si deseas descargarte iconos de feed de manera totalmente gratuita para incluir en tu sitio o aplicación web, puedes hacerlo en la web http://www.feedicons.com/. Cada uno de los sitios web que integren tecnología de sindicación de contenidos puede tener tantos “canales” de información como desee. Por ejemplo un periódico online puede tener un canal de economía, otro de sociedad, deportes… La única restricción que se impone es que todos estos canales deben tener referenciado su correspondiente documento XML que contenga la información que se envía en el mismo. RSS: Sindicación Realmente Simple Como hemos comentado, RSS es un formato de publicación de web feeds. Antes de ver un ejemplo de formación de un documento válido, vamos a echar un vistazo a su definición: U.D. IV – Web 2.0 189 RSS es una familia de formatos de fuentes web codificados en XML. Se utiliza para suministrar a suscriptores de información actualizada frecuentemente. El formato permite distribuir contenido sin necesidad de un navegador, utilizando un software diseñado para leer estos contenidos RSS (agregador). A pesar de eso, es posible utilizar el mismo navegador para ver los contenidos RSS. Las últimas versiones de los principales navegadores permiten leer los RSS sin necesidad de software adicional. RSS es parte de la familia de los formatos XML desarrollado específicamente para todo tipo de sitios que se actualicen con frecuencia y por medio del cual se puede compartir la información y usarla en otros sitios web o programas. A esto se le conoce como redifusión web o sindicación web (una traducción incorrecta, pero de uso muy común). Veamos ahora un ejemplo de archivo RSS que contiene un canal de noticias y una serie de elementos: <?xml version="1.0"?> <rss version="2.0"> <channel> <title>Canal noticias de ejemplo</title> <link> http://www.midominio.com/noticias/ </link> <description>Todas las noticias sobre sindicación de contenidos.</description> <language> es</language> <item> <title>Post 1</title> <link>Link del post 1</link> <description>Descripción del post 1</description> <pubDate>Fecha de publicación del post 1</pubDate> </item> <item> <title>Post 2</title> <link>Link del post 2</link> <description>Descripción del post 2</description> <pubDate>Fecha de publicación del post 2</pubDate> </item> </channel> </rss> U.D. IV – Web 2.0 190 Como todo documento XML, lo primero que debemos indicar a la hora de crear un documento XML es la cabecera que defina que dicho documento debe ser interpretado de este modo. Para ello incluimos la siguiente línea: <?xml version="1.0"?> A continuación definiremos el elemento raíz del mismo como documento RSS y especificaremos también la versión: <rss version="2.0"> Llegado este punto, debemos definir la información del canal de información. Para esto hacemos uso del elemento <channel> y de los subelementos que contiene para indicar qué canal estamos visitando, una breve descripción del mismo, el idioma y el enlace al sitio web original donde podemos leerlo. Una vez creado el canal, podemos empezar a disponer elementos sobre el mismo, cada uno de estos “bloques de información” se añade dentro de la etiqueta <item>. A cada uno de nuestros elementos <ítem> se le puede especificar el título (etiqueta <title>), el enlace hacia el ítem en la web original (etiqueta <link> - muy útil si queremos que el usuario “aterrice” en nuestra web), la descripción (etiqueta <description>), el autor, la fecha de publicación,… Crea tu primer feed RSS desde PHP. Basándote en el ejemplo de la lección 3 del capítulo anterior, modifica el fichero XML generado con la información de los posts del blog para que sea compatible con RSS. Más adelante podrás probar a incluirlo en un lector de noticias para comprobar si has realizado correctamente dicha conversión Acceso a los feeds desde navegadores web Todo lo que hemos visto hasta ahora está muy bien: exportamos información desde los sitios web que no interese para poder compartirla sin mayores problemas, pero ¿necesitamos realmente una web que consuma estos contenidos o un lector de noticias para visualizarlos? La respuesta es NO. Todos los navegadores que hoy en día existen en el mercado tienen soporte para interpretar los diferentes feeds que nos encontraremos a lo largo y ancho de la web. Simplemente accediendo a la dirección de dichos feeds, los navegadores serán capaces de mostrarnos el contenidos de los mismos e incluso nos permitirán suscribirnos de modo que nos envíen notificaciones cuando haya nuevos elementos que visitar. U.D. IV – Web 2.0 191 4.8.1_3 – Internet Explorer 8 interpretando un feed RSS Agregadores de feeds Para poder hacer un correcto uso de los diferentes feeds que nos podamos encontrar, necesitamos alguna herramienta que nos los “controle” y nos notifique cuando hay cambios en alguno de ellos sin necesidad de que estemos revisándolos manualmente cada media hora. Para ayudarnos en esta tarea surgen los agregadores o lectores de feeds. Un agregador o lector de feeds es un software o aplicación web capaz de entender y mostrar la información de los documentos XML RSS o Atom y por tanto actúa como suscriptor a fuentes de información que contengan una página en formato RSS, Atom, etc. Como comentamos, un agregador tiene la característica de que va a mantener “ordenados” aquellos feeds a los que estemos suscritos y sobre todo va a ser capaz de notificarnos cuando se produzcan cambios en los mismos, de modo que podamos consultar la información actualizada de manera cómoda y rápida. U.D. IV – Web 2.0 192 Existen muchos agregadores disponibles en el mercado y estos suelen estar incorporados en herramientas que utilizamos actualmente. Para hacernos a una idea, todos los navegadores modernos incorporan un servicio de suscripción a feeds. Asimismo, lectores de correo como Outlook o Windows Live Mail incorporan este sistema, de modo que cuando haya novedades en un feed nos notificarán del mismo modo que si hubiéramos recibido un correo electrónico… Agregando un feed desde Internet Explorer En las siguientes líneas vamos a agregar un feed para que Internet Explorer lo tenga en cuenta y nos avise de los cambios que en él se produzcan. El primer paso que tenemos que hacer es navegar hasta el propio feed. Esto es sencillo ya que si la web contiene feeds, el icono de RSS que está situado en la barra del navegador se iluminará, indicándonos que hay fuentes disponibles: 4.8.1_4 – Ejemplo de una página web con fuentes RSS integradas Ahora sólo deberemos hacer click en el icono de la barra superior o en el enlace que está dispuesto a tal efecto dentro de la página para ir a la ventana con el contenido del feed. Cuando estemos en esta página, aparecerá una cabecera encima de todos los elementos que nos indica que estamos visitando una fuente que se actualiza con frecuencia y nos invita a suscribirnos: U.D. IV – Web 2.0 193 4.8.1_5 - Ventana de información de feeds en Internet Explorer 8 Si ahora hacemos click en el enlace “Suscribirse a esta fuente” nos aparecerá una ventana emergente que deberemos confirmar. En ella nos indica la carpeta en la que va a colocar dicha fuente y nos permite seleccionar si queremos crear un botón de acceso rápido en la barra de favoritos. En nuestro caso la dejaremos con las opciones con defecto y haremos click en “Suscribirse” 4.8.1_6 –Cuadro de dialogo de suscripción a fuentes A partir de este momento nuestro navegador va a estar “al tanto” de las actualizaciones que se produzcan y nos avisará de las mismas en la zona que habrá creado a tal efecto: U.D. IV – Web 2.0 194 4.8.1_7 – Zona donde se muestran las fuentes suscritas en Internet Explorer 8 Agregadores Web El sistema de agregación de feeds de Internet Explorer es muy fácil y rápido de manejar, pero algo limitado cuando queremos tener muchas fuentes disponibles y tiene el problema de que si no estamos físicamente en nuestro equipo no podremos acceder a las mismas. Para resolver este “problema” existen los marcadores basados en web, tres claros ejemplos son iGoogle, Mi Yahoo! o My MSN, que por medio de identificación de usuario y contraseña en su cuenta correspondiente nos permiten ver el contenido y mantener actualizados nuestros feeds desde cualquier lugar. 4.8.1_8 – Imagen de Google Reader, un lector de fuentes basado en web U.D. IV – Web 2.0 195 Capítulo 9 Microformatos A lo largo de este capítulo vamos a introducir un par de conceptos muy importantes en el desarrollo de la Web 2.0 y de la futura Web 3.0, como son los microformatos y la Web Semántica. Estos elementos nos van a permitir, de modo análogo a la los web feeds y la sindicación en general, que los programas que ejecutemos en nuestro ordenador puedan interpretar de algún modo la información que contiene una página web y presentárnosla de una manera algo especial. Supongamos por ejemplo que en la información de nuestra página incluimos nuestros datos de contacto. Si los colocamos sin más, dichos datos aparecerán y un usuario podrá localizarlos para llamarnos o para escribirnos un correo puntualmente. Ahora bien, con el uso de los microformatos, vamos a conseguir que el navegador del usuario "detecte" que allí se encuentra una tarjeta de visita y puede ofrecernos almacenarla automáticamente en nuestra libreta de direcciones para que podamos utilizarla posteriormente. Como comentamos, el potencial de estos elementos está todavía por explotar, pero si la difusión del uso de los mismos es elevada, las posibilidades, como podremos suponer son infinitas. Al finalizar el estudio de este capítulo, serás capaz de: 9 Entender los conceptos de Web Semántica y Microformatos 9 Hacer uso de los microformatos para introducir información personal en una página o aplicación web U.D. IV – Web 2.0 196 Lección 1 Microformatos ¿Qué es la web semántica? Para conocer el pilar base de los microformatos, la web semántica, vamos a referenciarnos a Wikipedia, que en su página http://es.wikipedia.org/wiki/Web_sem%C3%A1ntica define la web semántica del siguiente modo: La Web semántica (del inglés semantic web) es la "Web de los datos". Se basa en la idea de añadir metadatos semánticos y ontológicos a la World Wide Web. Esas informaciones adicionales —que describen el contenido, el significado y la relación de los datos— se deben proporcionar de manera formal, para que así sea posible evaluarlas automáticamente por máquinas de procesamiento. El objetivo es mejorar Internet ampliando la interoperabilidad entre los sistemas informáticos usando "agentes inteligentes". Agentes inteligentes son programas en las computadoras que buscan información sin operadores humanos El precursor de la idea, Tim Berners-Lee, intentó desde el principio incluir informacion semántica en su creación, la World Wide Web, pero por diferentes causas no fue posible. Por ese motivo introdujo el concepto de semántica con la intención de recuperar dicha omisión Sobre el marcado semántico no hay mucho estándar creado y como tal, las discusiones sobre el mismo se propagan en multitud de blogs y foros. En cualquier caso, en las mismas siempre se observa una pauta constante de progresivo descubrimiento de soluciones óptimas y de consenso sobre determinados problemas con los que nos encontramos día a día: ¿Cómo marcar un título? ¿Los datos de contactos de una empresa? ¿Qué elementos HTML debemos utilizar para marcar un catálogo de productos? Entre las respuestas a estos temas y las diferentes ideas de expertos (y no tan expertos) sobre esto se han ido formando los microformatos: descripciones formalizadas de las mejores prácticas a realizar para resolver un problema de marcado determinado. U.D. IV – Web 2.0 197 Qué son los microformatos Los microformatos son "formatos" porque se crean con la intención de estandarizar, pretendiendo que se acepten y que se tomen como solución común. Asimismo podemos deducir que el "micro" viene tanto por la poca documentación necesaria para definirlos con precisión como por la poca extensión de los problemas que resuelven. Lo que van a pretender es explicar exhaustivamente una pregunta concreta, pero en ningún caso van a ser un juego de herramientas completas para un desarrollador. Asimismo diremos que son "micro" porque están formados de pequeños fragmentos de HTML, lo que los convierten en estructuras portables y reutilizables que podemos utilizar para crear páginas web completas, válidas y semánticas. Los microformatos, como podemos entender con las descripciones que hemos visto hasta ahora, son soluciones estándar de marcado HTML o XHTML destinadas a usos concretos: hay estructuras de marcado que suelen utilizarse para ciertas necesidades. Si estas son correctas, rápidamente son consideradas como "buena práctica" y de ahí surge la recomendación y adaptación por parte de toda la comunidad de la solución propuesta. 4.9.1_1 – Un ejemplo de explotación de microformatos a través de Firefox ¿De qué elementos estaríamos hablando? Pues nada más lejos que elementos HTML estándar como pueden ser tablas, listas ordenadas o desordenadas, párrafos... Una vez que utilicemos un formato para resolver problemas comunes de representación de datos, podemos formalizar e identificar dichas estructuras por medio de, por ejemplo, el atributo "class". Llegados a este punto ya tendremos un fragmento de código HTML identificable, reutilizable, considerado válido y consistente a través de distintos sitios y desarrolladores. En este caso estamos hablando de fragmentos estructurales de código, pero una clase de microformato es mucho más reducida que esto. Se va a limitar a la adopción de convenciones para determinados tipos de enlaces XHTML y que por U.D. IV – Web 2.0 198 tanto nos expresar mediante el atributo "rel" significados complejos en un enlace que sean tomados como válidos por el resto de usuarios. Ejemplos reales de microformatos son el rel="nofollow" propuesto por los motores de búsqueda y sus arañas de exploración, el rel="tag" creado por Technorati, otra serie de significados convenidos para expresar relaciones humanas, etc. Algunas de las características que hacen atractivos los microformatos son las siguientes: 9 Su aplicación es inmediata y solucionan problemas concretos y reales que nos podemos encontrar en el día a día. Como además el procesado de las páginas que los contienen es realmente rápida, los motores de búsqueda y páginas que aprovechen estos elementos pueden beneficiarse de esta tipo de tecnología a un coste de procesamiento realmente bajo. La proliferación de estos elementos, como podemos suponer, es realmente rápida. 9 No existen de barreras de entrada. Todo el mundo puede proponer nuevos microformatos, ya que el coste es cercano a cero tanto para crearlos como para adoptar microformatos propuestos por terceros en otros desarrollos ya existentes. 9 Por medio de su interpretación, permiten la adaptación a XHTML de otros elementos existentes y efectivos. De hecho, Technorati, cuyos desarrolladores son los principales evangelistas e impulsores de los microformatos, han reformulado como microformato "vCard", que se ha convertido en "hCard", para el marcado de tarjetas de visita, e "iCal" que pasa a ser "hCalendar", para el marcado de fechas y eventos. 9 Encajan de forma rápida e intuitiva con el paradigma del marcado semántico, confirmando que las buenas prácticas son un elemento real y de uso extendido en la web. 9 Evidentemente, al estar basados en XHTML y en las reglas que lo componen, son totalmente compatibles con el estándar del W3C. La extensibilidad del atributo "rel" se logra mediante las características de modularidad de XHTML. Los microformatos, como acabamos de ver, ofrecen una solución inmediata y "desde abajo" a la solución de pequeños problemas que nos encontramos cada día en la web y en nuestros desarrollos. Este enfoque ofrece resultados rápidos y extremas facilidades de popularización e implementación, es por esto que si siguen popularizándose y fomentándose, los microformatos pueden ser el próximo paso significativo de la evolución del marcado en la web y de la creación de estándares consensuados con la comunidad de desarrolladores web. U.D. IV – Web 2.0 199 Ejemplos de microformatos A continuación vamos a ver un ejemplo real de inclusión de datos personales en un blog por medio de un microformato: Si no utilizamos microformatos, nos serviremos del código HTML estándar, y en su caso, para facilitar la portabilidad de la información a otras plataformas, incluiremos la posibilidad de descargar un archivo ".vcf" que automáticamente se instala en la libreta de direcciones de Outlook o iCal de los usuarios que lo descarguen y ejecuten. <div class="direccion"> <div class="nombre">Homer Simpson</div> <div class="web"><a href="http://www.simpsons.com/">Simpsons.com</a></div> </div> Esto está muy bien formado, pero hay ciertos problemas asociados al mismo: Lo que nosotros indicamos como dirección, otra persona puede indicar como "address" o "contact info" o similar. La información que indiquemos en tal caso no es "aprovechable" por gestores automatizados ya que la máquina no va a ser capaz de reconocer que dentro de este código HTML hay datos de contacto reales. Si a pesar de esto el usuario reconoce efectivamente la dirección y quiere importarla en su gestor de direcciones o correo electrónico, tiene varias opciones para realizarlo: La primera de ellas pasa por copiar y pegar manualmente todos los datos que aparecen en su registro de direcciones. Como además de esto hemos creado un archivo de agenda en formato ".vcf", el usuario podrá importarlo manualmente en su libreta de un modo un poco más sencillo, pero que representa un problema de mantenimiento, ya que la dirección estará en el sitio web y en el archivo, teniendo que modificar ambos en cada uno de los cambios que se realicen. Al utilizar microformatos, vamos a estructurar el código HTML que contiene la información de contacto siguiendo unas convenciones establecidas por la comunidad de microformatos denominada hCard. Es importante seguir a rajatabla este punto ya que del hacerlo correctamente dependerá que el microformato sea legible por los visitantes. Si lo hacemos correctamente, el usuario lo podrá ver en el navegador, pero además podrá importar esa información en su libreta de direcciones sin mayor esfuerzo. U.D. IV – Web 2.0 200 El microformato hCard, no es más que una traducción literal del estándar vCal definido por la IETF a XHTML, y que como podemos suponer, es el formato empleado por las aplicaciones de Libreta de Direcciones más comunes. ¿Por qué inventar otras posibilidades si vCard funciona y es perfectamente aplicable? Formato vCard (versión resumida) BEGIN:VCARD VERSION:3.0 N:Simpson;Homer FN:Homer Simpson URL:http://www.simpsons.com/ ORG:simpsons.com END:VCARD Microformato hCard (versión equivalente) <div class="vcard"> <a class="url fn" href="http://www.simpsons.com/">Homer Simpson</a> <div class="org">simpsons.com</div> </div> Una vez que tenemos nuestro microformato listo para utilizarse, podemos publicarlo en nuestra web y de este modo hacer que toda la comunidad se beneficie de esta estandarización. Estas buenas prácticas pueden ser utilizadas en numerosas aplicaciones diferentes, por nombrar algunas de ellas, en la web alzado.org disponen de una agenda de eventos basada en microformatos y se han desarrollado aplicaciones como X2V, extractor de microformatos desarrollado por Brian Suda. U.D. IV – Web 2.0 201 Qué se pretende mejorar con los microformatos La web debe continuar con su mejora continua, pero dicha mejora no puede basarse en destruir los estándares actuales con nuevos formatos. Es mejor y más efectivo reutilizarlos y mejorarlos a base de pequeños pasos. 9 Sobre la web existente se han llegado a acuerdos para evolucionarla, por medio de la redacción de especificaciones breves, comprensibles y de rápida aplicabilidad con el fin de que los desarrolladores y publicadores de contenido las acepten sin problemas. Los fragmentos de código que son fruto de dichos acuerdos poco a poco pasan a ser módulos “semánticos” e identificables dentro del propio documento web. 9 Cualquier persona con unos conocimientos y base de XHTML puede publicar en su sitio web su propia tarjeta en formato hCard o incluir eventos con el uso de hCalendar. La difusión por tanto de estos elementos y su funcionalidad inmediata es un punto a favor de dicha tecnología. 9 Al adoptar una convención o "buena práctica" permitimos que al enviar una URI a buscadores y a otros servicios sea tratada como direcciones de contacto, eventos o cualquier otro tipo de información que esté "microformateada" en su interior, creando un nuevo modo de "entender" la web. 9 El usuario que comparta su información es el dueño de los cambios que en ellos se produzcan y por tanto, actualizar la información de contacto o sus eventos (del mismo modo que un feed web), se solucionaría por medio de una petición a dicha página para que se refresque la información. Asimismo si el uso de los microformatos se estandariza de este modo, una persona que quiera mantener su información actualizada sólo debería de hacerlo en la página referenciada en el microformato para que todo el mundo tuviera acceso a dichos cambios. 4.9.1_2 – Logotipo de referencia a los microformatos U.D. IV – Web 2.0 202 El futuro de los microformatos A fecha de hoy, los microformatos no dejan de ser una brillante mejora en proceso experimental que soluciona de manera creativa pequeños problemas de la web 2.0 con soluciones tremendamente creativas, pero... ¿Qué podemos esperar del futuro de los microformatos? En el fututo los microformatos deben tomar un papel decisivo en el intercambio de información y en las redes sociales. Por el uso de los mismos el tráfico de información puede acelerarse enormemente, es por esto que los grandes portales de información o los relativos a redes sociales están muy interesados en el desarrollo de los mismos. Asimismo, los usuarios recibirán información de una manera sencilla y a un bajo coste, con la certeza de acceder a datos actualizados y en cualquier momento del día. En cualquier caso el futuro de esta iniciativa depende de que se construyan servicios que los utilicen y que aporten valor al usuario final. Si no podemos utilizarlo de ningún modo, difícilmente vamos a conseguir motivación para que los incluyamos en nuestras páginas web o aplicaciones personales, pero si esto nos abre un mundo de información, como el caso de los web feeds, tenemos el futuro de los microformatos más que asegurado. 4.9.1_3 – Microformats.org, web de referencia sobre los microformatos U.D. IV – Web 2.0 203 Capítulo 10 Integración con Servicios Web Dentro del marco de la web 2.0, como podremos suponer, surgen cada día nuevos servicios y utilidades que podemos integrar dentro de nuestras páginas web y aplicaciones. A lo largo de este capítulo vamos a ver una de las más importantes que hoy en día podemos encontrar: Los Servicios Web Por medio de los servicios web vamos a poder obtener información personalizada o realizar tareas en servidores remotos con un coste mínimo de tráfico desde el cliente al servidor y viceversa. Los servicios web se basan una vez más en XML y por medio de este metalenguaje van a ser capaces de en primer lugar indicarnos qué operaciones podemos hacer con ellos. Opciones tan variopintas como informarnos acerca del pronóstico meteorológico de una determinada zona o proporcionarnos el estado de una reserva hotelera e incluso formalizarla son algunas de las que podremos realizar por medio de los mismos. Una vez que conozcamos las opciones y los datos que el servicio necesita para funcionar correctamente, realizaremos una petición en un formato determinado desde nuestra aplicación hasta el servicio correspondiente. Cuando reciba dichos datos, comenzará a ejecutar las operaciones necesarias para servirnos y una vez finalizadas nos devolverá la respuesta a dichas operaciones, que podremos interpretar como si de un feed web se tratase. En este capítulo, además definiremos todos los conceptos relativos a servicios web y aprenderemos a conectarnos a uno de ellos con el fin de intercambiar información con el mismo. Al finalizar el estudio de este capítulo, serás capaz de: 9 Entender todos los conceptos relacionados con servicios web y su protocolo 9 Conectarte a un servicio web desde PHP y obtener el estado meteorológico de una ciudad U.D. IV – Web 2.0 204 Lección 1 Integración con Servicios Web Conceptos básicos Para comenzar a entender los servicios web y el funcionamiento de los mismos, vamos a ver una definición más o menos coloquial que podemos encontrar en la página http://es.wikipedia.org/wiki/Servicio_web: Un servicio web (en inglés, Web service) es un conjunto de protocolos y estándares que sirven para intercambiar datos entre aplicaciones. Distintas aplicaciones de software desarrolladas en lenguajes de programación diferentes, y ejecutadas sobre cualquier plataforma, pueden utilizar los servicios web para intercambiar datos en redes de ordenadores como Internet. La interoperabilidad se consigue mediante la adopción de estándares abiertos. Las organizaciones OASIS y W3C son los comités responsables de la arquitectura y reglamentación de los servicios Web. Para mejorar la interoperabilidad entre distintas implementaciones de servicios Web se ha creado el organismo WS-I, encargado de desarrollar diversos perfiles para definir de manera más exhaustiva estos estándares. A continuación pasaremos a definir los elementos que componen los Servicios Web, para más adelante ver cómo están relacionados entre sí. XML, SOAP, WSDL, UDDI Como hemos visto, en los servicios web confluyen una serie de intercambios de mensajes que pueden darse a través del uso de diferentes tecnologías. Vamos a ver una por una todas ellas: XML: Ya hemos definido esta tecnología con anterioridad, pero en cualquier caso es un elemento que conviene repasar. XML es es un metalenguaje extensible de etiquetas desarrollado por el World Wide Web Consortium (W3C). Es una simplificación y adaptación del SGML y permite definir la gramática de lenguajes específicos (de la misma manera que HTML es a su vez un lenguaje definido por SGML). Por lo tanto XML no es realmente un lenguaje en particular, sino una manera de definir lenguajes para diferentes necesidades. Algunos de estos lenguajes que usan XML para su definición son XHTML, SVG, MathML. U.D. IV – Web 2.0 205 SOAP (siglas de Simple Object Access Protocol): es un protocolo estándar que define cómo dos objetos en diferentes procesos pueden comunicarse por medio de intercambio de datos XML. Este protocolo deriva de un protocolo creado por David Winer en 1998, llamado XML-RPC. SOAP fue creado por Microsoft, IBM y otros y está actualmente bajo el auspicio de la W3C. Es uno de los protocolos utilizados en los servicios Web. WSDL (Web Services Description Language): es un formato XML que se utiliza para describir servicios Web (algunas personas lo leen como wisdel). La versión 1.0 fue la primera recomendación por parte del W3C y la versión 1.1 no alcanzó nunca tal estatus. La versión 2.0 se convirtió en la recomendación actual por parte de dicha entidad. UDDI: son las siglas del catálogo de negocios de Internet denominado Universal Description, Discovery and Integration. El registro en el catálogo se hace en XML. UDDI es una iniciativa industrial abierta (sufragada por la OASIS) entroncada en el contexto de los servicios Web. UDDI es uno de los estándares básicos de los servicios Web cuyo objetivo es ser accedido por los mensajes SOAP y dar paso a documentos WSDL, en los que se describen los requisitos del protocolo y los formatos del mensaje solicitado para interactuar con los servicios Web del catálogo de registros. Puedes obtener más información sobre estos términos en su página oficial de Wikipedia: 9 9 9 9 XML: http://es.wikipedia.org/wiki/XML SOAP: http://es.wikipedia.org/wiki/SOAP WSDL: http://es.wikipedia.org/wiki/WSDL UDDI: http://es.wikipedia.org/wiki/UDDI Historia y evolución de los servicios web Los servicios web surgieron como método para formalizar la comunicación entre diferentes lenguajes de programación y diferentes máquinas. Cuando tenemos que interconectar estos sistemas, el único modo de hacerlo es a través de archivos que uno de los sistemas pueda escribir y que otro sea capaz de leer correctamente. Anteriormente a los servicios web, surgieron intentos de crear estándares, pero la propietariedad de los mismos supuso una barrera en la estandarización y puesta en marcha de los mismos. Otro gran problema al que se tuvo que hacer frente es que se hacía uso de RPC (Remote Procedure Call) para realizar la comunicación entre las máquinas o lenguajes. Esto supone un potenciar riesgo de seguridad, a la vez que implementarlo a través de Internet es prácticamente imposible. U.D. IV – Web 2.0 206 Los servicios web surgieron para finalmente poder lograr la tan esperada comunicación entre diferentes plataformas y en 1999 se comenzó a plantear un nuevo estándar, el cual terminaría utilizando las tecnologías que hemos visto: XML, SOAP, WSDL, y UDDI. 4.10.1_1 – Esquema de funcionamiento de un servicio web Muchos caerán en el error de limitar el uso de los servicios web al protocolo HTTP, pero en cualquier caso, los servicios web no fueron creados para el uso bajo un protocolo particular. Podríamos perfectamente utilizar SOAP sobre FTP o incluso SMTP. Se utiliza principalmente bajo HTTP porque es el protocolo más difundido y tiene menos problemas de funcionamiento por restricciones de firewalls o proxys. Integración de servicios web con PHP Podríamos comenzar el proceso de implementación de servicios web directamente desde funciones nativas de PHP, ya que para invocar y consumir estos servicios no se necesita más que un lenguaje de programación que permita realizar peticiones HTTP. No obstante vamos a hacer uso de una librería de programación que nos permite manejar el tráfico de mensajes de un modo más sencillo: NuSOAP U.D. IV – Web 2.0 207 NuSOAP es un kit de herramientas (ToolKit) para desarrollar Web Services bajo el lenguaje PHP. Está compuesto por una serie de clases que nos harán mucho más fácil el desarrollo de Web Services. Provee soporte para el desarrollo de clientes (aquellos que consumen los Web Services) y de servidores (aquellos que los proveen). NuSOAP está basado en SOAP 1.1, WSDL 1.1 y HTTP 1.0/1.1 Instalación de NuSOAP en nuestro servidor web La instalación de este componente o librería es bastante sencilla, para obtenerlo deberemos acceder a la página http://sourceforge.net/projects/nusoap/ y descargar el archivo comprimido que contiene la librería. Una vez en nuestro ordenador, lo descomprimiremos en un directorio de nuestro servidor web y ya podremos hacer uso de NuSOAP desde nuestra programación PHP. Para comenzar a consumir un servicio web, el primer paso que debemos realizar es ir a su página de definición y ver los diferentes métodos y opciones que nos brinda. Para ello y en nuestro ejemplo, accederemos a la siguiente dirección: http://www.webservicex.net/globalweather.asmx, que contiene la definición en lenguaje WSDL del mismo: U.D. IV – Web 2.0 208 4.10.1_2 – Descripción del servicio web en su página Como podemos ver en la captura adjunta, se nos muestran las funciones y métodos de los que disponemos. Podemos, si queremos, hacer click sobre las mismas y acceder a una pantalla adicional en la que están definidas en profundidad y se nos dan detalles de cómo acceder a las mismas y qué parámetros debemos proporcionarles: U.D. IV – Web 2.0 209 4.10.1_3 – Página con información del método GetWeather() y formulario de prueba Bajo este formulario se nos indica el formato de la petición y respuesta que obtendremos al invocar el método: 4.10.1_4 – Detalle de la petición y respuesta al método GetWeather() U.D. IV – Web 2.0 210 Con estos datos, podemos empezar la programación en PHP y preparar la consulta al método GetWeather sin mayores problemas. Sólo deberemos tener en cuenta que dicho método necesita: 9 Como variables de entrada “CityName” y “CountryName”, que deberán de ser del tipo String. En nuestro caso enviaremos "Zaragoza / Aeropuerto” como nombre de ciudad y “Spain” como país. 9 Como elementos de salida del mismo “GetWeatherResult”, cadena también del tipo String. Vamos a ver ahora el fragmento de código necesario para solicitar dicha petición y comentaremos el funcionamiento de las secciones referentes al procesamiento de dicho servicio: <?php // Inclusión de la librería NuSOAP require_once('lib/nusoap.php'); //Indicamos la ruta del archivo WSDL del servicio web $oSoapClient = new soapclient('http://www.webservicex.net/globalweather.asmx?WSDL', true); //Devolvemos error si no hemos podido conectar if ($sError = $oSoapClient->getError()) { echo "No se pudo realizar la operación [" . $sError . "]"; die(); } //Inicializamos los parámetros y obtenemos la respuesta $aParametros = array("CityName" => "Zaragoza / Aeropuerto", "CountryName" => "Spain"); $aRespuesta = $oSoapClient->call("GetWeather", $aParametros); // Existe alguna falla en el servicio? if ($oSoapClient->fault) { // Si echo 'No se pudo completar la operaci&oacute;n'; die(); } else { // No $sError = $oSoapClient->getError(); }?> // Hay algun error ? if ($sError) { // Si echo 'Error:' . $sError; } <html> <body> Contenido de la respuesta: <?php print_r($aRespuesta);?> </body> </html> U.D. IV – Web 2.0 211 La respuesta obtenida tras ejecutar el código es la siguiente: 4.10.1_5 – Respuesta de la ejecución del código mostrado con la llamada al servicio web Como podemos ver, el resultado de la ejecución nos devuelve un vector con información acerca del estado meteorológico de una determinada ciudad, que podemos aprovechar para lo que deseemos. Vamos a comentar ahora las líneas de código más significativas y su funcionalidad: require_once('lib/nusoap.php'); Por medio de esta línea establecemos la referencia necesaria para que la librería NuSOAP se cargue y podamos hacer uso de sus propiedades y métodos $oSoapClient = new soapclient('http://www.webservicex.net/globalweather.asmx?WSDL', true); Le indicamos a NuSOAP dónde está el servicio web que deseamos consumir y le proporcionamos acceso a su archivo WSDL, donde se encuentra la información necesaria que indica cómo se deben realizar las peticiones y obtener las respuestas $aParametros = array("CityName" => "Zaragoza / Aeropuerto", "CountryName" => "Spain"); $aRespuesta = $oSoapClient->call("GetWeather", $aParametros); U.D. IV – Web 2.0 212 Creamos un nuevo vector en el que indicamos los parámetros que vamos a utilizar, así como sus valores. Cuando los tenemos hacemos la llamada a la función GetWeather y le enviamos los parámetros que necesita. if ($oSoapClient->fault) { // Si echo 'No se pudo completar la operaci&oacute;n'; die(); } else { // No $sError = $oSoapClient->getError(); // Hay algun error ? if ($sError) { // Si echo 'Error:' . $sError; } } Verificamos el estado de la respuesta y en el caso de que se haya devuelto error por la petición, informamos al usuario del mismo <?php print_r($aRespuesta);?> Finalmente mostramos por pantalla la respuesta de la ejecución del servicio, dando el programa por finalizado. Prueba tu mismo el código que indicamos y haz una petición al servicio web para obtener el tiempo que hace ahora mismo en Zaragoza. Si quieres mejorarlo, intenta mediante operaciones de manejo de cadenas dar formato al texto que devuelve por medio de una tabla de HTML. U.D. IV – Web 2.0 213