Linguagem de expressão do HTL

A Linguagem de modelo HTML usa uma linguagem de expressão para acessar as estruturas de dados que fornecem os elementos dinâmicos da saída HTML. Essas expressões são delimitadas por caracteres ${ e }. Para evitar HTML malformado, as expressões só podem ser usadas em valores de atributo, no conteúdo do elemento ou em comentários.

<!-- ${component.path} -->
<h1 class="${component.name}">
    ${properties.jcr:title}
</h1>

As expressões podem ser escapadas ao antecipar um caractere \, por exemplo, \${test} será renderizado ${test}.

OBSERVAÇÃO

Para experimentar os exemplos fornecidos nesta página, um ambiente de execução ao vivo chamado Read Eval Print Loop pode ser usado.

A sintaxe de expressão inclui variáveis, literais, operadores e opções:

Variáveis

Variáveis são container que armazenam valores de dados ou objetos. Os nomes das variáveis são chamados de identificadores.

Sem precisar especificar nada, o HTL fornece acesso a todos os objetos que normalmente estavam disponíveis no JSP após a inclusão de global.jsp. A página Objetos Globais fornece a lista de todos os objetos aos quais foi fornecido acesso pelo HTL.

Acesso à propriedade

Há duas maneiras de acessar as propriedades de variáveis, com uma notação de ponto ou com uma notação de colchete:

${currentPage.title}  
${currentPage['title']} or ${currentPage["title"]}

A notação de pontos mais simples deve ser preferida para a maioria dos casos, e a notação de colchetes deve ser usada para acessar propriedades que contêm caracteres de identificador inválidos ou para acessar propriedades dinamicamente. Os dois capítulos seguintes fornecerão pormenores sobre estes dois casos.

As propriedades acessadas podem ser funções, mas não há suporte para a transmissão de argumentos, portanto, somente as funções que não esperam argumentos podem ser acessadas, como getters. Essa é uma limitação desejada, que tem como objetivo reduzir a quantidade de lógica incorporada às expressões. Se necessário, a instrução data-sly-use pode ser usada para passar parâmetros para a lógica.

Também mostrado no exemplo acima é que as funções do Java getter, como getTitle(), podem ser acessadas sem antecipar o get e diminuindo as letras maiúsculas e minúsculas do caractere a seguir.

Caracteres de Identificador Válidos

Os nomes de variáveis, chamados de identificadores, estão em conformidade com determinadas regras. Eles devem start com uma letra (A-Z e a-z), ou um sublinhado (_), e os caracteres subsequentes também podem ser dígitos (0-9) ou dois pontos (:). Letras Unicode, como å e ü, não podem ser usadas em identificadores.

Dado que o caractere de dois pontos (:) é comum em nomes de propriedades AEM, é necessário enfatizar que ele é um caractere identificador válido:

${properties.jcr:title}

A notação entre colchetes pode ser usada para acessar propriedades que contêm caracteres de identificador inválidos, como o caractere de espaço no exemplo abaixo:

${properties['my property']}

Acessar membros dinamicamente

${properties[myVar]}

Tratamento Permissivo de Valores Nulos

${currentPage.lastModified.time.toString}

Literais

Um literal é uma notação para representar um valor fixo.

Booleano

Booliano representa uma entidade lógica e pode ter dois valores: true e false.

${true} ${false}

Números

Há apenas um tipo de número: números inteiros positivos. Enquanto outros formatos de números, como ponto flutuante, são suportados em variáveis, mas não podem ser expressos como literais.

${42}

Strings

As strings representam dados textuais e podem ser únicas ou duplos entre aspas:

${'foo'} ${"bar"}

Além dos caracteres comuns, os seguintes caracteres especiais podem ser usados:

  • \\ Caractere de barra invertida

  • \' Citação única (ou apóstrofe)

  • \" Duplo aspas

  • \t Guia

  • \n Nova linha

  • \r Retorno de carro

  • \f Feed de formulário

  • \b Backspace

  • \uXXXX O caractere Unicode especificado pelos quatro dígitos hexadecimais XXXX.
    Algumas sequências de escape unicode úteis são:

    • \u0022 para "
    • \u0027 para '

Para caracteres não listados acima, o anterior a um caractere de barra invertida exibirá um erro.

Estes são alguns exemplos de como usar o escape de sequência:

<p>${'it\'s great, she said "yes!"'}</p>
<p title="${'it\'s great, she said \u0022yes!\u0022'}">...</p>

que resultará na seguinte saída, pois HTL aplicará escape específico ao contexto:

<p>it&#39;s great, she said &#34;yes!&#34;</p>
<p title="it&#39;s great, she said &#34;yes!&#34;">...</p>

Matrizes

Uma matriz é um conjunto ordenado de valores que podem ser referenciados com um nome e um índice. Os tipos de seus elementos podem ser misturados.

${[1,2,3,4]}
${myArray[2]}

As matrizes são úteis para fornecer uma lista de valores do modelo.

<ul data-sly-list="${[1,2,3,4]}">
  <li>${item}</li>
</ul>

Operadores

Operadores lógicos

Normalmente, esses operadores são usados com valores booleanos, no entanto, como no JavaScript, eles retornam o valor de um dos operandos especificados, de modo que, quando usados com valores não booleanos, podem retornar um valor não booliano.

Se um valor puder ser convertido em true, o valor será chamado de verdadeiro. Se um valor puder ser convertido em false, o valor será chamado de falso. Os valores que podem ser convertidos em false são variáveis indefinidas, valores nulos, o número zero e sequências vazias.

NOT lógico

${!myVar} retorna false se seu único operando puder ser convertido em true; caso contrário, retorna true.

Por exemplo, isso pode ser usado para inverter uma condição de teste, como exibir um elemento somente se não houver páginas secundárias:

<p data-sly-test="${!currentPage.hasChild}">current page has no children</p>

AND lógica

${varOne && varTwo} retorna varOne se for falsa; caso contrário, retorna varTwo.

Esse operador pode ser usado para testar duas condições de uma só vez, como verificar a existência de duas propriedades:

<div data-sly-test="${properties.jcr:title && properties.jcr:description}">
    <h1>${properties.jcr:title}</h1>
    <p>${properties.jcr:description}</p>
</div>

O operador AND lógico também pode ser usado para exibir condicionalmente atributos HTML, pois HTL remove atributos com valores definidos dinamicamente que avaliam como falso ou como uma sequência vazia. Portanto, no exemplo abaixo, o atributo class só é mostrado se logic.showClass for verdadeiro e se logic.className existir e não estiver vazio:

<div class="${logic.showClass && logic.className}">...</div>

OR lógica

${varOne || varTwo} retorna varOne se for verdadeiro; caso contrário, retorna varTwo.

Esse operador pode ser usado para testar se uma das duas condições se aplicam, como verificar a existência de pelo menos uma propriedade:

<div data-sly-test="${properties.jcr:title || properties.jcr:description}">...</div>

Como o operador OR lógico retorna a primeira variável verdadeira, ela também pode ser usada para fornecer valores de fallback.

Também pode ser usado para exibir condicionalmente atributos HTML, pois HTL remove atributos com valores definidos por expressões que avaliam como falso ou como uma sequência vazia. Assim, o exemplo abaixo exibirá o título properties.jcr: se ele existir e não estiver vazio, caso contrário, ele voltará para a exibição de properties.jcr:description se ele existir e não estiver vazio, caso contrário, exibirá a mensagem "nenhum título ou descrição fornecido":

<p>${properties.jcr:title || properties.jcr:description || "no title or description provided"}</p>

Operador Condicional (ternário)

${varCondition ? varOne : varTwo} retorna varOne se varCondition for verdadeiro; caso contrário, retorna varTwo.

Normalmente, esse operador pode ser usado para definir condições no expressão, como exibir uma mensagem diferente com base no status da página:

<p>${currentPage.isLocked ? "page is locked" : "page can be edited"}</p>
DICA

Como os caracteres de dois pontos também são permitidos nos identificadores, é melhor separar os operadores ternários com um espaço em branco para fornecer clareza ao analisador:

<p>${properties.showDescription ? properties.jcr:description : properties.jcr:title}</p>

Operadores de comparação

Os operadores de igualdade e desigualdade suportam apenas operandos de tipos idênticos. Quando os tipos não correspondem, um erro é exibido.

  • As strings são iguais quando têm a mesma sequência de caracteres.
  • Os números são iguais quando têm o mesmo valor
  • Os booleanos são iguais se ambos forem true ou se ambos forem false.
  • As variáveis nulas ou indefinidas são iguais a si mesmas e entre si.

${varOne == varTwo} retorna true se varOne e varTwo são iguais.

${varOne != varTwo} retorna true se varOne e não varTwo são iguais.

Os operadores relacionais suportam apenas operandos que são números. Para todos os outros tipos, um erro é exibido.

${varOne > varTwo} retorna true se varOne for maior que varTwo.

${varOne < varTwo} retorna true se varOne for menor que varTwo.

${varOne >= varTwo} retorna true se varOne for maior ou igual a varTwo.

${varOne <= varTwo} retorna true se varOne for menor ou igual a varTwo.

Agrupamento de parênteses

O operador de agrupamento () controla a precedência da avaliação no expressão.

${varOne && (varTwo || varThree)}

Opções

As opções de expressão podem atuar na expressão e modificá-la, ou servir como parâmetros quando usadas em conjunto com instruções de bloqueio.

Tudo depois de @ é uma opção:

${myVar @ optOne}

As opções podem ter um valor, que pode ser uma variável ou um literal:

${myVar @ optOne=someVar}
${myVar @ optOne='bar'}
${myVar @ optOne=10}
${myVar @ optOne=true}

Várias opções são separadas por vírgulas:

${myVar @ optOne, optTwo=bar}

Expressões paramétricas contendo apenas opções também são possíveis:

${@ optOne, optTwo=bar}

Formatação de cadeia de caracteres

Opção que substitui os espaços reservados enumerados, {n}, pela variável correspondente:

${'Page {0} of {1}' @ format=[current, total]}

Manipulação de URL

Um novo conjunto de manipulações de url está disponível.

Consulte os seguintes exemplos de uso:

Adiciona a extensão html a um caminho.

<a href="${item.path @ extension = 'html'}">${item.name}</a>

Adiciona a extensão html e um seletor a um caminho.

<a href="${item.path @ extension = 'html', selectors='products'}">${item.name}</a>

Adiciona a extensão html e um fragmento (#value) a um caminho.

<a href="${item.path @ extension = 'html', fragment=item.name}">${item.name}</a>

O @extension funciona em todos os cenários, verificando se a extensão deve ser adicionada ou não.

${ link @ extension = 'html' }

Formatação de números/datas

HTL permite a formatação nativa de números e datas, sem gravar código personalizado. Isso também suporta fuso horário e localidade.

Os exemplos a seguir mostram que o formato é especificado primeiro e o valor que precisa de formatação:

<h2>${ 'dd-MMMM-yyyy hh:mm:ss' @
           format=currentPage.lastModified,
           timezone='PST',
           locale='fr'}</h2>

<h2>${ '#.00' @ format=300}</h2>
OBSERVAÇÃO

Para obter detalhes completos sobre o formato que você pode usar, consulte especificação HTL.

Internacionalização

Traduz a string para o idioma do source atual (veja abaixo), usando o dicionário atual. Se nenhuma tradução for encontrada, a string original será usada.

${'Page' @ i18n}

A opção de dica pode ser usada para fornecer um comentário aos tradutores, especificando o contexto em que o texto é usado:

${'Page' @ i18n, hint='Translation Hint'}

A origem padrão do idioma é resource, o que significa que o texto é traduzido para o mesmo idioma do conteúdo. Isso pode ser alterado para user, o que significa que o idioma é retirado da localidade do navegador ou da localidade do usuário conectado:

${'Page' @ i18n, source='user'}

Fornecer uma localidade explícita substitui as configurações de origem:

${'Page' @ i18n, locale='en-US'}

Para incorporar variáveis em uma string traduzida, a opção de formato pode ser usada:

${'Page {0} of {1}' @ i18n, format=[current, total]}

Array Join

Por padrão, ao exibir uma matriz como texto, HTL exibirá valores separados por vírgula (sem espaçamento).

Use a opção de junção para especificar um separador diferente:

${['one', 'two'] @ join='; '}

Exibir contexto

O contexto de exibição de uma expressão HTL refere-se à sua localização na estrutura da página HTML. Por exemplo, se a expressão for exibida no lugar que produziria um nó de texto depois de renderizada, então será considerado como estando em um contexto text. Se for encontrado dentro do valor de um atributo, então será considerado um contexto attribute e assim por diante.

Com exceção dos contextos de script (JS) e de estilo (CSS), o HTL detectará automaticamente o contexto das expressões e as ignorará apropriadamente para evitar problemas de segurança do XSS. No caso de scripts e CSS, o comportamento de contexto desejado deve ser definido explicitamente. Além disso, o comportamento de contexto também pode ser explicitamente definido em qualquer outro caso em que uma substituição do comportamento automático seja desejada.

Aqui temos três variáveis em três contextos diferentes:

  • properties.link ( uri contexto)
  • properties.title (attribute contexto)
  • properties.text (text contexto)

Os HTL poderão escapar a cada uma destas situações de forma diferente, de acordo com os requisitos de segurança dos respectivos contextos. Nenhuma configuração de contexto explícita é necessária em casos normais, como este:

<a href="${properties.link}" title="${properties.title}">${properties.text}</a>

Para exibir com segurança a marcação (isto é, onde a expressão em si avalia para HTML), o contexto html é usado:

<div>${properties.richText @ context='html'}</div>

O contexto explícito deve ser definido para contextos de estilo:

<span style="color: ${properties.color @ context='styleToken'};">...</span>

O contexto explícito deve ser definido para contextos de script:

<span onclick="${properties.function @ context='scriptToken'}();">...</span>

A proteção de Escaping e XSS também pode ser desativada:

<div>${myScript @ context='unsafe'}</div>

Configurações de contexto

Contexto Quando usar O que ele faz
text Padrão para conteúdo dentro de elementos Codifica todos os caracteres especiais HTML.
html Marcação de saída com segurança Filtros HTML para atender às regras de política do AntiSamy, removendo o que não corresponde às regras.
attribute Padrão para valores de atributo Codifica todos os caracteres especiais HTML.
uri Para exibir links e caminhos Padrão para valores de atributos href e src Valida o URI para gravar como um valor de atributo href ou src, não resulta em nada se a validação falhar.
number Para exibir números Valida o URI para conter um número inteiro, resulta em zero se a validação falhar.
attributeName Padrão para atributo de estilo de dados ao definir nomes de atributo Valida o nome do atributo e não gera nada se a validação falhar.
elementName Padrão para o elemento de estilo de dados Valida o nome do elemento e não gera nada se a validação falhar.
scriptToken Para identificadores JS, números literais ou strings literais Valida o token JavaScript e não gera nada se a validação falhar.
scriptString Em strings JS Codifica caracteres que se dividiriam na string.
scriptComment Em comentários JS Valida o comentário do JavaScript, não resulta em nada se a validação falhar.
styleToken Para identificadores CSS, números, dimensões, strings, cores hexadecimais ou funções. Valida o token CSS e não gera nada se a validação falhar.
styleString Em strings CSS Codifica caracteres que se dividiriam na string.
styleComment Em comentários CSS Valida o comentário CSS, não resulta em nada se a validação falhar.
unsafe Somente se nenhuma das opções anteriores fizer o serviço Desativa a remoção e a proteção XSS completamente.

Nesta página