Ítalo Queiroz

Apenas um programador Manolo!!!

quem é o manolo?

Ítalo Queiroz, há 5 anos atua na área de Tecnologia da Informação em empresas como Preceptor, Senado Federal, X25, MEC - Ministério da Educação e Grupo 954… about.me

Criando Widget Usando jQuery

- - falando sobre: Widget, jQuery

Atualmente a moda é namorar pelado Widget’s, que são componentes de interface que fornecem uma funcionalidade específica. Acessando o site da jQueryUI encontrei este link Widget Factory.

Montei o exemplo a seguir tentando repassa o que consegui abstrair dos conceitos informados pela jQueryUI.

Primeiro iremos criar 2 arquivos index.html e jquery.custom.list.js

No index.html montaremos uma estrutura simples de html adicionando algumas chamadas para as libs da jQuery (v 1.8) e jQueryUI (v 1.9).

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css" />
  <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
  <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
  <script type="text/javascript" src="jquery.custom.list.js"></script>
  <style type="text/css">
      table td, table th {
          padding:5px;
      }
  </style>
</head>
<body>
  <div id="demo"></div>
</body>
</html>

O jquery.custom.list.js será o arquivo onde criaremos nosso widget.

jquery.custom.list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
$(function() {
  $.widget("custom.list", {
    // default options
    options: {
      data: [],
      columns: ['nome', 'idade']
    },

    htmlTable: null,

    //Construtor
    _create: function() {
      console.log('construtor');
      this.element.addClass('custom-list');
      this._refresh();
    },

    //Este método é chamada assim que for criado e quando for alterada as opções.
    _refresh: function() {
      //verifica se foi informado os dados.
      if (this.options.data.length) {
        this._createTable();
        this._createHeaderTable();
        this._createBodyTable();
      } else {
        $('<div>', {id:"custon-list-alert", text:"Não existem registros"})
          .appendTo(this.element);
      }
    },

    //Método privado que cria a tabela
    _createTable: function () {
      this.element.html('<table>');
    },

    //Método privado que cria o cabeçalho
    _createHeaderTable: function () {
      var headerTable = $('<thead>');

      $('<tr>').appendTo(headerTable);
      $.each(this.options.columns, function(key, column){
        $('<th>', {text:column, class:'ui-widget-header'}).appendTo(headerTable.find('tr'));
      });

      this.element.find('table').html(headerTable);
    },

    //Método privado que monta o corpo da tabela com os dados passados.
    _createBodyTable: function () {
      var bodyTable = $('<tbody>'),
      self = this;

      $.each(self.options.data, function(key, data){
        $('<tr>').appendTo(bodyTable);
        $.each(self.options.columns, function(i, column){
          $('<td>', {text: (data[column]?data[column]:'') , class:'ui-state-default'}).appendTo(bodyTable.find('tr:last-child'));
        });
      });

      this.element.find('table').append(bodyTable);
    },

    //Responsável por remover o plugin e fazer as limpezas necessárias.
    _destroy: function() {
      this.element.find('table').remove();
      this.element.removeClass('custom-list');
    },

    // Este método é chamado sempre que uma opção é alterada
    // e toda vez que uma opção é alterada atualizamos nosso widget.
    _setOptions: function() {
      // _super and _superApply continuam a manipulação correta dos argumentos passados.
      this._superApply( arguments );
      this._refresh();
    }
  });
});

No início do arquivo temos a chamada do $.widget que tem como primeiro parâmetro o namespace (custom) e nome (list) do seu plugin, caso o namespace não exista a jQuery já criara a instância.
O segundo parâmetro é o objeto widget de onde você deseja herdar, podendo este também ser um novo objeto.
Terceiro parâmetro são as configurações que você deseja adicionar ou sobrescrever no widget herdado.

Como você pode perceber temos alguns métodos que iniciam com “_” (underscore), este são métodos privados (por convenção) não podem ser acessados Ex: $(‘#demo’).list(‘_create’)

São necessários a princípio as seguintes implementações:

options: Com as opções default do seu widget.

_create: Que é o construtor do seu widget.

_destroy: Que é o seu lixeiro, assim que acionado ele remove o widget e você pode informar demais procedimentos para a “limpeza” do DOM.

Adicionei meus métodos privados:
_refresh, _createTable, _createHeaderTable, _createBodyTable.

E sobrescrevi o setOptions, pois sempre que for alterado meus options o widget será atualizado (_refresh).

Abra o console do seu navegador e tente as seguintes instruções de cada vez:
$(‘#demo’).list(‘option’, ‘columns’, [‘nome’]);
$(‘#demo’).list(‘option’, ‘data’, [{nome:’Nome de alguém’, idade:43}]);
$(‘#demo’).data(‘list’)._refresh;
$(‘#demo’).list(‘destroy’);

Link do código no GitHub

Atualizando O PHP No MAC OS

- - falando sobre: MAC OS, PHP

Manolada, quem tem MAC OS sabe muito bem que ele já vem com um PHP e Apache instalado, pronto para ser utilizado. Só que nem tudo são flores, porque a versão que vem instalada no OS é muito desatualizada com a ultima versão estável disponível.

E ai que vem a porrada. Como atualizar o PHP do MAC sem cuspir sangue?. Isso pode ser feito de 2 maneiras. Você pode usar gerenciadores de pacote ou simplesmente utilizar um comando no terminal e mais nada. coisa linda d++++

Atualizar PHP
1
curl -s http://php-osx.liip.ch/install.sh | bash -s 5.4

Simples assim, se tiverem dúvidas podem acessar o site desta bagaça.

Espero ter ajudado.

Criando Templates Com HandleBars

- - falando sobre: HandleBars, Javascript, Template, jQuery

Se você querido “manolo” leitor que quando utiliza javascript se “amarra” em misturar lógica com string’s que geram seu html.

Html misturado com a lógica
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var html = "<div>
             <ul>
                 <li>1</li>
                 <li>2</li>
                 <li>3</li>
                 <li>4</li>
             </ul>
         </div>";
          
  //Bizarro :D eu sei        
  if (1 == 1) {
     html += '<span> Coisa linda </span>';
  }
  
  $('#target').html(html);            

Venho então lhe propor uma solução que poderá mudar a sua vida de uma vez por todas. (sei que isso foi bem tosco)

Desde que comecei a postar tenho falado sobre templates javascript e dentre eles sobre o HandleBars, então pensei em montar este tutorial com o foco apenas em conhecermos o template e como é simples sua implementação.

Começaremos criando uma estrutura de pasta conforme a imagem abaixo.

Na nossa index.html criaremos um documento html padrão, adicionando algumas bibliotecas javascript (jQuery e HandleBars) e com 2 div’s, uma com id table e outra com id div.

index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <div>
      <h3>Template 1 - Table</h3>
      <div id="table"></div>
  </div>
  <div>
      <h3>Template 2 - Div</h3>
      <div id="div"></div>
  </div>
</body>
<!-- HandleBars Library-->
<script type="text/javascript" src="http://cloud.github.com/downloads/wycats/handlebars.js/handlebars-1.0.rc.1.js"></script>
<!-- jQuery Library-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</html>

E montaremos nossos 2 arquivos de template (table.hb e div.hb) com os seguintes códigos.

table.hb
1
2
3
4
5
6
7
8
9
10
11
<style type="text/css">
    #tableComponent td{border:1px #000 solid;padding:10px}
</style>
<table id='tableComponent'>
  {{#each pessoas}}
      <tr>
          <td>{{nome}}</td>
          <td>{{idade}}</td>
      </tr>
  {{/each}}
</table>
div.hb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style type="text/css">
  .divComponent div{
      width:100px;
      height:50px;
      padding:10px;
      margin:10px;
      color:#FFF;
      background:#A5BFDD;
      float:left;
}  
</style>
<div class="divComponent">
  {{#each pessoas}}
    <div>
      Nome: {{nome}}<br />
      Idade: {{idade}}
    </div>
  {{/each}}
</div>

Como você deve ter notado, existem elementos que estão entre chaves duplas - { { nome } } – que são usadas sempre que quisermos imprimir o valor de um elemento. Caso estas chaves duplas venham referenciando um bloco de expressão - { { #each pessoas } } - é carregado este helper que pode ser um loop, uma formatação de impressão, condicionais - { { #if pessoas } } - e zas.

**obs: Não existe este espaço entre as chaves como coloquei no texto acima, mas tive que fazer isso por limitação da minha ferramenta de gerenciamento de conteúdo.

Logo abaixo temos o código javascript que faz toda a mágica de chamar nossos templates. Tentarei explicar da melhor forma possível :D. Lembrando que o javascript poderia ter sido bem melhor elaborado, com funções para gerenciar nossos templates, mas achei melhor deixar isso para outro post e não complicar mais as coisas!!!

JS que chama nossos templates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$(function() {
  
  /******************************************
  * Carregando o template "table"
  ******************************************/
  //Variável reponsável por guardar o template de "table"
  var tableTemplate = null;
  //Carrega o template de "table";
  $.ajax({
      url: 'table.hb',
      dataType: 'html',
      async: false,
      success: function (template) {
          if (template) {
              tableTemplate = Handlebars.compile(template);
          }
      }
  });
  //Dados que seram passados para o template.
  var context = {"pessoas":[{"nome":"Pedro","idade":23},{"nome":"Kleber","idade":20},{"nome":"Marcos","idade":31}]};
  //Gera o html de acordo com o JSON passado.
  var tableHtml = tableTemplate(context);
  //Seta o html para a div#table, outra opção seria $('#table').html(tableTemplate(context));
  $('#table').html(tableHtml);

  /******************************************
  * Carregando o template "div"
  ******************************************/
  //Variável reponsável por guardar o template de "div"
  var divTemplate = null;
  //Carrega o template de "table";
  $.ajax({
      url: 'div.hb',
      dataType: 'html',
      async: false,
      success: function (template) {
          if (template) {
              divTemplate = Handlebars.compile(template);
          }
      }
  });
  //Gera o html de acordo com o JSON passado (usaremos o mesmo que do template "table").
  var divHtml = divTemplate(context);
  //Seta o html para a div#div, outra opção seria $('#div').html(divTemplate(context));
  $('#div').html(divHtml);
});

Resumidamente o que precisei fazer foi carregar meus arquivos .hb que poderiam ser qualquer outro tipo de extensão (Ex: table.html, table.italo, table.queiroz), o importante mesmo é o seu conteúdo.

Para carregar e obter o html dos meus templates utilizei a função $.ajax() (Linha 9 e linha 32). Após ter a string dos meus arquivos, compilo o mesmo para ser um template HandleBars (Linha 15 e linha 38).

Depois de feito isso é necessário passar um JSON (Linha 20) para o nosso template gerar o html (Linha 22 e linha 43) e logo depois adiciono o html gerado em nossas div’s para serem apresentadas no browser.

Conclusão

O uso de templates JS ajudam muito na criação e na manutenção de conteúdos dinâmicos, além de prover uma organização, separando as montagens de html da lógica do sistema. Caso seja necessário um designer poderá mexer apenas no arquivo do template para alterar a aparência sem necessariamente ter que editar um arquivo js.

Tentei explicar de forma bem simples o funcionamento do HandleBars, aconselho que você leia a documentação para saber o que mais esta engine de template js pode fazer….

Segue o link no GitHub para download.

HandleBars Ou EJS

- - falando sobre: 960.gs, Bootstrap, EJS, Foundation, Handlebars, Javascript

Atualmente aqui no trabalho estamos definindo uma framework para o lado cliente (somente HTML e JS) que possa salvar nossas vidas, que seja “componetizada”, de fácil uso e acima de tudo tenha pouca dependência no layout utilizado na página (podendo usar Bootstrap, Foundation, 960.gs e zas).

PQP
1
{{handlebars}}
Inativando o cache
1
2
3
4
5
6
//Exemplo do site da engine HandleBars 
var source   = $("#entry-template").html();
var template = Handlebars.compile(source);

var context = {title: "My New Post", body: "This is my first post!"}
var html    = template(context);

Em meio a elaboração do projeto nos deparamos com a necessidade de utilizar um template JS, eu já tinha trabalhado com EJS mas estava fortemente voltado ao HandleBars (culpa do Meteor), sendo assim, fui dar uma googlada e percebi que existiam dezenas de engines de template e que o LinkedIn tinha feito um comparativo com várias opções para definir o que eles usariam na parte de view do site (clique aqui para ver os resultados).

Dentre as opções o HandleBars teve alguns elogios por parte da equipe do LinkedIn e por esse e outros motivos acabamos escolhendo-o. Mesmo sendo uma excelente engine e que também suporta templates do Mustache (que tem uma comunidade enorme) creio que testes de conceito sejam a melhor maneira de averiguar o que atende a sua necessida, assim como fez a equipe do LinkedIn.

Teve um ponto em específico levantado pela nossa equipe que me fizeram pensar 2 vezes antes de apoiar totalmente o HandleBars: “O CACHE”. No EJS para “cachear” um template é estupidamente simples pois já vem nativo já no HandleBars sua implementação é um pouco mais trabalhosa.

Inativando o cache
1
2
//Inativando o cache...
EJS.config({cache: false});

Mas creio que para saber como funciona esse lance de template JS a melhor opção seja o EJS, é mais tranquilo de trabalhar (com coisas simples), caso a idéia (como é a do nosso framework) seja mexer com vários componentes criando helpers e plugins aconselho o HandleBars por ter uma documentação mais vasta já que ele veio do Mustache.

Meteor

- - falando sobre: HandleBars, Javascript, Meteor, jQuery

Durante meu momentos de estudo me deparei com uma framework pra lá de curiosa, ela simplesmente prometia uma programação no lado servidor e no lado cliente usando somente Javascript e trabalhando de forma reativa: qualquer alteração realizada na página seria imediatamente populada em todos os outros clientes.

Até então não tinha acredito muito bem, e mesmo que possível, imaginei que fosse uma dificuldade imensa para configurar a máquina. Leigo engano logo após ver os vídeos de demonstração no site fiquei absurdamente surpreso. No momento de sua instalação não tive nenhum problema, sendo possível ainda baixar e rodar projetos demos.

Meteor tem um conjunto de pacotes que podem ser adicionados ao projeto.
Ex: mongoDB, HandleBars, Node.js, Bootstrap, entre outros…

Para entender melhor como funcionava montei um Kanban criei o repositório “kanbam” com “m”, sorry onde os usuários vão adicionando tarefas e movendo-as pelo quadro.

Segue o link do ”kanbam” no GitHub.

Blog, GitHub Pages E Suas Malandragens

- -

A uma semana atrás vi que era possível criar um blog hospedado pelo GitHub Pages (sei que estou atrasado) usando Jekyll e Octopress.

Na tentativa o maior problema encontrado foi a atualização do Ruby para a versão 1.9.2, que após algumas “googladas” consegui resolver facilmente com RVM, mentira tive que atualizar o XCode e instalar umas extensões para linha de comando.

Com este blog pretendo na medida do possível compartilhar alguns conhecimentos (e se você me conhece pessoalmente deve estar dizendo “quase nenhum”) e ferramentas que encontro em minhas pesquisas diárias…