|
|
|

|

|
Dicas
|

|
ASP - Active Server Page (Miscelâneas)
|
|
 |
Título da Dica: Fórum em XML e ASP - Parte II / III
|
 |
|
|
Postada em 3/10/2003 por ^HEAVY-METAL^
Módulo 2 - Folhas de estilo XSL
Comecemos pelos documentos XSL. Inicialmente, exibiremos os grupos disponíveis em um drop-down, que irá redirecionar a página para o grupo selecionado. Esta folha de estilo recebe como parâmetro opcional o grupo atual, para que o drop-down mantenha selecionado o grupo que o usuário se encontra.
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" omit-xml-declaration="yes" /> <xsl:variable name="GroupId"/>
<xsl:template match="//Groups"> <form action="" method="get" name="header"> <div> Selecione o fórum: <select onchange="document.location.href = this.options[this.selectedIndex].value"> <option value="index.asp">Página principal</option> <xsl:for-each select="Group"> <xsl:element name="option"> <xsl:if test="@GroupId = $GroupId"> <xsl:attribute name="selected">selected</xsl:attribute> </xsl:if> <xsl:attribute name="value">index.asp?GroupId=<xsl:value-of select="@GroupId"/></xsl:attribute> ::<xsl:value-of select="@Title"/> </xsl:element> </xsl:for-each> </select>
<xsl:if test="$GroupId != ''">
<xsl:element name="a"> <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="$GroupId"/>&Message=-1</xsl:attribute> [ Nova mensagem ] </xsl:element> <xsl:element name="a"> <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="$GroupId"/></xsl:attribute> [ Principal ] </xsl:element>
</xsl:if>
</div> </form> </xsl:template> </xsl:stylesheet>
Para quem acha que passamos rápido demais:
¤ Definimos uma variável chamada GroupId, que utilizaremos posteriormente, para mantermos realçada a opção de grupo atual. ¤ No template que seleciona todos os elementos do node Groups, criamos os campos de um form, que servirá para redirecionar para o grupo desejado, alterando a opção do drop-down. ¤ Se o @GroupId (atributo do elemento Group) for igual a $GroupId (variável que definimos anteriormente), acrescente um "SELECTED", para manter o grupo atual como padrão no drop-down. ¤ Mostramos a descrição do grupo selecionado. ¤ Criamos os links para nova mensagem e para retornar a página que exibe todas as threads. Estudaremos em detalhes esses elementos posteriormente, no Módulo 3 deste tutorial.
Teremos também que exibir as threads. As mensagens serão mostradas hierarquicamente, mostrando as respostas das perguntas identadas, com a utilização recursiva do elemento <UL> do HTML. Queremos aqui exibir o assunto da mensagem, o autor, data e hora e número de respostas na thread.
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="Messages"> <xsl:element name="ul"> <xsl:apply-templates select="Message[@GroupId='x']"/> </xsl:element> </xsl:template>
<xsl:template name="threads" match="Message"> <li> <xsl:element name="a"> <xsl:attribute name="href">index.asp?GroupId=<xsl:value-of select="@GroupId"/>&MsgId=<xsl:value-of select="@MsgId"/></xsl:attribute> <xsl:value-of select="@Subject"/> </xsl:element> - <xsl:value-of select="@UserName"/> - <xsl:value-of select="@TimeStamp"/> [<xsl:value-of select="count(.//Message)"/>] <ul> <xsl:apply-templates select="./Message"/> </ul> </li> </xsl:template> </xsl:stylesheet>
Aqui as coisas são mais simples, mas vamos passo-a-passo:
¤ No primeiro template, baseado no node Messages, criamos o elemento UL principal e aplicamos a segunda template apenas nos itens do grupo que estamos posicionados. ¤ Como você pode perceber, não usamos criamos uma variável GroupId neste template. No entanto, como os documentos XSL são também documentos XML, poderemos alterar o valor do node posteriomente. ¤ No template threads, exibimos os dados de identificação da mensagem (autor, data, etc.) e o link para exibirmos a mensagem. ¤ Um detalhe diferente é a contagem de nodes filhos do node atual. Isso é feito com a função count(.//Message). Traduzindo: do local atual (.) pegue todas os elementos Message, independentemente de o quão aninhados eles estão (//Message). ¤ Criamos um novo elemento <UL> e aplicamos os templates relacionados novamente. Então, recursivamente, os dados vão sendo montados.
Se você está acompanhando o raciocício até agora, ótimo! Só falta montar a rotina para a exibição de mensagens. Ela é um pouco maior que as demais, mas também usa conceitos simples. Vamos comentar cada parte separadamente e em detalhes:
<?xml version="1.0" encoding="iso-8859-1" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" omit-xml-declaration="yes" />
<xsl:variable name="UserName"/> <xsl:variable name="EMail"/> <xsl:variable name="GroupId"/> <xsl:variable name="NewMessage">0</xsl:variable>
Cabeçalho padrão, identificando o documento e o namespace usado. Também declaramos algumas variáveis que usaremos posteriormente.
<xsl:template match="Message"> <form action="index.asp?GroupId=@GroupId" method="POST"> <table border="0" style="border: 1 solid black;" align="center" width="75%"> <xsl:if test="$NewMessage = 0"> <tr class="color1"> <td>Assunto:</td> <td><xsl:value-of select="@Subject"/></td> </tr> <tr class="color2"> <td>Data:</td> <td><xsl:value-of select="@TimeStamp"/><small> (<xsl:value-of select="@IPAddress"/>)</small></td> </tr> <tr class="color2"> <td>De:</td> <td> <xsl:element name="a"> <xsl:attribute name="href">mailto:<xsl:value-of select="@EMail"/></xsl:attribute> <xsl:attribute name="target">_blank</xsl:attribute> <xsl:value-of select="@UserName"/> </xsl:element> <<xsl:value-of select="@EMail"/>> </td> </tr> <tr class="color3"> <td valign="top">Mensagem:</td> <td style="text-align: justify;"> <xsl:call-template name="replace"> <xsl:with-param name="content" ><xsl:value-of select="@Body"/></xsl:with-param> <xsl:with-param name="character"> </xsl:with-param> <xsl:with-param name="replace" /> </xsl:call-template> </td> </tr> </xsl:if> <xsl:call-template name="NewMessage" /> </table> </form> </xsl:template>
<xsl:template name="replace" > <xsl:param name="content" /> <xsl:param name="character"/> <xsl:param name="replace" />
<xsl:if test="not (contains( $content, $character ))"> <xsl:value-of select="$content"/> </xsl:if>
<xsl:if test="contains( $content, $character )"> <xsl:value-of select="substring-before($content,$character)"/><br /> <xsl:value-of select="$replace"/>
<xsl:if test="contains( substring-after($content,$character), $character )"> <xsl:call-template name="replace"> <xsl:with-param name="content" ><xsl:value-of select="substring-after($content,$character)"/></xsl:with-param> <xsl:with-param name="character"><xsl:value-of select="$character"/></xsl:with-param> <xsl:with-param name="replace" ><xsl:value-of select="$replace"/></xsl:with-param> </xsl:call-template> </xsl:if> <xsl:if test="not ( contains( substring-after($content,$character), $character ) )"> <xsl:value-of select="substring-after($content,$character)"/> </xsl:if> </xsl:if> </xsl:template>
Este template é o responsável pela exibição da mensagem. Detalhadamente:
Caso a variável NewMessage seja diferente de zero, significa que estamos editando uma nova mensagem, nao subordinada a nenhuma outra (uma nova thread). Então não é exibida a mensagem original, pois nao há nenhuma :-) Criamos então a estrutura da tabela onde a mensagem estará contida, exibindo os dados do remente da thread anterior. A única coisa diferente neste template é a rotina de quebra de linhas, exibida em negrito, necessária para a exbição correta da mensagem. Como a mensagem vai ser montada em um <TEXTAREA>, quebras de linhas podem ocorrer e devem ser exibidas como sendo <BR>. Para tanto a segunda template foi contruída. Ela faz uso de funções de manipulação de strings. Para estudar essas funções, baixe o XML SDK.
<xsl:template name="NewMessage"> <tr class="color1"> <td colspan="2"> <xsl:if test="$NewMessage = 0">Resposta:</xsl:if> <xsl:if test="$NewMessage = 1">Nova mensagem:</xsl:if> <a name="new" /> </td> </tr> <tr class="color2"> <td>Usuário:</td> <td> <xsl:element name="input"> <xsl:attribute name="type">text</xsl:attribute> <xsl:attribute name="name">UserName</xsl:attribute> <xsl:attribute name="size">30</xsl:attribute> <xsl:attribute name="value"><xsl:value-of select="$UserName"/></xsl:attribute> </xsl:element> </td> </tr> <tr class="color2"> <td>Email:</td> <td> <xsl:element name="input"> <xsl:attribute name="type">text</xsl:attribute> <xsl:attribute name="name">EMail</xsl:attribute> <xsl:attribute name="size">30</xsl:attribute> <xsl:attribute name="value"><xsl:value-of select="$EMail"/></xsl:attribute> </xsl:element> </td> </tr> <tr class="color2"> <td>Assunto:</td> <td> <xsl:element name="input"> <xsl:attribute name="type">text</xsl:attribute> <xsl:attribute name="name">Subject</xsl:attribute> <xsl:attribute name="size">30</xsl:attribute> <xsl:attribute name="value"> <xsl:if test="$NewMessage = 0">Re: <xsl:value-of select="@Subject"/></xsl:if> <xsl:if test="$NewMessage = 1"/> </xsl:attribute> </xsl:element> </td> </tr> <tr class="color3"> <td valign="top">Mensagem:</td> <td><textarea cols="70" rows="10" name="Body"></textarea></td> </tr> <tr class="color3"> <td colspan="2" align="center"> <xsl:element name="input"> <xsl:attribute name="type">hidden</xsl:attribute> <xsl:attribute name="name">Id</xsl:attribute> <xsl:attribute name="value"> <xsl:if test="$NewMessage = 0"><xsl:value-of select="@MsgId"/></xsl:if> <xsl:if test="$NewMessage = 1">-1</xsl:if> </xsl:attribute> </xsl:element> <xsl:element name="input"> <xsl:attribute name="type">hidden</xsl:attribute> <xsl:attribute name="name">GroupId</xsl:attribute> <xsl:attribute name="value"><xsl:value-of select="$GroupId"/></xsl:attribute> </xsl:element> <input type="hidden" name="action" value="new" /> <xsl:element name="input"> <xsl:attribute name="type">submit</xsl:attribute> <xsl:attribute name="value"> <xsl:if test="$NewMessage = 0">Postar resposta</xsl:if> <xsl:if test="$NewMessage = 1">Postar nova mensagem:</xsl:if> </xsl:attribute> </xsl:element> </td> </tr> </xsl:template> </xsl:stylesheet>
Esse foi um pouco maior que os demais, mas nao envolve nada descomunal. é apenas o trabalho de criar os elementos necessários do form, para enviar a mensagem. Mas, analisando um pouco mais profundamente, podemos ressaltar alguns pontos a comentar:
Nome e usuário são armazenados em variáveis session no script ASP, poupando o usuário de digitá-los em cada nova mensagem. O primeito trecho destacado em negrito aponta um recurso novo: a definição dos atributos de elementos <INPUT>, baseado no que estams fazendo. Caso a variável NewMessage esteja com o valor 0, estamos respondendo a uma mensagem, então os dados relacionados a ela são exibidos. Do contrário, é mostrado em branco, conforme já haviamos comentado anteriormente. No segundo trecho em negrito, enviamos o id da mensagem a ser respondida (para criarmos a thread) ou -1, indicando que é uma nova mensagem. Esse recurso também éé usado para indicarmos para o usuário o que ele está fazendo: postando uma nova mensagem ou respondendo a uma já postada.
Na próxima parte, utilizaremos os conceitos estabelecidos aqui, para construirmos o script ASP que será encarregado de construir o fórum e torná-lo operacional.
Fim Parte II
|
|
|
|

|