Componentes
O NEO possui vários componentes para a criação da visão. A visão no NEO é feita através de JSPs e os componentes são tags. Existem tags para todos os tipos de funcionalidades comuns no desenvolvimento de aplicações empresariais. Este capítulo visa mostrar como utilizar essas tags.
Arquitetura
Todas as tags do neo extendem a classe BaseTag. A classe BaseTag provê funcionalidades básicas e bastante úteis para a criação de tags. Um aspecto importante da BaseTag é a utilização de templates. Os templates são arquivos JSP que servem para montar a parte de visão da Tag. É como o MVC, a tag é o controller e o JSP é a visão.
Cada template deve ficar no mesmo pacote da classe dentro de /WEB-INF/classes. Por exemplo, a tag br.com.linkcom.neo.view.template.ListagemTag possui um template. Esse template deve ficar no diretório /WEB-INF/classes/br/com/linkcom/neo/view/template/ e deve ter o nome ListagemTag.jsp (o mesmo nome da classe, só que com extensão JSP). Não é possível ler templates dentro de arquivos JAR por isso os templates devem ficar no /WEB-INF/classes. Não é necessário, apesar disso, copiar os templates do NEO para o /WEB-INF/classes o NEO irá verificar se existe algum template que esteja faltando e copiar de dentro do JAR para o /WEB-INF/classes da aplicação. Entretanto só é possível fazer essa cópia se o projeto estiver publicado como diretório (e não como um arquivo compactado).
Quando utilizar a tag br.com.linkcom.neo.view.template.ListagemTag e essa tag requisitar a inclusão do template o NEO irá procurar o arquivo /WEB-INF/classes/br/com/linkcom/neo/view/template/ListagemTag.jsp se não encontrar ele vai copiar esse arquivo que está no JAR do NEO para o diretório correto. É possível sobrescrever algum template do NEO criando um arquivo com o nome correto e colocando-o no diretório da tag. Se já existir um arquivo de template no diretório o NEO não irá sobrescrever o template que já está na aplicação.
Importante: Sempre utilize a publicação aberta (com diretórios) ao invés de fechada (arquivo compactado) para o NEO conseguir copiar os templates.
As vezes uma tag precisa de vários templates diferentes como é o caso da br.com.linkcom.neo.view.InputTag. Os templates então, ganham sufixos e o nome dos arquivos ficam como InputTag-text.jsp, InputTag-date.jsp.
Componentes básicos
No NEO existem duas categorias de tags: Neo e templates. Cada uma dessas categorias é representada por uma taglib. Para utilizar as tags do NEO insira no cabeçalho do JSP a seguinte linha:

    [JSP]
    <%@taglib prefix="n" uri="neo"%>

O arquivo tld responsável por essa taglib é o neo.tld e já está incluso dentro do JAR do NEO.
n:input
Tag responsável por renderizar inputs na tela. Pode ser qualquer componente HTML que seja um input como text, select, radio, checkbox, textarea, etc. Essa tag renderiza o tipo de componente de acordo com o atributo type. Exemplo:

    [JSP]
    	<n:input name="texto"          type="text"/>
    	<n:input name="habilitado"     type="checkbox"/>
    	<n:input name="dataNascimento" type="date"/>

É possível também informar um value para o input. Exemplo:

    [JSP]
    	<n:input name="texto"          type="text"     value="${bean.texto}"/>
    	<n:input name="habilitado"     type="checkbox" value="${bean.habilitado}"/>
    	<n:input name="dataNascimento" type="date"     value="${bean.dataNascimento}"/>

Quando o value for informado e o valor informado não for null o NEO consegue alterar o tipo do input de acordo com o tipo de dados. Exemplo:

    [JSP]
    	<n:input name="texto"          value="${bean.texto}"/>
    	<n:input name="habilitado"     value="${bean.habilitado}"/>
    	<n:input name="dataNascimento" value="${bean.dataNascimento}"/>

Se ${bean.texto} retornar uma String o tipo será text.
Se ${bean.habilitado} retornar um Boolean o tipo será checkbox.
Se ${bean.dataNascimento} retornar um Date o tipo será date.
Não existe <input type="date"> no HTML. O tipo date do NEO na verdade é um type="text" com alguns eventos javascript para formatar a entrada de dados com o formato de data. Existem outros tipos no input no NEO que utilizam formatação. E serão vistos mais adiante.
É possível utilizar o n:input para criar combos. Para fazer um combo o atributo type deve ser select-one ou select-many (se desejar um combo com várias opções selecionáveis). Quando o tipo for select-one ou select-many o atributo itens deve ser informado. Exemplo:

    [JSP]
    	<n:input name="municipio" type="select-one" value="${bean.municipio}" itens="${listaMunicipio}"/>

Nesse caso será renderizado um combo onde o valor selecionado será o que estiver em ${bean.municipio}. Se ${bean.municipio} for um objeto de uma classe anotado com @Entity ou o atributo itens for informado, é possível não informar o type. Exemplo:

    [JSP]
    	<n:input name="municipio" value="${bean.municipio}" itens="${listaMunicipio}"/>

Dica: Sempre que o atributo value do input for um objeto cuja classe for anotada com @Entity ou o atributo itens for informado, o type será select-one.
O atributo type também pode receber um objeto class. Com esse class o NEO escolhe qual o melhor tipo de input para o dado. Exemplo:

    [JSP]
    <n:input name="texto" type="<% =String.class%>"/>
    <n:input name="habilitado" type="<% =Boolean.class%>"/>

Se a classe informada no atributo type for anotada com @Entity, o tipo será select-one.
Sempre que o input for relativo a alguma proprieade que possua @Entity. O atributo itens também pode ser omitido. Exemplo:

    [JSP]
    <n:input name="municipio" type="<% =Municipio.class%>"/>

ou

    [JSP]
    <n:input name="municipio" type="${classeMunicipio}"/>

Aqui o tipo será select-one porque a classe é anotada com @Entity. Para configurar o atributo itens o NEO irá executar o método findForCombo no DAO de município. O DAO deve ter o nome MunicipioDAO. Se nenhum DAO for encontrado a lista será vazia.
O NEO utilizará para mostrar como label a propriedade que tiver a anotação @DescriptionProperty no getter. O @DescriptionProperty indica qual é a propriedade que descreve o bean.
Dica: Sempre coloque @DescriptionProperty em alguma propriedade do bean que for anotado com @Entity
Sempre que a propriedade for um tipo anotado com @Entity cada option do select terá uma sitaxe especial para valores que são entidade. Supondo que temos a classe empresa.sistema.Municipio e o atributo anotado com @Id for id o value de um option para essa classe seria assim:
empresa.sistema.Municipio[id=6]
Isso permite que o atributo chegue ao sevidor da seguinte forma municipio=empresa.sistema.Municipio[id=6] o NEO ao mapear a propriedade municipio irá criar um bean Municipio e setar o id como 6. Essa sintaxe não é utilizada no desenvolvimento de aplicações, mas é importante saber como o mapeamento é feito. A utilização dessa sintaxe é apenas feita pelo NEO, para o usuário do framework todo o mapeamento é automático.
Atributos

Nome | Descrição | Valor
name | Nome que será colocado no input | name
forceValidation | Indica se deve ser forçada a validação do campo. Somente aplicável a campos tipo hidden | true/false
autoSugestUniqueItem | Utilizado somente quando o tipo for combo. Informa se caso existir apenas um item no combo ele deva ser automaticamente selecionado. | true/false
holdValue | Utilizado apenas em combos e se estiver utilizando ajax. Indica se em um reload de ajax o valor deve permanecer configurado. Se a nova lista que veio do servidor tiver o valor selecionado atualmente ele não será modificado. | true/false
useAjax | Indica se deve ser utilizado ajax nesse input. Somente utilizado para combos e se ele estiver englobado pela tag comboReloadGroup. | true/false
onLoadItens | Evento disparado quando um ajax é executado e os itens do combo são atualizados. | javascript
type | Indica qual é o tipo do input. Aceita valores string com a descrição do tipo ou um objeto da classe Class. | BUTTON, CHECKBOX, CHECKLIST, FILE, HIDDEN, IMAGE, PASSWORD, RADIO, RESET, SUBMIT, TEXT, DATE, TIME, FLOAT, INTEGER, MONEY, CPF, CNPJ, CEP, CPFCNPJ, INSCRICAO-ESTADUAL, CREDIT-CARD, SELECT-ONE, SELECT-MANY, SELECT-ONE-BUTTON, SELECT-ONE-RADIO, TEXT-AREA, TELEFONE, HTML
value | Valor do input |
selectLabelProperty | Utilizado em combos. Indica qual propriedade deve ser utilizada para ser mostrada nas opções. |
label | Legenda do input. |
required | Indica se o input é obrigatório. Isso faz com que uma marca especial de campos obrigatórios seja impressa | true/false
itens | Lista ou mapa com os itens que devem ser mostrados. Se esse atributo for configurado e o type não, o type passa a ser select-one |
optionalParams | No caso de uma chamada AJAX indica quais parâmetros são opcionais | lista de parâmetros separados por vírgula
cols | Utilizado em textarea. Indica quantas colunas tem o textarea | inteiro
rows | Utilizado em textarea. Indica quantas linhas tem o textarea | inteiro
showLabel | Indica se deve ser mostrado uma legenda para o input | true/false
includeBlank | Utilizado com combos. Indica se deve ser incluida a opção 'em branco' | true/false
blankLabel | Nome que deve ser colocado na opção 'em branco' |
selectOnePath | Para tipos select-one-button indica qual é o path para onde o botão irá | caminho de algum controller
reloadOnChange | Indica se ao modificar o valor do input deve ser feito um reload na página | true/false
trueFalseNullLabels | Legendas para valores true, false e null. Utilizando quando o tipo for Boolean | Valores para true, false e null separados por vírgula
write | Se o tipo for hidden indica se deve ser impresso o valor na tela |
labelStyle | Estilo da legenda do input |
labelStyleClass | Classe CSS da legenda do input |

n:output
A tag output serve para mostrar algum dado. Ela já formata automaticamente o dado para a exibição. Se desejar pode ser utilizado o atributo pattern para tipos double ou date.
Atributos

Nome | Descrição | Valor
value | Valor que deve ser impresso |
pattern | Padrão que deve ser utilizado para formatar double ou date | Padrão para double ou date
escapeHTML | Indica se deve ser feito o escape do HTML | true/false
styleClass | Class CSS para o outpur |
style | Estilo CSS para o output |
trueFalseNullLabels | Legendas para valores true, false e null. Utilizando quando o tipo for Boolean | Valores para true, false e null separados por vírgula

n:bean e n:property
As tags n:bean e n:property só funcionam em conjunto. Elas servem para ler informações de beans e disponibilizarem para o JSP. A tag n:bean representa um bean que estiver no escopo. A tag n:property representa a propriedade de algum bean. A tag n:property deve estar aninhada a uma tag n:bean. A tag n:bean serve apenas como referência para a tag n:property saber de qual bean deve ler as propriedades. Vamos supor o seguinte bean:

    package teste;

    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.SequenceGenerator;

    public class Aluno {

    	private Integer id;
    	private String nome;
    	private Boolean matriculado;

    	public Boolean getMatriculado() {
    		return matriculado;
    	}
    	public void setMatriculado(Boolean matriculado) {
    		this.matriculado = matriculado;
    	}
    	public Integer getId() {
    		return id;
    	}
    	public String getNome() {
    		return nome;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public void setNome(String nome) {
    		this.nome = nome;
    	}
    }

Suponhamos também que exista um bean da classe Aluno no escopo com o nome aluno. A utilização das tags é feita da seguinte forma:

    [JSP]
    <n:bean name="aluno">
    	<n:property name="id">

    	</n:property>
    	<n:property name="nome">

    	</n:property>
    	<n:property name="matriculado">

    	</n:property>
    </n:bean>

A tag n:bean indica que devemos utilizar o bean aluno que está no escopo. É posssível também que não exista o bean com o nome aluno escopo. Quando não houver bean ou o bean for nulo o atributo valueType deve ser informado. O atributo valueType recebe a classe do bean em questão.
Cada tag n:property representa uma propriedade e ela coloca no escopo informações relativas a propriedade.

    [JSP]
    <n:bean name="aluno">
    	<n:property name="id">
    		Nome: ${name}
    		Valor: ${value}
    		Type: ${type}
    	</n:property>
    	<n:property name="nome">
    		Nome: ${name}
    		Valor: ${value}
    		Type: ${type}
    	</n:property>
    	<n:property name="matriculado">
    		Nome: ${name}
    		Valor: ${value}
    		Type: ${type}
    	</n:property>
    </n:bean>

O exemplo acima mostra a utilização da tag property para mostrar as informações name, value e type de cada propriedade. É interessante utilizar a tag n:property para preencher os atributos da tag n:input veja o exemplo:

    [JSP]
    <n:bean name="aluno">
    	<n:property name="id">
    		<n:input name="${name}" value="${value}" type="${type}"/>
    	</n:property>
    	<n:property name="nome">
    		<n:input name="${name}" value="${value}" type="${type}"/>
    	</n:property>
    	<n:property name="matriculado">
    		<n:input name="${name}" value="${value}" type="${type}"/>
    	</n:property>
    </n:bean>

A classe n:input lê do escopo, caso não tenham sido informados, os atributos necessários. Isso simplifica a utilização da tag n:property com n:input. Veja:

    [JSP]
    <n:bean name="aluno">
    	<n:property name="id">
    		<n:input/>
    	</n:property>
    	<n:property name="nome">
    		<n:input/>
    	</n:property>
    	<n:property name="matriculado">
    		<n:input/>
    	</n:property>
    </n:bean>

É possível utilizar tags n:property aninhadas. Como no exemplo:

    [JSP]
    <n:bean name="aluno">
    	<n:property name="municipio">
    		<n:property name="nome">
    			<n:input/>
    		</n:property>
    	</n:property>
    </n:bean>

No exemplo acima estamos criando um input para a propriedade nome que está dentro da propriedade municipio dentro de aluno.
Atributos n:bean

Nome | Descrição | Valor
name | Nome no escopo do bean que deve ser utilizado. | Nome de algum atributo do escopo.
propertyPrefix | Uma tag n:property aninhada coloca no escopo o nome do input. É possível que todos os property aninhados possuam um prefixo no nome do campo. | Prefixo para o nome dos property
propertyIndex | Uma tag n:property aninhada coloca no escopo o nome do input. É possível que todos os property aninhados possuam um indice no nome do campo. | Índice que deve ser utilizado nos property
valueType | Quando o name indicar algum atributo nulo. É obrigatório informar o valueType. O valueType é a classe do bean. | Classe do bean
varLabel | A classe n:bean coloca no escopo do displayName do bean. O atributo varLabel indica com qual nome o displayName deve ser colocado no escopo |

Atributos n:property

Nome | Descrição | Valor
name | Nome da propriedade que deve ser utilizada |
varValue | A tag property coloca no escopo o valor da propriedade. O atributo varValue indica com qual nome deve ser colocado o valor no escopo. |
varLabel | A tag property coloca no escopo o label da propriedade. O atributo varLabel indica com qual nome deve ser colocado o label no escopo. |
varName | A tag property coloca no escopo o nome que deve ser utilizado no input da propriedade. O atributo varName indica com qual nome deve ser colocado o nome do input no escopo. |
varAnnotations | A tag property coloca no escopo as anotações da propriedade. O atributo varAnnotations indica com qual nome devem ser colocadas as anotações no escopo. |
varType | A tag property coloca no escopo o tipo (classe) da propriedade. O atributo varType indica com qual nome deve ser colocado o tipo no escopo. |
varParameterizedTypes | A tag property coloca no escopo o tipo parametrizado (quando utilizar generics em coleções por exemplo) da propriedade. O atributo varParameterizedTypes indica com qual nome deve ser colocado o tipo parametrizado no escopo. |

Dica: Deixe os atributos das tags n:bean e n:property com valores padrão. Não existe situação onde será necessário definir algum atributo que não seja o name (tanto na tag bean quanto na property). Isso evitará problemas caso os atributos não sejam manipulados corretamente e ainda facilitará o desenvolvimento. Em algumas situações talvez seja necessário utilizar o atributo propertyPrefix ou propertyIndex da tag bean mas isso pode ser evitado com a utilização de outras tag como forEachBean ou dataGrid.
n:panelGrid
Podemos considerar o n:panelGrid como um componente para organizar o posicionamento de outros componentes. Ele renderiza uma tabela HTML com a vantagem de não ter que especificar os TRs. Você define o número de colunas que deseja para o n:panelGrid e ele cria as linhas de acordo. Dentro do panelGrid devem ser colocados outro componente o n:panel. O n:panel é equivalente ao TD do HTML. Então o panelGrid é um componente para organizar panels. Veja um exemplo:

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel>Linha 1 Coluna 1</n:panel>
    	<n:panel>Linha 1 Coluna 2</n:panel>
    	<n:panel>Linha 2 Coluna 1</n:panel>
    	<n:panel>Linha 2 Coluna 2</n:panel>
    	<n:panel>Linha 3 Coluna 1</n:panel>
    	<n:panel>Linha 3 Coluna 2</n:panel>
    </n:panelGrid>

O código acima irá renderizar uma tabela com três linhas e duas colunas. Como foi definido que o n:panelGrid tem duas colunas, a cada dois n:panel um TR será criado.
Existem várias formas de personalizar o estilo do panelGrid e os panels. É possível especificar o estilo do TD no próprio panel.

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel style="color:green">Linha 1 Coluna 1</n:panel>
    	<n:panel class="coluna2">Linha 1 Coluna 2</n:panel>
    </n:panelGrid>

Ou no próprio panelGrid:

    [JSP]
    <n:panelGrid columnStyles="color:red,color:green">
    	<n:panel>Linha 1 Coluna 1</n:panel>
    	<n:panel>Linha 1 Coluna 2</n:panel>
    </n:panelGrid>

O atributo columnStyles serve para definir o estilo das colunas. É possível definir o estilo de várias colunas ao mesmo tempo, para isso basta separar os valores por vírgula como no exemplo. A primeira coluna terá o estilo color:red, a segunda color:green, a terceira color:red e assim por diante. O mesmo pode ser feito para o atributo columnStyleClasses só que nesse caso ao invés de configurar o atributo style do td, será configurado o atributo class.
Utilizando a mesma lógica também é possível colocar estilo nos TRs com os atributos rowStyles e rowStylesClasses.
É possível um componente ser utilizado no lugar de um panel veja o exemplo:

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel>Nome</n:panel>
    	<n:input name="nome" type="text"/>
    </n:panelGrid>

Sempre que outro componente estiver no lugar de um panel. Um panel será criado para ele. O código acima é equivalente à:

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel>Nome</n:panel>
    	<n:panel>
    		<n:input name="nome" type="text"/>
    	</n:panel>
    </n:panelGrid>

É possível ainda configurar alguma propriedade do panel implicito. Para isso é só escrever panel e o nome da propriedade que se deseja configurar. Exemplo:

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel>Nome</n:panel>
    	<n:input name="nome" type="text" panelStyle="color:blue"/>
    </n:panelGrid>

O input ficará dentro de um TD com o style="color:blue".
O panel também suporta colspan. O panelGrid irá levar isso em consideração quando for criar as linhas. Exemplo:

    [JSP]
    <n:panelGrid columns="2">
    	<n:panel>Linha 1 Coluna 1</n:panel>
    	<n:panel>Linha 1 Coluna 2</n:panel>
    	<n:panel colspan="2">Linha 2 Coluna 1</n:panel>
    	<n:panel>Linha 3 Coluna 1</n:panel>
    	<n:panel>Linha 3 Coluna 2</n:panel>
    </n:panelGrid>

n:tabPanel
O componente tabPanel serve para criar abas. Cada aba é representada por uma tag panel (a mesma do panelGrid). O tabPanel lê os panels internos e monta uma aba para cada panel. Cada panel pode especificar um título para a aba. Exemplo:

    [JSP]
    <n:tabPanel id="tab1">
    	<n:panel title="Aba 1">
    		Conteúdo da aba 1
    	</n:panel>
    	<n:panel title="Aba 2">
    		Conteúdo da aba 2
    	</n:panel>
    </n:tabPanel>

De acordo com o exemplo acima serão criadas duas abas. Com seus respectivos títulos e seus conteúdos. A tag tabPanel precisa do atributo id. Esse id é apenas uma referência para a tag. Caso ocorra um reload da tela o tabPanel saberá qual panel estava ativo.
É possível definir um evento quando uma aba for selecionada. Esse evento é configurado no panel através do atributo onSelectTab. Exemplo:

    [JSP]
    <n:tabPanel id="tab1">
    	<n:panel title="Aba 1" onSelectTab="alert('aba 1 selecionada');">
    		Conteúdo da aba 1
    	</n:panel>
    	<n:panel title="Aba 2" onSelectTab="alert('aba 2 selecionada');">
    		Conteúdo da aba 2
    	</n:panel>
    </n:tabPanel>

n:group
A tag n:group é equivalente a tag n:panelGrid com a diferença que a n:group renderiza uma borda em volta da tabela e dá a possibilidade de colocar também um título. A borda é na verdade a tag fieldset do HTML e o título é a tag LEGEND. Exemplo:

    [JSP]
    <n:group columns="2" legend="Dados Cadastrais">
    	<n:panel>Nome</n:panel>
    	<n:input name="nome" type="text"/>

    	<n:panel>Telefone</n:panel>
    	<n:input name="telefone" type="telefone"/>
    </n:group>

n:dataGrid
Para montar tabelas de dados utilizamos a tag n:dataGrid. A tag dataGrid recebe uma lista de objetos sobre os quais deseja-se mostrar alguma informação. A dataGrid monta uma tabela e para cada item da lista monta uma linha. A tag n:dataGrid é utilizada em conjunto da tag n:column. Cada n:column define uma coluna do dataGrid. Dentro da tag column existem 3 áreas: header, body e footer. Cada área é especificada por uma tag. Ao criar o dataGrid o header é renderizado (para montar a linha de título por exemplo), depois o body é renderizado uma vez para cada item, e por fim o footer. A tag dataGrid coloca no escopo o bean sobre o qual está iteragindo. Dentro do column esse bean é utilizado para mostrar determinada informação. Suponha que exista uma lista de objetos Aluno no escopo com o nome listaAluno. E que a classe Aluno possua os campos id, nome e dataNascimento. Com base nessas informações poderiamos montar um dataGrid de alunos dessa forma:

    [JSP]
    	<n:dataGrid itens="${listaAluno}">
    		<n:column>
    			<n:header>Id</n:header>
    			<n:body>${row.id}</n:body>
    		</n:column>
    		<n:column>
    			<n:header>Nome</n:header>
    			<n:body>${row.nome}</n:body>
    		</n:column>
    		<n:column>
    			<n:header>Data de nascimento</n:header>
    			<n:body>${row.dataNascimento}</n:body>
    		</n:column>
    	</n:dataGrid>

O dataGrid por padrão coloca o bean no escopo com o nome de row. É possível definir o nome que o bean é colocado no escopo através do atributo var. Exemplo:

    [JSP]
    	<n:dataGrid itens="${listaAluno}" var="aluno">
    		<n:column>
    			<n:header>Id</n:header>
    			<n:body>${aluno.id}</n:body>
    		</n:column>
    		<n:column>
    			<n:header>Nome</n:header>
    			<n:body>${aluno.nome}</n:body>
    		</n:column>
    		<n:column>
    			<n:header>Data de nascimento</n:header>
    			<n:body>${aluno.dataNascimento}</n:body>
    		</n:column>
    	</n:dataGrid>

Para economizar é possível definir o conteúdo do header através da tag column, como no exemplo:

    [JSP]
    <n:dataGrid itens="${listaAluno}" var="aluno">
    	<n:column header="Id">
    		<n:body>${aluno.id}</n:body>
    	</n:column>
    	<n:column header="Nome">
    		<n:body>${aluno.nome}</n:body>
    	</n:column>
    	<n:column header="Data de nascimento">
    		<n:body>${aluno.dataNascimento}</n:body>
    	</n:column>
    </n:dataGrid>

Com o conteúdo do header na tag column, é possível também suprimir a tag n:body.

    [JSP]
    <n:dataGrid itens="${listaAluno}" var="aluno">
    	<n:column header="Id">
    		${aluno.id}
    	</n:column>
    	<n:column header="Nome">
    		${aluno.nome}
    	</n:column>
    	<n:column header="Data de nascimento">
    		${aluno.dataNascimento}
    	</n:column>
    </n:dataGrid>

É recomendável utilizar as tags dataGrid e column em conjunto com as tags bean e property. Isso faz com que o NEO formate os dados e o conteúdo de cada column fique igual. Exemplo:

    [JSP]
    <n:dataGrid itens="${listaAluno}" var="aluno">
    	<n:bean name="aluno" valueType="<% =Aluno.class%>">
    		<n:property name="id">
    			<n:column header="${displayName}">
    				<n:output value="${value}"/>
    			</n:column>
    		</n:property>
    		<n:property name="nome">
    			<n:column header="${displayName}">
    				<n:output value="${value}"/>
    			</n:column>
    		</n:property>
    		<n:property name="telefone">
    			<n:column header="${displayName}">
    				<n:output value="${value}"/>
    			</n:column>
    		</n:property>
    	</n:bean>
    </n:dataGrid>

Apesar de ter mais código repare que a única diferença entre as colunas é o atributo name do n:property. Existe uma tag que será vista mais adiante (t:property) que representa o seguinte bloco:

    [JSP]
    <n:property name="?">
    	<n:column header="${displayName}">
    		<n:output value="${value}"/>
    	</n:column>
    </n:property>

A '?' seria substituida pela propriedade desejada. Isso faz com que cada coluna gaste apenas uma linha. Por isso é recomendável utilizar as tags n:bean e n:property.
Para eliminar a necessidade da tag bean, a tag dataGrid provê uma facilidade. É possível especificar o tipo de dados no próprio dataGrid. Quando especificado a tag n:bean é criada automaticamente. Exemplo:

    [JSP]
    <n:dataGrid itens="${listaAluno}" var="aluno" itemType="<% =Aluno.class%>">
    	<n:property name="id">
    		<n:column header="${displayName}">
    			<n:output value="${value}"/>
    		</n:column>
    	</n:property>
    	<n:property name="nome">
    		<n:column header="${displayName}">
    			<n:output value="${value}"/>
    		</n:column>
    	</n:property>
    	<n:property name="telefone">
    		<n:column header="${displayName}">
    			<n:output value="${value}"/>
    		</n:column>
    	</n:property>
    </n:dataGrid>

n:menu
A tag n:menu é bem simples e bastante util. Ela renderiza um menu hierárquico através da definição de um arquivo XML. A utilização da tag é simples:

    [JSP]
    <n:menu menupath="/WEB-INF/menu.xml"/>

O único atributo da tag menu é o menupath. O menupath é o caminho de um arquivo xml que deve ser utilizado para renderizar o menu. Um exemplo desse XML:

    [JSP]
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE menugroup PUBLIC "//LinkCom//Neo Menu 1.0//EN" "http://www.linkcom.com.br/framework/dtd/menu.dtd">
    <menugroup>
    	<menu title="Cadastro">
    		<menu title="Aluno" url="/login/crud/Aluno" />
    		<menu title="Bolsista" url="/login/crud/Bolsista" />
    		<menu title="Cliente" url="/login/crud/Cliente" />
    		<menu title="Grupo" url="/login/crud/Grupo" />
    		<menu title="Natureza" url="/login/crud/Natureza" />
    		<menu title="Orientador" url="/login/crud/Orientador" />
    		<menu title="Processo" url="/login/crud/Processo" />
    		<menu title="-----" />
    		<menu title="Andamento" url="/login/crud/Andamento" />
    		<menu title="Anexo" url="/login/crud/Anexo" />
    		<menu title="Papel" url="/login/crud/Papel" />
    		<menu title="Partecontraria" url="/login/crud/Partecontraria" />
    		<menu title="Permissao" url="/login/crud/Permissao" />
    		<menu title="Situacao" url="/login/crud/Situacao" />
    		<menu title="Tela" url="/login/crud/Tela" />
    		<menu title="Usuario" url="/login/crud/Usuario" />
    		<menu title="Usuariopapel" url="/login/crud/Usuariopapel" />
    		<menu title="Autorização" url="/login/process/Autorizacao" />
    	</menu>

    	<menu title="Sair" url="/logout.jsp" />
    </menugroup>

Cada tag menu define um item do menu. Podem existir tags menu dentro de tags menu. Isso cria a hierarquia do menu. O atributo title é o título do menu e a url é o caminho. Na url não é necessário colocar o caminho da aplicação. Repare o item menu com valor title="------" isso serve para criar um separador para o menu. O estilo do menu é definido pelo arquivo theme.css. Existe um arquivo desse dentro do NEO que é utilizado caso a aplicação não defina nenhum arquivo de estilo. Para definir um arquivo de estilo para o menu, basta criar o arquivo theme.css e colocá-lo dentro do diretório /css da aplicação. Se existir um arquivo /css/theme.css o NEO utilizará esse arquivo e não o que vem como padrão. Para saber quais estilos colocar no arquivo veja o arquivo original theme.css do NEO.
n:form
A tag n:form define uma tag FORM do HTML. É possível definir a URL de um controller e também a action para onde deve ser enviada a requisição. Quando nenhum é definido a URL é a última URL chamada. Veja o exemplo da utilização da tag n:form:

    [JSP]
    <n:form>
    	<n:input name="nome" type="text"/>
    </n:form>

n:submit
A tag submit renderiza um componente para enviar os dados do formulário. Não necessariamente é um botão submit, pode ser um link ou imagem também. A tag submit define o comportamento de envio de dados e não o elemento HTML que será renderizado. A tag n:submit sempre deve ser utilizada dentro de uma tag n:form. A tag submit pode sobrescrever a url ou a action para onde devem ser enviados os dados. Exemplo:

    [JSP]
    <n:form>
    	.
    	.
    	.
    	<n:submit url="/login/Controller" action="executar">Enviar</n:submit>
    	.
    </n:form>

Para definir o tipo de renderização utilizamos o atributo type. Temos três tipos de renderização: button (padrão), image e link. Para utilizar o tipo image também é necessário informar o atributo img que conterá o caminho da imagem.

    [JSP]
    <n:form>
    	.
    	.
    	.
    	<n:submit url="/login/Controller" action="executar" type="link">Enviar</n:submit>
    	.
    </n:form>

Se desejar que ao invés de o botão dê um submit no form, ele execute um código javascript. É só colocar na url o prefixo javascript:

    [JSP]
    <n:form>
    	.
    	.
    	.
    	<n:submit url="javascript:alert('Javascript ao invés de submit')">Enviar</n:submit>
    	.
    </n:form>

n:link
A tag link possui a mesma lógica da tag submit só que com comportamento de link. Um corpotamento de link é apenas a mudança de página sem o envio dos dados do formulário. Exemplo:

    [JSP]
    <n:link url="/login/Controller" action="executar">Link</n:link>

Templates
Os templates do neo podem ser utilizados adicionando a seguinte linha ao JSP:

    [JSP]
    <%@taglib prefix="t" uri="template"%>

Os templates do NEO são apenas o agrupamento de outras tags para atingir uma nova funcionalidade. Os templates geralmente contém layouts e estilos e por isso devem ser atualizados para cada site. O NEO possui templates para relatórios, cruds e telas diversas que facilitam o desenvolvimento dessas telas (a explicação de templates para fins específicos como CRUD, serão explicados nos capítulos específicos). Lembre-se que os templates possuem JSPs que podem ser alterados para modificar o resultado da tag (explicado no início do capítulo).
t:tela
O template tela representa uma tela com o conteúdo mínimo necessário. Ela cria uma tabela para acomodar o conteúdo da página com um título.
t:property
O template property é um dos mais importantes e mais utilizados no NEO. Ele cria um input ou output para determinada propriedade e é flexível o suficiente para se adequar a qualquer local da tela. Para isso o property utiliza dois conceitos. O primeiro é definido pelo atributo mode, que pode ser input ou output. Se for input será renderizado um campo para entrada de dados, se for output será mostrado o valor da propriedade.
O outro conceito definido pelo atributo renderAs define como o property deve ser renderizado. Os valores possíveis para renderAs são:

- column: renderiza o property como uma coluna de um dataGrid
- double: renderiza um n:panel para o label e outro n:panel para o valor (ou input)
- sinlge: renderiza apenas um n:panel para o label e o valor (ou input)
- doubleline: renderiza apenas um n:panel para o label e o valor (ou input) mas separa o label do valor com um <BR> (cada um em uma linha)

O property possui todos os atributos do n:input e n:output, esses atributos tem a mesma funcionalidade dos atributos correspondentes nas tags input e output.
Qualquer atributo que desejar para o input pode ser colocado na tag property.
Se estiver utilizando o renderAs como column é possível utilizar atributos para configurar os estilos do header body e footer da coluna.
Exemplos de utilização do t:property.

    [JSP]
    <n:dataGrid itens="${lista}" itemType="<% =teste.Aluno.class%>">
    	<t:property name="nome"           renderAs="column"/>
    	<t:property name="telefone"       renderAs="column"/>
    	<t:property name="dataNascimento" renderAs="column"/>
    </n:dataGrid>

    [JSP]
    <n:panelGrid columns="2">
    	<t:property name="nome"           renderAs="double" mode="input"/>
    	<t:property name="telefone"       renderAs="double" mode="input"/>
    	<t:property name="dataNascimento" renderAs="double" mode="input"/>
    </n:panelGrid>

No primeiro exemplo cada property irá criar uma coluna para a propriedade. Utilizar a tag t:property seria o mesmo que utilizar:

    [JSP]
    <n:property name="nome">
    	<n:column header="${label}">
    		${value}
    	</n:column>
    </n:property>

No segundo exemplo cada property irá criar dois panels, um para o label e outro para o input. Seria o mesmo que fazer:

    [JSP]
    <n:property name="nome">
    	<n:panel>${label}</n:panel>
    	<n:panel><n:input/></n:panel>
    </n:property>

É possível evitar ter que configurar o mode ou o renderAs de vários t:property. Quando o t:property estiver dentro de um dataGrid ele será renderAs="column", então o nosso exemplo ficaria dessa forma:

    [JSP]
    <n:dataGrid itens="${lista}" itemType="<% =teste.Aluno.class%>">
    	<t:property name="nome"           />
    	<t:property name="telefone"       />
    	<t:property name="dataNascimento" />
    </n:dataGrid>

Outra forma de configurar vários input é utilizar o propertyConfig. Os atributos configurados no propertyConfig serão válidos para todos os t:property aninhados.

    [JSP]
    <n:panelGrid columns="2">
    	<t:propertyConfig renderAs="double" mode="input">
    		<t:property name="nome"           />
    		<t:property name="telefone"       />
    		<t:property name="dataNascimento" />
    	</t:propertyConfig>
    </n:panelGrid>

Outros templates
Existem outros templates para criação de telas de CRUD e relatórios e serão explicados nos capítulos que falarem desses assuntos.