«

»

Sep 12

Print this Post

Custom Tag CFML

Introdução

Quando promovemos reutilização de código, passamos a fazer uso constante do cfinclude.
Com essa prática frequente, por vezes são criadas templates que necessitam de variáveis, pre-definidas a sua invocação, o que provoca erros na implementação.

texto.cfm


<cfif IsDefined(”url.texto”)>
     <h1><cfoutput>#url.texto#</cfoutput> </h1>
</cfif>

executa.cfm


<cfparam name=”url.helloworld” default=”Hello World!” />
<cfinclude template=”exibir_variavel.cfm” />


Há casos em que essas variáveis são necessárias apenas ao template do include, sendo necessária uma ginástica impressionante para excluir esta variável após a execução da template.

executa.cfm


<cfif NOT IsDefined(”url.helloworld”)>
     <cfset url.helloworld=”Hello World!” >
     <cfset codHorror=”helloworld”>
</cfif>
<cfinclude template=”exibir_variavel.cfm” />
<cfif IsDefined(”codHorror”)>
     <cfset StructDelete(url,codHorror)>
</cfif>

Porém podemos criar chamadas mais funcionais, que promoverão um código mais limpo, sem que seja necessário o famoso código “macarrônicos”.

Custom Tags

Com o surgimento dos Componentes (cfc) as Custom Tags passaram a ser utilizadas com menos frequência do que em versões anteriores do ColdFusion Server, porém aplicações como o fórum criado por Raymond Camden comprovam sua importância, praticando um desenvolvimento integrado de CFCs e Custom Tags.

Elas são construidas com códigos CFML, como qualquer página CFM, e são invocadas através da junção do prefixo CF_ e o nome do arquivo sem a extensão, com um arquivo TEXTO.CFM invocariamos <CF_TEXTO>, através da tag CFMODULE ou ainda da tag CFIMPORT.

Na chamada podemos informar atributos, como em UDFs onde são passados parâmtros, numa exibição de TEXTO.CFM visto no incio do artigo, implementariamos uma chamada como:

executa.cfm


<CF_TEXTO texto=”Hello World!” >

E a variável texto será identificada no escopo Attributes. Mais a frente veremos outras formas de execução.

texto.cfm


<cfif IsDefined(”Attributes.texto”)>
     <h1><cfoutput>#Attributes.texto#</cfoutput> </h1>
</cfif>

No artigo CFX (Custom Tag) java vimos a obrigatoriedade do registro da classe transformando-a em uma tag, com Custom Tags CFML o mesmo processo não é necessário, porém o Servidor CF deve ser informado onde estão as paginas cfm que serão a base das tags, para isto basta entrar com o caminho completo da pasta no CFAdmin, em Extensions»Custom Tags Paths. Você pode registrar mais de um repositório.

Propriedades

Escopos

Custom Tags dispõem de três escopos.

Escopo Abrangência
Attributes Todo valor passado à uma Custom Tag estará contido neste escopo.
ThisTag Faz referência a todas as variáveis exclusivas a custom tags.
Caller A página que está executando a Custom Tag recebará variáveis atribuidas neste escopo.

ThisTag
Com a estrutura ThisTag recuperamos informações importantes sobre a execução da Custom Tag.

Variável Conteúdo
ThisTag.ExecutionMode Contém o valor referente ao estado de execução da Custom Tag.
Os valores podem ser:
– start, indica o inicio da execução;
– end, indica o fim da execução (depende de uma tag de fechamento);
– inactive, este estado ocorre quando alguma outra tag está sendo executada.
ThisTag.HasEndTag Contém a informação da existência ou não de uma tag de fechamento.
Os valores podem ser YES ou NO.
ThisTag.GeneratedContent Em uma chamada que exista tag de inicio, corpo e tag de encerramento, tudo que estiver no corpo será atribuído a ela, inclusive variáveis que receberam atribuições dentro do corpo estarão acessíveis nesta variáveis.
ThisTag.AssocAttribs Esta variável está relacionada a tag cfassociate, contém um array com todos os atributos de todas as custom tags aninhadas.

Quando em ThisTag.ExecutionMode é dito que pode conter três valores entenda que a Custom Tag poderá ser executada duas vezes em uma chamada, dependendo do modo da invocação.

CFASSOCIATE

Os métodos relacionados a Custom Tags dependem da tag cfassociate.
A tag cfassociate possui dois atributos:

baseTag – contém o nome da custom tag antecedente e
datacollection – substitui a key AssocAttribs em ThisTag.

primeira.cfm


<cfif ThisTag.ExecutionMode eq “start”>
     <b>
     <cfset ThisTag.StartPrimeira=”Start 1?>
<cfelseif ThisTag.ExecutionMode eq “end”>
     </b>
</cfif>

segunda.cfm


<cfassociate basetag=”CF_PRIMEIRA” datacollection=”myAssocAttribs”>
<cfif ThisTag.ExecutionMode eq “start”>
     <i>
     <cfset ThisTag.StartSegunda=”Start 2?>
<cfelseif ThisTag.ExecutionMode eq “end”>
     </i>
     <cfdump var=”#GetBaseTagList()#”/>
     <cfdump var=”#GetBaseTagData(’CF_PRIMEIRA’)#”/>
</cfif>

chamada.cfm


<CF_PRIMEIRA>
     <CF_SEGUNDA>
          texto
     </CF_SEGUNDA>
</CF_PRIMEIRA>

Resultado

Métodos

 

Método Retorno
GetBaseTagList() Retorna os nomes de todas as Custom Tags aninhadas, numa lista de valores delimitada por vírgula.
A posição de ocorrência do baseTag corresponde a ordem inversa de chamada das Custom Tags, tendo como ponto de orientação a baseTag atual para sabermos quais foram executados antes ou depois.
GetBaseTagData(baseTag,N) Retorna as variáveis, da baseTag informada, em uma estrutura onde as keys de primeiro ocorrência correspondem aos escopos e/ou variaveis criadas nas tags aninhadas.
N representa o nível de próximidade do antecessor ou descendente, é um parâmetro opcional, o default é 1.

 

Invocando Custom Tags

Já foi visto uma das formas de invocar uma custom tags (CF_ + Nome do arquivo), e também sabemos que elas podem trabalhar com as tags CFMODULE e CFIMPORT, são estas formas desenvolveremos agora.

CFMODULE

Com esta tag não é necessário armazenar as custom tags em um repositório registrado no Administrador.


<cfmodule attribute_name=”Tag_name”  attributecollection=”coleção_de_atributos” 
     name=”path” template=”path”>

Atributos Requerido Retorno
attribute_name opcional Define um nome de atributo.
attributecollection opcional Podemos passar todos os atributos necessários a custom tag, em forma de estrutura, onde as keys serão os nomes dos atributos.
name requerido se template ausente Caminho onde a raíz é um dos repositórios Custom Tag.
Uma atribuição como tag.texto demostra que em um dos repositórios existe uma pasta tag que dispõem de um arquivo texto.cfm
template requerido se name ausente Caminho relativo ou absoluto (como base um dos mappings), caminhos físicos não são válidos

Com estas informações reinvocamos o aninhamento, o resultado produzido será idêntico ao anterior.

chamada2.cfm


<cfmodule template=”/exemplos/primeira.cfm” >
     <cfmodule template=”/exemplos/segunda.cfm”>
          texto
     </cfmodule>
</cfmodule>

CFIMPORT

Como o cfmodule, esta tag não necessita de repositório registrado. Esta forma de utilização de custom tags é semelhante em JSP.


<cfimport prefix=”prefixo_da_tag” taglib=”path”>

Atributos Retorno
prefix Define o prefixo.
Uma chamada como <mytag:texto> demostra que o prefix é mytag e um dos arquivos importados foi texto.cfm.
taglib Caminho relativo ou absoluto (como base um dos mappings), caminhos físicos não são válidos

Aqui também percebemos o mesmo resultado das execuções anteriores.

chamada3.cfm


<cfimport prefix=”view” taglib=”/exemplos/”>
<view:primeira>
     <view:segunda>
          texto
     </view:segunda>
</view:primeira>

Observamos ainda que podemos utilizar custom tags como VIEW em uma framework CFMVC, o que podemos constatar em outro aplicativo de Raymond Camden

Conhecendo mais

Durante a implementaçao de custom tags são identificadas necessidades, como em toda implementação, então veremos aqui a utilização de CFEXIT e CFTROW dentre muitas das soluções existentes.
Para demostrar isso criaremos a terceira custom tag e executaremos algumas vezes provocando situações diferentes.

terceira.cfm


<cfif ThisTag.ExecutionMode eq “start”>
     <cfif NOT IsDefined(”Attributes.tag”)>
          <cfthrow type=”any” message=”key tag inexistente em attributes «br> Você fez isso de propósito?”»
     </cfif>
     <cfoutput><#Attributes.tag#></cfoutput>
     <cfset Caller.varCustomTag = StructNew() >
     <cfset Caller.varCustomTag.atributos = Attributes >
     <cfif NOT ThisTag.HasEndTag>
          <cfset Caller.varCustomTag.erro =”Cadê a tag de encerramento?” >
          <cfoutput></#Attributes.tag#></cfoutput>
          <!— encerramos a custom tag para que não seja executada a segunda parte da custom tag —>
          <cfexit method=”exittag”>
     </cfif>
<cfelseif ThisTag.ExecutionMode eq “end”>
     <cfif NOT Len(Trim(ThisTag.GeneratedContent))>
          <cfset Caller.varCustomTag.erro =”Cadê o conteúdo?” >
     </cfif>
     <cfoutput></#Attributes.tag#></cfoutput>
</cfif>

Nesta primeira chamada provocaremos a geração do erro falta de atributo.

chamada4.cfm


<cfimport prefix=”view” taglib=”/exemplos/”>
<view:terceira>

Resultado


<cfimport prefix=”view” taglib=”/exemplos/”>
<view:terceira tag=”h1?>
<cfdump var=”#Variables.varCustomTag#”>

Resultado


<cfimport prefix=”view” taglib=”/exemplos/”>
<view:terceira tag=”strong”></view:terceira>
<cfdump var=”#Variables.varCustomTag#”>

Resultado


<cfimport prefix=”view” taglib=”/exemplos/”>
<view:terceira tag=”script”>
     document.write(’Custom tag final’);
     document.write(’<br>’);
</view:terceira>
foi utilizada a tag html 
<i><cfoutput>#Variables.varCustomTag.atributos.tag#</cfoutput></i>

Resultado

by Pedro Claudio

Permanent link to this article: http://ensina.me/coldfusion/custom-tag-cfml/

Leave a Reply