Fundamentos do desenvolvimento

Este documento descreve os conceitos e tarefas básicas para o processo de desenvolvimento do gadget. Para obter informações sobre como usar a API de gadgets, leia Primeiros passos.

Sumário

  1. Seleção do tipo de conteúdo
    1. HTML
    2. URL
  2. Como transformar uma página da web ou aplicativo existente em um gadget
  3. Uso de tipos de dados Userpref
    1. Uso do tipo de dados list
    2. Uso do tipo de dados location
  4. Como salvar o estado
  5. Codificação de escape de caracteres especiais
  6. Criação de gadgets que necessitam de login ou cookies

Seleção do tipo de conteúdo

Uma das primeiras decisões que você deve tomar ao desenvolver um gadget é que tipo de conteúdo irá usar. Por exemplo:

<Content type="html">

O tipo de conteúdo determina:

  • Que recursos da API estão disponíveis para você como autor do gadget.
  • Como seu gadget é exibido.
  • Onde seu gadget pode ser implementado.

A tabela a seguir descreve os tipos de conteúdo disponíveis e quando você deve usá-los:

Tipo de conteúdo Descrição Quando usar
html Com o tipo de conteúdo , o conteúdo completo normalmente reside nas especificações do gadget. html Um gadget type="html" contém HTML, possivelmente com JavaScript, Flash, ActiveX ou outros objetos incorporados ao navegador. Este é o tipo padrão. O tipo de conteúdo mais flexível e versátil é o html. Na dúvida, selecione o tipo de conteúdo html.
url Com o tipo de conteúdo , o conteúdo do gadget reside em uma página da web remota que pode ser acessada por meio de um URL localizado nas especificações do gadget. url A página da web remota é onde reside todo o markup HTML e o JavaScript. Você NÃO pode colocar nenhum markup HTML ou código JavaScript nas especificações do gadget. Atualmente, o tipo de conteúdo type="url" não é totalmente suportado pelos gadgets.* ou APIs do OpenSocial. Se desejar usar o tipo de conteúdo type="url" com as bibliotecas de gadgets JavaScript, use a API de gadgets antiga.

HTML

Com o tipo de conteúdo html, o código completo normalmente reside nas especificações do gadget. Isso inclui o XML do gadget e qualquer markup HTML e JavaScript. Quase todos os exemplos deste guia do desenvolvedor usam o tipo de conteúdo html. Ele é o tipo mais flexível e versátil e você deve normalmente optar por ele, a menos que esteja criando um gadget com requisitos específicos.

O exemplo a seguir demonstra a implementação de um gadget do recurso ROT13. O ROT13 criptografa textos substituindo cada letra pela letra que está 13 posições à frente no alfabeto. Quando o recurso ROT13 é reaplicado, ele rotaciona cada letra novamente, restaurando o texto original.

Esta é a especificação do gadget:

<?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>

As regras para um gadget type="html" são as seguintes:

  • Um gadget type="html" deve conter uma seção CDATA, e todos os códigos HTML devem estar dentro dessa seção:
<Content type="html"> 
    <![CDATA[ HTML here... ]]>

As seções CDATA são usadas para adicionar códigos de escape a blocos de texto contendo caracteres que, de outra forma, seriam considerados markup. O único separador reconhecido em uma seção CDATA é a string '']]>'', que finaliza a seção CDATA.

  • Você não pode usar as tags <html>, <head>, ou <body>. Os gadgets são gerados com suas próprias tags <html>, <head>, e <body>. Basta incluir o conteúdo que normalmente ficaria dentro da tag <body>.

Um gadget com tipo de conteúdo html também pode fazer referência a um arquivo 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

Quando um gadget possui o tipo de conteúdo type="url", o atributo href= fornece um URL e qualquer outro conteúdo da especificação do gadget é ignorado. Com o tipo de conteúdo url, supõe-se que todas as informações relacionadas à interface de usuário e à lógica programática do gadget residem no arquivo apontado pelo URL. Não se deve colocar nenhum markup HTML ou JavaScript dentro do gadget em si. Por exemplo:

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

Como transformar uma página da web ou aplicativo existente em um gadget

Para transformar uma página da web ou aplicativo existente em um gadget, siga as orientações abaixo:

  • Remova as tags <html>, <head> e <body> (em outras palavras, forneça apenas o conteúdo HTML). Esta diretriz aplica-se somente a gadgets . type="html" Ela não se aplica a gadgets .type="url"
  • Para eventos onload, use gadgets.util.registerOnLoadHandler().
  • Se o gadget exigir login, use um tipo de conteúdo URL. Consulte a seção Criação de gadgets que necessitam de login ou cookies para saber como lidar com situações que podem ser consideradas "armadilhas". Gadgets HTTPS emitem avisos de ''conteúdo misto'' no Internet Explorer, o que pode incomodar os usuários.
  • Faça as alterações necessárias na interface do usuário para ajustar sua página ou aplicativo no pequeno espaço do gadget. O makeRequest() pode ser usado como proxy do conteúdo de amadores e profissionais criando protótipos. Para gadgets desenvolvidos comercialmente, recomendamos simplesmente criar uma pequena página nova e usar o type="url" apontando para ela.

Uso de tipos de dados Userpref

Cada preferência de usuário tem um tipo de dados dentro da especificação do gadget. O datatype é uma string opcional que especifica o tipo de dados do atributo. Os valores possíveis de datatype são string, bool, enum, hidden (uma string invisível que não pode ser editada pelo usuário), list e location (para gadgets baseados no Google Maps). O tipo de dados padrão é string.

Consulte a referência para obter informações detalhadas sobre os tipos de dados das preferências do usuário.

Esta seção descreve dois dos tipos de dados mais especializados: list e location. Você pode encontrar exemplos de como usar os outros tipos de dados na documentação (por exemplo, enum, hidden, e bool).

Uso do tipo de dados list

Uma preferência de usuário com o tipo de dados list é uma matriz de valores fornecidos dinamicamente pelos usuários durante a execução. À medida que os usuários digitam valores na caixa de edição de preferências do usuário, os valores são adicionados à lista. Assim como qualquer outro userpref, a lista pode ser acessada programaticamente pelo gadget durante a execução. Você pode usar o tipo de dados list sempre que quiser permitir que os usuários forneçam uma lista de valores arbitrários dinamicamente. Por exemplo, um gadget de condições climáticas pode permitir que os usuários digitem uma lista de códigos postais.

Para declarar que um userpref tem tipo de dados list, use datatype="list". Por exemplo:

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

O gadget acessa os valores da lista usando a função Prefs getArray(),; por exemplo:

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

Dentro da matriz, os itens são armazenados em uma lista separada por barras verticais. Você pode usar a função getString() de Prefs para retornar esta lista como uma única string na qual os valores são separados pelo caractere barra vertical (|); por exemplo:

prefs.getString("mylist");

Você também pode usar uma string separada por barras verticais para definir os valores padrão de um tipo de dados list:

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

Use a função setArray(name, val) de Prefs para adicionar valores à lista programaticamente. Para usar essa função, seu gadget deve incluir <Require feature="setprefs"/> em <ModulePrefs>. Por exemplo, o trecho a seguir adiciona os valores ''Nokia'' e ''CNET'' à lista:

...

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

Aqui está um exemplo simples que fornece os itens da lista digitados pelo usuário na caixa Edit (Editar):

<?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 do tipo de dados location

Os gadgets baseados no Google Maps podem usar o tipo de dados location. O gadget do exemplo a seguir ilustra como usar o tipo de dados location. Nos gadgets, o valor fornecido para um tipo de dados location deve ser uma cidade ou um código postal dos Estados Unidos, Canadá ou Reino Unido. O uso de códigos postais pode ter um resultado melhor.

Ao usar o tipo de dados location, use getString() para recuperar a longitude e a latitude do local especificado pelo usuário.

<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>

Ao ler uma preferência xlocation de :

  • Se x for uma string vazia (significando um local vazio), x.lat e x.long são a string vazia.
  • Se x não puder ser geocodificada (significando um local inválido), x.lat e x.long são 0.0.

As versões anteriores da API de gadgets não permitiam especificar um default_value para o tipo de local. Mas agora isso mudou.

Como salvar o estado

É comum permitir que os usuários definam suas preferências de forma explícita, através da caixa de edição. Entretanto, às vezes é útil definir programaticamente os valores das preferências do usuário, sem sua participação direta. Por exemplo, em um gadget de jogo, você pode armazenar continuamente a pontuação mais alta do usuário. Você pode fazer isso de maneira programática, definindo o valor de uma preferência de usuário ''high_score''.

Para usar o recurso setprefs, seu gadget deve incluir:

  • Uma tag <Require feature="setprefs"/> (em <ModulePrefs>) para informar ao gadget que ele precisa carregar a biblioteca setprefs.
  • Uma userpref cujo valor você deseja definir programaticamente e armazenar continuamente. Normalmente, esta userpref tem o tipo de dados hidden.
  • Uma chamada à função JavaScript set() para a userpref cujo valor você deseja salvar.

O tamanho da preferência atualmente está restrito por limitações de URL, podendo chegar a 2K.

O gadget da amostra a seguir consiste em dois botões: um que aumenta o valor de um contador, e outro que redefine o valor do contador para 0. Neste exemplo, ''counter'' é uma preferência de usuário. O tipo de dados é hidden, o que significa que os usuários não têm permissão de modificar diretamente o valor.

Esta é a especificação do gadget:

<?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>

Observação: Se for necessário armazenar diversos valores, recomendamos salvá-los em uma string JSON.

Codificação de escape de caracteres especiais

É necessário adicionar códigos de escape a determinados caracteres especiais dentro dos atributos XML de uma especificação de gadget. Você pode usar somente entidades ASCII na especificação do gadget. Por exemplo, não é possível usar entidades ISO 8859-1 de símbolo. Aqui está uma lista dos caracteres especiais suportados:

Caractere Codificação de escape
& &amp;
< &lt;
> &gt;
" &quot;
' &apos;

Por exemplo:

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

Observe que esse tipo de escape não é necessário no bloco CDATA. Entretanto, seu uso é recomendável.

Dentro do código JavaScript, use a função _hesc(str) para retornar a string HTML str com os seguintes caracteres codificados como escape: <>'".

Criação de gadgets que necessitam de login ou cookies

As políticas de privacidade padrão do Microsoft Internet Explorer e do Apple Safari não permitem que sites de terceiros definam cookies. Portanto, alguns gadgets podem não funcionar corretamente. Os sites que usam cookies para login, especificamente, podem não funcionar corretamente dentro de um iframe da página do iGoogle. Veja algumas soluções possíveis:

  • Use parâmetros URL em vez de cookies. Por exemplo, o Orkut birthdays gadget (aniversários do Orkut) passa credenciais de autenticação via URL. Aviso importante: Se você optar por este método, tenha cuidado para que esses parâmetros de URL não vazem para outros sites da web nos campos HTTP de direcionamento.
  • Use o OAuth. A API do gadgets suporta um recurso chamado proxy OAuth que permite a conexão segura dos gadgets com outro site que armazena dados particulares associados à conta de um usuário. O OAuth é um padrão criado para permitir que o proprietário dos dados particulares da conta autorize outro aplicativo a acessar os dados. O proxy OAuth foi desenvolvido para facilitar o uso do padrão OAuth pelos gadgets.
  • Crie cabeçalhos P3P. Dependendo da política de privacidade do seu site, talvez você possa criar cabeçalhos P3P, os quais permitem que o Internet Explorer (mas não o Safari) leia cookies de terceiros do seu site. Se você estiver usando PHP e desejar definir os cabeçalhos, use este snippet de código no alto da sua página PHP:
<?php
  header("P3P: CP=\"CAO PSA OUR\"");
?> 

Esse comando deve ser chamado antes da exibição de qualquer resultado na página.

VERIFIQUE SUA POLÍTICA DE PRIVACIDADE CUIDADOSAMENTE QUANTO AOS CABEÇALHOS QUE PODEM SER USADOS EM SEU SITE. ENCORAJAMOS VOCÊ A CONSULTAR SEU ADVOGADO.

  • Informe os usuários. Isso pode ser feito em JavaScript, como nesta amostra de gadget (experimente) . Você também pode integrar instruções à sua lógica de autenticação. Se detectar o bloqueio de cookies, informe os usuários que eles devem diminuir sua configuração de privacidade ou experimentar um navegador diferente. Por exemplo, você pode exibir uma mensagem como:

Seu navegador não é compatível com este site na configuração atual. Se estiver usando o Microsoft Internet Explorer, altere sua configuração de segurança selecionando Ferramentas > Opções da Internet. Abra a guia Privacidade, clique em Avançado e, em seguida, clique em Ignorar manipulação automática de cookies. Em Cookies Secundários, clique em Aceitar. Como alternativa, você pode usar outro navegador, como o Firefox.

 

Voltar ao início