wiki:versoes/24/HowTo/Templating/BoasPraticas

Version 2 (modified by gustavo, 12 years ago) (diff)

Ajustadas as urls

Boas práticas no desenvolvimento de interfaces

TOC?

Apresentação

Este documento apresenta uma compilação das boas práticas de desenvolvimento de interfaces no ExpressoMail, adotadas pela Prognus, definidas através de consultas à modelos e práticas consolidadas no mercado e da experiência dos nossos desenvolvedores.

Príncípios

Obediência aos padrôes

  • <Marcação semântica>
  • <jQuery ao invés de DOM>
  • <JSON>

  • <utilização moderada de id>
  • <templates em EJS>
  • <marcação adequada com classes significativas e pouco específicas nos elementos HTML>
  • <seletores mais específicos (compostos) no jQuery e no CSS>

Separação de código e baixo acoplamento

Separação de código (coesão)

Uma boa forma de manter o desenvolvimento de interfaces simples e de fácil manutenção é cultivando a separação de código. Isso inclui principalmente:

  • não utilizar estilos CSS inline
  • não utilizar código javascript inline
  • não constuir HTML através de código javascript
  • minimizar a aplicação de CSS através de código javascript

JAVASCRIPT:
A utilização de jQuery nos permite fazer uma manipulação adequada do comportamento dos elementos na interface. O tratamento de eventos (click, mousemove, keydown, keyup, etc.) é extremamante facilitado e nos possibilita evitar de fazê-lo inline no HTML, por exemplo.

<sem javascript de comportamento no template (o js do template é só de conteúdo)...>

HTML:

CSS:

Desacoplamento

A forma mais comum de experimentar o desacoplamento no desenvolvimento de interfaces é a construção de templates mínimos e sua principal vantagem é o reaproveitamento de código através de templates reusáveis.

Um bom exemplo para se aplicar tal reúso é visto na Figura 1, onde é mostrada a duas listas de marcadores no módulo ExpressoMail, uma na tela principal e outra na tela de configuração dos marcadores. Apesar de tratar-se da mesma lista, o desenvolvedor poderia se sentir tentado a criar um template para cada uma delas, já que a diferênça entre elas é claramente visível.

No image "configuracaoMarcadores.png" attached to versions/24/HowTo/Templating/BoasPraticas
Figura 1: Exemplo de reúso de template 1

Porém uma análise mais criteriosa revelaria que ambas as listas são idênticas em conteúdo e diferem apenas em aparência (cores e visibilidade dos elementos) e comportamento (clicks e demais eventos gerados pela interação do usuário). Assim, o trecho de código abaixo define um template que atenderia, sem nenhum problema, ao conteúdo necessário a qualquer uma das listas:

        <ul class="label-list">
                <%for (var i=0; i<data.labels.length; i++){ %>
                        <li class="label-item label-item-<%= (data.labels[i].id) ? data.labels[i].id : ''%>" style="
                                background: <%= (data.labels[i].backgroundColor) ? data.labels[i].backgroundColor : '#ebebeb' %>;
                                color: <%= (data.labels[i].fontColor) ? data.labels[i].fontColor : '#000000' %>;
                                border-color: <%= (data.labels[i].borderColor) ? data.labels[i].borderColor : '#000000' %>;">
                           
                                <span class="text-list"><%= (data.labels[i].name) ? data.labels[i].name : '' %></span>
                                <input type="hidden" value="<%= data.labels[i].id%>" name="labelItemId" class="id-item-list" />
                                
                                <div class="square-color ui-corner-all" 
                                     style="background: <%= (data.labels[i].backgroundColor) ? data.labels[i].backgroundColor : '#ffffff' %>;">
                                </div>

                                <div class="button close tiny" style="float: right"></div>
                                <div class="button edit tiny" style="float: right"></div>
                        </li>
                <%}%>
        </ul>

Para ficar mais interessante, vamos olhar para mais uma lista de marcadores. A Figura 2 mostra a lista de marcadores aplicados a uma mensagem. Apesar de o conteúdo das listas diferirem um pouco (na quantidade de marcadores) a estrutura da lista é a mesma e, devido a forma como foi construído o template das duas listas anteriores, não haveria problema nenhum em utilizá-lo aqui também. Tudo que teríamos que fazer é a definição adequada do CSS para cada contexto.

No image "mensagemMarcadores.png" attached to versions/24/HowTo/Templating/BoasPraticas
Exemplo de reúso de template 2

/* definições gerais para todas as três listas de marcadores */

.label-configure-win .label-list-container .label-list,
.expressomail-label-container .label-list-container .label-list,
.message-container .label-list-container .label-list
{ overflow: auto; height: 293px; margin:0px; }
...
...

/* definições específicas para a listas de marcadores presente na visualização da mensagem */

.message-container .label-list-container .label-list li
{ display: inline }
...
...

OBSERVAÇÃO 1:
Na lista de marcadores da tela principal do módulo ExpressoMail, diferentemente das outras duas, a cor do marcador é exibida somente dentro do botão de edição do marcador. A uma primeira vista, o tratamento destas diferenças pode parecer inserção de complexidade desnecessária, porém vejamos como é simples e coerente mantermos desta forma.

Tudo que precisamos fazer para adequar isto é utilizar javascript para dispor estas cores de acordo com o local para o qual o template foi chamado. O que soa bastante natural já que o javascript que deve tratar do comportamentamento da tela e saber onde foi requisitado o template e quais as espectativas do usuário quanto a visualização e interação com ele. Assim, o trecho de código abaixo é suficiente para efetuar este ajuste:

/* carrega o template da lista de marcadores e aplica na janela de configuração de marcadores */
var container = $('.label-configure-win .label-list-container').html(DataLayer.render('<template_path>', data));

/* oculta o botão de edição do marcador, o qual não é utilizado nesta tela */
container.find('.square-color').hide();

OBSERVAÇÃO 2:
Aliado a uma marcação HTML e uma estrutura de classes semanticamente coerente, podemos elevar consideravelmente o reúso de código dos templates.

Nos códigos acima, pôde-se observar que a flexibilidade alcançada pelo template não seria possível sem a separação adequada de XHTML, CSS e Javascript experiemntada. Por exemplo:

  1. a utilização de nomes de classes que remetam ao conteúdo e não à apresentação
  2. a ausência de código javascript e css inline (dentro das tags)

Como exemplo, imagine que o elemento HTML que representa a lista contivesse a seguinte classe:

<ul class="left-side-labels">
...

Neste caso o reaproveitamento do template em qualquer lugar que não estivesse necessáriamente no lado esquerdo (left-side-) pareceria incoerente.

Vejamos outros casos em que a má separação de código poderia influenciar:

/* impede ou dificulta a utilização onde os itens da lista não sejam inline, ou mesmo onde a lista possua tamanho diferente */
<ul style="overflow: auto; height: 293px; margin:0px;">
	<li style="display: inline;">
	...
...
/* impede ou dificulta a utilização em outros locais onde a ação de click seja diferente ou dispensável */
<ul>
	<li onlcick="javascript:abre_configuracao_label(this.id)">
	...
...

Modularidade, componentização e reúso

  • Modularidade: <...>
  • Componentização: <plugins, widgets, ...>
  • Reúso: <...>
  • Classes genéricas: <...>

Padronização

Padronização de nomencatura

  • <ids com todas minúsculas e underline>
  • <classes com todas minúsculas e ífem>

Attachments