Desarrollo de aplicaciones HTML5 para AppUp℠: Parte 3, Una aplicación RSS

 

Presentamos el tercero de los capítulos de la serie de @jefftranter sobre cómo programar con HTML5 y cómo subir estas aplicaciones a AppUp.

El primero de los capítulos está disponible en este enlace.

El segundo, aquí.

 

Introducción


En esta tercera entrega de nuestra serie sobre el desarrollo de aplicaciones HTML5 para AppUp, vamos a ver un ejemplo de aplicación que puede leer y mostrar los artículos de un feed RSS web. Se ilustran algunas características de HTML5, cómo conseguir el contenido de un sitio web y el análisis del formato XML.

 

El Protocolo RSS


Nuestra aplicación de ejemplo tendrá la función de leer y mostrar los artículos de los servidores que soportan el protocolo RSS.

RSS correspondía inicialmente a RDF Site Summary, pero ahora se refiere a menudo como Really Simple Syndication. Se trata de un formato estándar para la publicación de información actualizada frecuentemente como artículos de noticias, foros y blogs. Un documento RSS o "feed", utiliza un formato XML estándar. Un programa, a menudo conocido como un lector de RSS, puede suscribirse a una o más fuentes RSS y mostrar la información a un usuario. La principal ventaja de RSS es que permite a un usuario acceder a la información proveniente de diferentes sitios en los que esté interesado, y ver desde un solo lugar.

Como los archivos RSS son esencialmente XML de texto con formato, el archivo RSS en sí es relativamente fácil de leer, tanto por procesos automatizados como por los un usuario. Un archivo de ejemplo podría tener un contenido tal como se muestra en la Figura 1. Esto podría ser colocado en cualquiera de los protocolos de comunicación apropiados para la recuperación de archivos, tales como HTTP o FTP, y  un software de lectura, usando la información para presentar una pantalla de lectura para el usuario final.

Hay varias versiones diferentes de RSS. Para simplificar el ejemplo sólo utilizaremos la versión 2.0, el que la mayoría de los sitios están utilizando.

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
        <title>RSS Title</title>
        <description>This is an example of an RSS feed</description>
        <link>http://www.someexamplerssdomain.com/main.html</link>
        <lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000 </lastBuildDate>
        <pubDate>Mon, 06 Sep 2009 16:45:00 +0000 </pubDate>
        <ttl>1800</ttl>
        <item>
                <title>Example entry</title>
                <description>Here is some text containing an interesting description.</description>
                <link>http://www.wikipedia.org/</link>
                <guid>unique string per item</guid>
                <pubDate>Mon, 06 Sep 2009 16:45:00 +0000 </pubDate>
        </item>
</channel>
</rss>

Figura 1: Ejemplo de datos RSS

 

La Aplicación


Nuestra aplicación de ejemplo tiene un canal RSS a partir de una URL única y muestra un resumen de las entradas de la fuente (por lo general se trata de titulares de noticias o publicaciones en blogs). En la parte superior se ofrecen botones para volver a la pantalla de inicio, navegar adelante y atrás, la actualización de la pantalla, cambiar la configuración y cerrar la aplicación. La figura 2 muestra un ejemplo de pantalla típica que utiliza la alimentación por defecto de contenidos del sitio de noticias CNN. 


Figura 2: Pantalla principal del lector RSS

Si haces clic en un enlace te dirigirá al artículo (en este caso un titular de prensa), accediendo al mismo de manera completa. Un ejemplo se muestra en la Figura 3. 


Figura 3: Visor del artículo RSS

La figura 4 muestra la pantalla de configuración. Permite al usuario cambiar la dirección del feed RSS. Los sitios que ofrecen RSS suelen publicar estas direcciones URL. Aquí hemos entrado una dirección distinta de la predeterminada. Al hacer clic en Guardar volverá a la pantalla principal y el contenido se actualizará para reflejar el nuevo feed RSS

Figura 4: Pantalla configuración del lector RSS

 

Cómo funciona


Echemos un vistazo a cómo funciona nuestra aplicación. Todos los archivos del código fuente descritos en este artículo pueden ser descargados desde aquí.

En primer lugar, para cumplir con los requisitos del Encapsulator tenemos un archivo llamado icon.png, icono de la aplicación.

Vamos a utilizar un par de hojas de estilo, de app.css y de content.css. Estos establecer algunos parámetros sobre interfaz de la aplicación y experiencia de usuario, como la imagen de fondo y la apariencia de un botón, y se hace referencia en los archivos HTML que utilizan.

Ahora vamos a ver el punto de partida, el archivo principal index.html, archivo HTML que se muestra en el Listado 1. Este archivo carga la hoja de estilo, y el app.css index.js, archivo JavaScript. A continuación, crea las seis imágenes con un clic para Inicio, Atrás, Adelante, Actualizar, Configuración y Cerrar, y los asocia con las funciones de JavaScript que se ejecuta cuando se hace clic. Por último, crea un iframe cuyo contenido proviene de la content.html archivo.

<!DOCTYPE HTML>
<html>
  <head>
    <title>HTML5 RSS Reader</title>
    <link href="app.css" rel="stylesheet" type="text/css"/>
    <script src="index.js" type="text/javascript"></script>
  </head>
  <body>
    <nav>
      <ul class="navigation">
        <li><a href="#" onclick="home()"><img src="images/home.png" title="Home"/></a></li>
        <li><a href="#" onclick="back()"><img src="images/back.png" title="Back"/></a></li>
        <li><a href="#" onclick="forward()"><img src="images/forward.png" title="Forward"/></a></li>
        <li><a href="#" onclick="reload()"><img src="images/refresh.png" title="Refresh"/></a></li>
        <li><a href="#" onclick="settings()"><img src="images/applications.png" title="Settings"/></a></li>
        <li><a href="#" onclick="closeApplication()"><img src="images/close.png" title="Close"/></a></li>
      </ul>
    </nav>
    <iframe id="frameId" src="qrc:/content.html" width="100%" height="90%"></iframe>
  </body>
</html>

Listado 2: archivo content.html

Echemos un vistazo a onFrameLoad function () en rss.js, que se muestra en el Listado 3. Si la variable xmlhttp es nulo, llamamos getXmlHttpObject () que crea una instancia de un objeto XMLHttpRequest (). Entonces llamamos a getRSS () con la ruta de la URL del feed RSS del sitio.

<!DOCTYPE HTML>
<html>
  <head>
    <title>RSS Viewer</title>
    <link href="content.css" rel="stylesheet" type="text/css"/>
    <script src="rss.js" type="text/javascript"></script>
  </head>
  <body id="bodyId" onload="onFrameLoad()">
  </body>
</html>

Listado 3: Funcionamiento del onFrameLoad desde el rss.js

Examinando getRSS function () mostrado en el Listado 4, establece la función getXmlDoc, que se llamará cuando se cambie de estado, y luego debemos de crear una solicitud HTTP GET a la URL.

function onFrameLoad()
{
    if (xmlhttp == null)
        xmlhttp = getXmlHttpObject()
    getRSS(top.rss_path)
}

Listado 4: Función getRSS desde el archivo rss.js

Cuando la solicitud XML al HTTP se ha completado, la función getXmlDoc es llamada. Mirar el código para esta función (Listado 5), si el estado es correcto, pide parseRSS () con el contenido obtenido XML. Si el estado no es correcto, se muestra un mensaje de error al usuario. La causa más probable de un error aquí es que no se está ejecutando la aplicación desde el programa envoltorio Encapsulator.

function getXmlDoc()
{
    if (xmlhttp.readyState == 4)
    {
        if (xmlhttp.status == 200) {
            var xmlDoc = xmlhttp.responseXML
            parseRSS(xmlDoc)
        } else {
            body = document.getElementById('bodyId')
            if (xmlhttp.statusText != '')
                body.innerHTML = '<div><strong>Error: </strong>' + xmlhttp.statusText + '</div>'
            else
                body.innerHTML = '<div><strong>Error: </strong>Are you trying to run this example outside of Encapsulator?</div>'
        }
    }
}

Listado 5: Función getXmlDoc desde el archivo rss.js

La función ParseRSS () (Listado 6) es el último en describir y hace la mayor parte de las tareas. En primer lugar, comprueba que el XML es devuelto en RSS 2.0. Si no, se presenta un mensaje de error.

A continuación, obtiene una lista de los titulares, descripción, y publicación de las fechas de todos los elementos del documento XML, generando una lista en formato HTML de la información que se establece como el cuerpo del documento HTML. Por último, si sale algún error, lo captura y muestra un mensaje de advertencia.

function parseRSS(xmlDoc) {
    try {
        if (!xmlDoc)
            throw 'Error during load of RSS'
        var rss = xmlDoc.getElementsByTagName('rss')
        if (rss && rss[0].getAttribute('version') != '2.0')
        {
            body = document.getElementById('bodyId')
            body.innerHTML = '<div><strong>Content is not RSS version 2.0</strong></div>'
            return
        }
        var channel = xmlDoc.getElementsByTagName('channel')
        if (channel && channel.length > 0) {
            var channelNode = channel.item(0)
            var childs = channelNode.childNodes
            var html = ''
            for (var i = 0; i < childs.length; i++) {
                var node = childs.item(i)
                var top_title
                var top_link
                if (node.localName == 'title') {
                    top_title = xmlDoc.getElementsByTagName('title')[0].textContent
                } else if (node.localName == 'description') {

                } else if (node.localName == 'link') {
                    top_link = xmlDoc.getElementsByTagName('link')[0].textContent
                } else if (node.localName == 'language') {

                } else if (node.localName == 'item') {
                    body = document.getElementById('bodyId')
                    var items = xmlDoc.getElementsByTagName('item')
                    if (top_title && top_title != '') {
                        html += '<div>'
                        html += '<a href="' + top_link.textContent +'">'
                        html += '<h1><strong>'
                        html += top_title
                        html += '</strong></h1>'
                        html += '</a>'
                        html += '</div>'
                    }
                    html += '<ol>'
                    for (i = 0; i < items.length; i++) {
                        node = items.item(i)
                        var title = node.getElementsByTagName('title')[0]
                        var description = node.getElementsByTagName('description')[0]
                        var link = node.getElementsByTagName('link')[0]
                        var pubDate = node.getElementsByTagName('pubDate')[0]
                        var guid = node.getElementsByTagName('guid')[0]
                        html += '<li>'
                        html += '<a href="' + node.getElementsByTagName('link')[0].textContent +'">'
                        html += '<strong id="title">' + node.getElementsByTagName('title')[0].textContent + '</strong>'
                        html += '</a>'
                        html += '<br>'
                        html += '<blockquote>' + node.getElementsByTagName('description')[0].textContent + '</blockquote>'
                        html += '<div>'
                        html += '<small id="right">Publication date: ' + pubDate.textContent + '</small>'
                        html += '</div><br><br></li>'
                    }
                    html += '</ol>'
                    body.innerHTML = html
                    break
                }
            }
        }
    }
    catch(err) {
        body = document.getElementById('bodyId')
        body.innerHTML = '<div><strong>' + err + '</strong></div>'
    }
}

Listado 6: Función parseRSS desde el archivo rss.js

El archivo index.js (Listado 7) tiene funciones JavaScript para las llamados de los botones en la parte superior de la interfaz de usuario. Cada función es más o menos trivial y requiere una línea de código. También hay algo de inicialización hecho aquí requerido en la carga inicial.

top.default_path = "http://rss.cnn.com/rss/cnn_topstories.rss"
top.rss_path = top.default_path

function start()
{
    window.homeLocation = getFrame().contentDocument.location.href
}

window.onload = start

function closeApplication()
{
    intel.adp.encapsulator.closeapplication()
}

function getFrame()
{
    return document.getElementById('frameId')
}

function back()
{
    window.history.back()
}

function forward()
{
    window.history.forward()
}

function home()
{
    getFrame().contentDocument.location.assign(window.homeLocation)
}

function reload()
{
    getFrame().contentDocument.location.reload()
}

function settings()
{
    getFrame().src = 'qrc:/settings.html'
}

Listado 7: Archivo index.js

Cuando el usuario hace clic en el botón Configuración que se carga desde el archivo settings.html (Listado 8). Esta página tiene un campo de entrada de la URL y los botones RSS Cancelar, Guardar y Borrar.

<!DOCTYPE HTML>
<html>
  <head>
    <title>HTML5 RSS Settings</title>
    <link href="content.css" rel="stylesheet" type="text/css"/>
    <script type="text/javascript" src="settings.js"></script>
  </head>
  <body id="bodyId" onload="onBodyLoad()">
    <div class="search">
      <div class= "left-input"> 
        <div class= "right-input"> 
          <div class= "fill-input"> 
            <input id="rssUrlId" type="text" class="box" />
      </div></div></div>
    </div>
    <a class="button small white" href="#" onclick="cancelSettings()">Cancel</a>
    <a class="button small white" href="#" onclick="saveSettings()">Save</a>
    <a class="button small white" href="#" onclick="clearSettings()">Clear</a>
  </body>
</html>

Listado 8: Archivo settings.html

El archivo settings.js JavaScript (Listado 9) aporta la lógica de los ajustes. Se ocupa de guardar los ajustes, la cancelación de los cambios, o limpiar el campo de texto.

function saveSettings()
{
    top.rss_path = document.getElementById('rssUrlId').value
    top.document.getElementById('frameId').src = 'qrc:/content.html'
}
function cancelSettings()
{
    top.document.getElementById('frameId').src = 'qrc:/content.html'
}
function clearSettings()
{
    var input = document.getElementById('rssUrlId')
    input.value = ''
    input.size = 10
}
function onBodyLoad()
{
    var input = document.getElementById('rssUrlId')
    input.onkeypress = input.onkeydown = function() {
    this.size = ( this.value.length > 10 ) ? (this.value.length > 150 ? 150: this.value.length) : 10;
    };
    input.value = top.rss_path
    input.size = input.value.length
}

Listado 9: Archivo settings.js

 

Conclusiones


Sería fácil extender el ejemplo con más características para que sea una aplicación completa. Algunas de las mejoras evidentes son:

  • Incluir el soporte para múltiples canales RSS
  • Realizar los ajustes perdurables
  • Seguimiento e información sobre el estado de los artículos que se leen

Este ejemplo que te hemos mostrado sobre una aplicación razonablemente funcional, se puede escribir con una pequeña cantidad de código, por lo general menos líneas de código que si se implementa mediante un conjunto de herramientas nativas basadas en C + + o Java.

 

Copyright © 2011, Intel Corporation.

 

Enlace original disponible aquí.

有关编译器优化的更完整信息,请参阅优化通知