Principios de programación

En este documento se describen los conceptos y las tareas fundamentales del proceso de programación de gadgets. Para conocer los procedimientos básicos del API, consulta la sección Introducción.

Contenido

  1. Elección de un tipo de contenido
    1. HTML
    2. URL
  2. Cómo convertir una página web o una aplicación existente en un gadget
  3. Uso de los tipos de datos de las preferencias de usuario
    1. Uso del tipo de datos "list"
    2. Uso del tipo de datos "location"
  4. Almacenamiento del estado
  5. Caracteres especiales de escape
  6. Creación de gadgets que requieran autenticación o cookies

Elección de un tipo de contenido

Una de las primeras decisiones que se deben tomar a la hora de crear un gadget es el tipo de contenido que se va a usar. Por ejemplo:

<Content type="html">

El tipo de contenido determina:

  • las funciones de API que tienes disponibles como autor de un gadget,
  • la forma en que se mostrará el gadget y
  • el lugar en el que se puede instalar el gadget.

En la tabla siguiente se describen los tipos de contenido disponibles y cuándo se deben usar:

Tipo de contenido Descripción Cuándo se debe usar
html Con un tipo de contenido html, todo el contenido reside, por lo general, en la especificación del gadget. Un gadget type="html" contiene código HTML, posiblemente con objetos JavaScript, Flash, ActiveX u otros objetos de navegador incrustados. Se trata del tipo predeterminado. El tipo de contenido más flexible y versátil es html. Cuando tengas dudas, elige el tipo de contenido html.
url Con un tipo de contenido url, el contenido del gadget se aloja en una página web remota a la que hace referencia una URL en la especificación del gadget. La página web remota es el lugar donde residen todas las etiquetas HTML y JavaScript. NO se puede insertar ningún código de etiquetas HTML ni JavaScript en la especificación del gadget propiamente dicha. El tipo de contenido type="url" no es totalmente compatible actualmente con las API de gadgets.* u OpenSocial. Si deseas usar el tipo de contenido type="url" con las bibliotecas JavaScript de gadgets, usa el API de gadgets heredada.

HTML

Con el tipo de contenido html, todo el código reside, por lo general, en la especificación del gadget, incluido el código XML y todas las etiquetas HTML y JavaScript. En casi todos los ejemplos que aparecen en esta guía del desarrollador se utiliza el tipo de contenido html. Es el tipo más flexible y versátil, y el que deberías elegir a menos que un gadget presente requisitos especiales.

El ejemplo siguiente es una implementación de ROT13 con gadgets. ROT13 encripta el texto reemplazando cada letra por aquella situada 13 posiciones por delante en el alfabeto. A continuación, al volver a aplicar ROT13, cada letra rota de nuevo y se restaura el texto original.

La especificación del gadget es la siguiente:

<?xml version="1.0" encoding="UTF-8" ?> 

<Module>
  <ModulePrefs title="Magic Decoder"/> 
  <Content type="html">
  <![CDATA[
     <script type="text/javascript">

       // The gadget version of ROT13.
       // Encodes/decodes text strings by replacing each letter with the letter
       // 13 positions to the right in the alphabet. 
       function decodeMessage (form) {
          var alpha = "abcdefghijklmnopqrstuvwxyz";
          var input = form.inputbox.value; 
          var aChar;
          var message = "";
          for (var i = 0; i <input.length; i++)
          { 
             aChar = input.charAt(i);
             var index = alpha.indexOf(aChar.toLowerCase());

             // if a non-alphabetic character, just append to string
             if (index==-1)
             {
                message += aChar;
             }

             // if you have to wrap around the end of the alphabet
             else if(index > 12) { // compensate for 0-based index
                index = 25 - index; // last item in array is at [25]
                index = 12 - index; // because array starts with 0
                aChar = alpha.charAt(index);
                message += aChar;
             }

             // if you don't have to wrap
             else {
                aChar = alpha.charAt(index+13);
                message += aChar;
             }
          }
          document.getElementById('content_div').innerHTML = "<b>Your message: </b>" + message; 
     }
     </script>

     <FORM NAME="myform" ACTION="" METHOD="GET">Message: <BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><P>
<INPUT TYPE="button" NAME="button" Value="Transform" onClick="decodeMessage(this.form)"> </FORM> <div id="content_div"></div> ]]> </Content> </Module>

Las reglas de un gadget type="html" son las siguientes:

  • Un gadget type="html" debe incluir una sección CDATA, donde deberá aparecer todo el código HTML:
<Content type="html"> 
    <![CDATA[ HTML here... ]]>

Las secciones CDATA permiten aplicar formato de escape a los bloques de texto que contienen caracteres que, de lo contrario, se considerarían etiquetas. El único delimitador reconocido en una sección CDATA es la cadena "]]>", que pone fin a la sección CDATA.

  • No se pueden usar las etiquetas <html>, <head>, ni <body>. Los gadgets se generan con sus propias etiquetas <html>, <head>, y <body>. Tan sólo hay que incluir el contenido que normalmente se colocaría dentro de la etiqueta <body>.

Un gadget con un tipo de contenido html también puede hacer referencia a un archivo JavaScript externo:

<Module>
  <ModulePrefs ... /> 
  <Content type="html"><![CDATA[
    <script src="http://www.example.com/gadgets/clock/clock.js" type="text/javascript"></script>

  ]]></Content> 
</Module>

URL

Si un gadget tiene un tipo de contenido type="url", el atributo href= proporcionará una URL, y el resto de contenido de la especificación del gadget se ignorará. Con un tipo de contenido url, se asume que toda la información relacionada con la interfaz de usuario y la lógica de programación del gadget reside en el archivo al que hace referencia la URL. No se debe colocar ninguna etiqueta HTML ni JavaScript dentro del gadget propiamente dicho. Por ejemplo:

<Module>
  <ModulePrefs ... /> 
  <Content type="url" href="http://www/cgi-bin/example/gadgets/mystats.cgi" /> 
</Module>

Cómo convertir una página web o una aplicación existente en un gadget

Para convertir una página web o una aplicación existente en un gadget, debes seguir estas directrices:

  • Elimina las etiquetas <html>, <head> y <body> (en otras palabras, deja únicamente el contenido HTML en sí). Esta directriz sólo se aplica a los gadgets type="html". No se aplica a los gadgets type="url".
  • Para eventos de carga, usa gadgets.util.registerOnLoadHandler().
  • Si el gadget exige el acceso del usuario, usa un tipo de contenido URL. Consulta Creación de gadgets que requieran autenticación o cookies para evitar los problemas más habituales. Ten en cuenta que los gadgets HTTPS generan advertencias de "contenido combinado" en Internet Explorer, lo que puede resultar molesto para los usuarios.
  • Realiza todos los cambios en la interfaz de usuario que sean necesarios para que tu página o aplicación quepa en el pequeño espacio del gadget. Los aficionados o los profesionales que desarrollan prototipos pueden usar makeRequest() para enviar el contenido a un servidor proxy. Para gadgets programados con fines comerciales, recomendamos crear una página nueva y pequeña, y hacer que type="url" apunte a dicha página.

Uso de los tipos de datos de las preferencias de usuario

Dentro de la especificación del gadget, cada preferencia de usuario presenta un tipo de datos. La cadena datatype es opcional y especifica el tipo de datos del atributo. Los valores posibles de la cadena datatype son string, bool, enum, hidden (una cadena no visible que el usuario no puede editar), list y location (para gadgets basados en Google Maps). El tipo de datos predeterminado es string.

Consulta la referencia para obtener información detallada sobre los tipos de datos.

En esta sección se describen dos de los tipos de datos más especializados: list y location. En esta guía encontrarás ejemplos de cómo utilizar el resto de tipos de datos (por ejemplo, enum, hidden y bool).

Uso del tipo de datos "list"

Una preferencia del usuario con el tipo de datos "list" es un conjunto de valores que los usuarios envían de forma dinámica durante el tiempo de ejecución. A medida que los usuarios escriben los valores en el cuadro de edición de las preferencias, éstos se añaden a la lista. El gadget puede acceder a la lista de forma automática durante el tiempo de ejecución, al igual que cualquier otra preferencia de usuario. Puedes usar el tipo de datos "list" en cualquier momento para permitir que los usuarios envíen de forma dinámica una lista arbitraria de valores. Por ejemplo, un gadget sobre el tiempo podría permitir que los usuarios introdujeran sus códigos postales.

Para declarar que una preferencia de usuario incluye el tipo de datos debes utilizar datatype="list". Por ejemplo:

<UserPref name="mylist" display_name="Add Search Terms" datatype="list" required="true"/> 

El gadget accede a los valores de la lista con la función Prefs getArray(),, por ejemplo:

var search_terms = prefs.getArray("mylist");

Dentro del conjunto, los elementos se almacenan como una lista separada por barras verticales. Puedes usar la función Prefs getString() para mostrar esta lista como una cadena única en la que los valores están separados por el carácter de barra vertical (|), por ejemplo:

prefs.getString("mylist");

También puedes usar una cadena separada por barras verticales para definir valores predeterminados para un tipo de lista:

<UserPref name="mylist" display_name="Add Search Terms" datatype="list" default_value="zdnet|pc|Apple Insider"/>

Puedes usar la función Prefs setArray(name, val) para añadir de forma automática valores a la lista. Para utilizar esta función, tu gadget debe incluir <Require feature="setprefs"/> en <ModulePrefs>. Por ejemplo, el siguiente fragmento añade los valores "Nokia" y "CNET" a la lista:

...

<ModulePrefs title="Feed Searcher" scrolling="true">
   <Require feature="setprefs" />
</ModulePrefs> ... prefs.setArray("mylist", ["Nokia","CNET"]);

A continuación se ofrece un ejemplo sencillo en el que aparecen los elementos de la lista introducidos por los usuarios en el cuadro de edición:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs 
    title="List Data Type Example" 
    scrolling="true"/> 
  <UserPref name="mylist" 
    display_name="Add Terms" 
    datatype="list" />
  <Content type="html">
  <![CDATA[ 
  <div id=content_div></div>

  <script type="text/javascript"> 
    // Get userprefs
    var prefs = new gadgets.Prefs();

    // Get the array of search terms entered by the user
    var terms = prefs.getArray("mylist");  
    var html = "";

    // If the user has not added any terms yet, display message.
    if (terms.length == 0)
    {
      html += "Edit the userprefs to add terms.";
    }
    else {
      html += "Your terms are:<br /><br />";
      for (var i = 0; i < terms.length ; i++) {
        var term = (terms[i]);
        html += term + "<br />";
      }
    }
    document.getElementById("content_div").innerHTML = html; 
  </script>

  ]]> 
  </Content>
</Module>

Uso del tipo de datos "location"

Los gadgets basados en Google Maps pueden usar el tipo de datos location. En el ejemplo siguiente se muestra cómo usar el tipo de datos location. Para los gadgets, el valor proporcionado para un tipo de datos location debe ser una ciudad importante o un código postal de Estados Unidos, Canadá o el Reino Unido. Es posible que los códigos postales te ofrezcan mejores resultados.

Con el tipo de datos location, puedes usar getString() para recuperar la longitud y la latitud de la ubicación especificada por el usuario.

<Module>
<ModulePrefs title="Map of __UP_loc__" height="300" author="Jane Smith" author_email="xxx@google.com" />
<UserPref name="loc" display_name="Location" datatype="location" required="true" />
<Content type="html">
<![CDATA[
<script src="http://maps.google.com/maps?file=js" type="text/javascript"></script>
<div id="map" style="width: 100%; height: 100%;"></div>
<script type="text/javascript">
var prefs = new gadgets.Prefs();
var map = new GMap(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.centerAndZoom(new GPoint(prefs.getString("loc.long"), prefs.getString("loc.lat")), 6);
</script> ]]>
</Content> </Module>

Al leer la cadena "x" de una preferencialocation:

  • Si "x" es la cadena vacía (lo que significa una ubicación vacía), x.lat y x.long son la cadena vacía.
  • Si "x" no se puede codificar geográficamente (lo que significa una ubicación no válida), el valor de x.lat y x.long será 0.0.

Las versiones anteriores del API de gadgets no permitían especificar una cadena default_value para un tipo de ubicación. Esto ya no sucede.

Almacenamiento del estado

Es habitual dejar que los usuarios definan sus preferencias de manera explícita mediante el cuadro de edición. No obstante, algunas veces resulta útil definirlas de forma automática, sin que el usuario participe directamente. Por ejemplo, para un gadget de juegos es conveniente guardar de forma continuada la puntuación más alta del usuario. Para ello, podrías definir de forma automática un valor para la preferencia de usuario "high_score" o puntuación máxima.

Para usar la función setprefs, el gadget debe incluir lo siguiente:

  • Una etiqueta <Require feature="setprefs"/> (en <ModulePrefs>) que indique al gadget que debe cargar la biblioteca setprefs.
  • Una preferencia de usuario cuyo valor deseas definir de forma automática y guardar de forma permanente. Por lo general, se le aplica el tipo de datos hidden.
  • Una llamada a la función JavaScript set() para la preferencia de usuario cuyo valor deseas guardar.

Ten en cuenta que el tamaño de la preferencia se encuentra actualmente restringido por las limitaciones de la URL, que es de 2 KB.

El gadget de ejemplo siguiente consta de dos botones: uno que incrementa el valor del contador y otro que lo restablece a 0. En este ejemplo, "counter" es una preferencia del usuario. Tiene el tipo de datos hidden, lo que significa que los usuarios no pueden modificar directamente su valor.

La especificación del gadget es la siguiente:

<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs 
    title="Setprefs New">
    <Require feature="opensocial-0.8"/>
    <Require feature="setprefs" /> 
    </ModulePrefs>
  <UserPref 
    name="counter" 
    default_value="0" 
    datatype="hidden"/>
  <Content type="html">
  <![CDATA[ 
    <div id="content_div" style="height: 100px;"></div>
    <script type="text/javascript">

    // Get user preferences
    var prefs = new gadgets.Prefs();
    var html = "";
    var div = document.getElementById('content_div');
    // Increment value of "counter" user preference
    function incrementCounter() {  
      var count = prefs.getInt("counter");
      div.innerHTML = "The count is " + count + ".";
      // Increment "counter" userpref          
      prefs.set("counter", count + 1);
    }

    // Reset value of "counter" userpref to 0
    function resetCounter(){
      prefs.set("counter", 0);
      div.innerHTML = "Count reset to " + prefs.getInt("counter") + ".";
    }

    </script>
    <input type=button value="Count" name="count" onClick="incrementCounter()">
    <input type=button value="Reset" name="reset" onClick="resetCounter()">
  ]]> 
  </Content>
</Module>

Nota: si necesitas guardar varios valores, es recomendable que los guardes en una cadena JSON.

Caracteres especiales de escape

En los atributos XML de una especificación de gadget, deberás aplicar caracteres de escape a ciertos caracteres especiales. Ten en cuenta que sólo puedes utilizar entidades ASCII en la especificación del gadget. Por ejemplo, no puedes usar entidades de símbolo ISO 8859-1. A continuación se ofrece una lista de los caracteres especiales admitidos:

Carácter Código de escape
& &amp;
< &lt;
> &gt;
" &quot;
' &apos;

Por ejemplo:

  • INCORRECTO: href="http://www.foo.com/bar?x=a&y=b"
  • CORRECTO: href="http://www.foo.com/bar?x=a&amp;y=b"
  • INCORRECTO: description="this is a "sexy" gadget"
  • CORRECTO: description="this is a &quot;sexy&quot; gadget"

Ten en cuenta que el uso de este tipo de caracteres de escape no es necesario en el bloque CDATA, aunque sí es recomendable.

En el código JavaScript, puedes usar la función _hesc(str) para devolver la cadena HTML str con los siguientes caracteres de escape aplicados: <>'".

Creación de gadgets que requieran autenticación o cookies

Las políticas de privacidad predeterminadas de Microsoft Internet Explorer y Apple Safari no permiten que los sitios de terceros establezcan cookies. Por tanto, es posible que algunos gadgets no funcionen correctamente. En especial, es posible que los sitios que usan cookies para la autenticación de usuario no funcionen correctamente dentro de un iframe desde la página de iGoogle. A continuación te indicamos algunas posibles soluciones:

  • Usa parámetros de la URL en lugar de cookies. Por ejemplo, el gadget de cumpleaños en orkut transmite las credenciales de autenticación a través de la URL. Una advertencia: si eliges esta opción, ten cuidado de no filtrar estos parámetros de la URL a otros sitios web en campos de referencias HTTP.
  • Utiliza OAuth. El API de gadgets es compatible con una función que se llama proxy de OAuth que permite a los gadgets conectarse de forma segura a otro sitio web donde se almacenen los datos privados asociados a la cuenta de un usuario. OAuth es un estándar que permite al propietario de la cuenta de los datos privados indicar al sitio web que permita a otra aplicación acceder a los datos. El proxy de OAuth está diseñado para facilitar a los gadgets el uso del estándar OAuth.
  • Crea encabezados P3P. En función de la política de privacidad de tu sitio, es posible que puedas crear encabezados P3P que permitan que Internet Explorer (pero no Safari) lea las cookies de terceros desde tu sitio. Si utilizas PHP y deseas definir encabezados, puedes usar este fragmento de código en la parte superior de la página PHP:
<?php
  header("P3P: CP=\"CAO PSA OUR\"");
?> 

Deberá ejecutarse antes de que se aparezca cualquier resultado en la página.

DEBERÁS REVISAR TU POLÍTICA DE PRIVACIDAD DETENIDAMENTE PARA VER QUÉ ENCABEZADOS SE PUEDEN USAR EN TU SITIO. TE RECOMENDAMOS PONERTE EN CONTACTO CON TU ASESOR LEGAL.

  • Brinda instrucciones a los usuarios. Puedes hacerlo en JavaScript, como en este gadget de ejemplo (pruébalo). También puedes integrar las instrucciones con la lógica de autenticación. Si detectas que las cookies se bloquean, avisa a los usuarios para que rebajen el nivel de privacidad o para que prueben con otro navegador web. Por ejemplo, podrías mostrar un mensaje como el siguiente:

La configuración de tu navegador es incompatible con este sitio. Si utilizas Microsoft Internet Explorer, puedes modificar tu configuración de seguridad seleccionando Herramientas> Opciones de Internet. Abre la ficha Privacidad, haz clic en Avanzada y, a continuación, selecciona Invalidar la administración automática de cookies. En Cookies de terceros, haz clic en Aceptar. Si lo prefieres, puedes probar con otro navegador web como, por ejemplo, Firefox.

 

Volver al principio