Tapeçaria Apache - Modelos

Vamos considerar o modelo XML Tapestry nesta seção. O modelo XML é um documento XML bem formado. A camada de apresentação (interface do usuário) de uma página é um modelo XML. Um modelo XML tem marcação HTML normal, além dos itens fornecidos abaixo -

  • Espaço para nome de tapeçaria
  • Expansions
  • Elements
  • Components

Vamos agora discuti-los em detalhes.

Espaço para nome de tapeçaria

Os namespaces de tapeçaria nada mais são do que namespaces XML. Os namespaces devem ser definidos no elemento raiz do modelo. É usado para incluir componentes de tapeçaria e informações relacionadas a componentes no modelo. Os namespaces mais comumente usados ​​são os seguintes -

  • xmlns: t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” - É usado para identificar os Elementos, Componentes e Atributos da Tapeçaria.

  • xmlns: p = “tapeçaria: parâmetro” - É usado para passar pedaços arbitrários de código para componentes.

Um exemplo de espaço para nome Tapestry é o seguinte -

<html xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_3.xsd" 
   xmlns:p = "tapestry:parameter"> 
   
   <head> 
      <title>Hello World Page</title> 
   </head>  
   <body> 
      <h1>Hello World</h1> 
      <t:eventlink page = "Index">refresh page</t:eventlink> 
   </body> 
</html>

Expansões

Expansão é um método simples e eficiente para alterar dinamicamente o Modelo XML durante a fase de renderização da Página. A expansão usa a sintaxe $ {<name>}. Existem muitas opções para expressar a expansão no modelo XML. Vejamos algumas das opções mais comumente usadas -

Expansões de propriedade

Ele mapeia a propriedade definida na classe de página correspondente. Ele segue a Especificação Java Bean para definição de propriedade em uma classe Java. Ele vai um passo adiante, ignorando os casos de nome de propriedade. Vamos mudar o exemplo “Hello World” usando expansão de propriedade. O seguinte bloco de código é a classe Page modificada.

package com.example.MyFirstApplication.pages; 
public class HelloWorld {   
   // Java Bean Property 
   public String getName { 
      return "World!"; 
   } 
}

Em seguida, altere o modelo XML correspondente conforme mostrado abaixo.

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <title>Hello World Page</title> 
   </head> 
   <body> 
      <!-- expansion --> 
      <h1>Hello ${name}</h1> 
   </body> 
</html>

Aqui, nós definimos name Como Java Bean Property na classe Page e processou-o dinamicamente no modelo XML usando expansão ${name}.

Expansão da Mensagem

Cada classe de página pode ou não ter um arquivo de propriedade associado - «page_name».propertiesna pasta de recursos. Os arquivos de propriedades são arquivos de texto simples com um único par de chave / valor (mensagem) por linha. Vamos criar um arquivo de propriedades para a página HelloWorld em -

“/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” e adicione uma mensagem de “Saudação”.

Greeting = Hello

o Greeting mensagem pode ser usada no modelo XML como ${message:greeting}

<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <title>Hello World Page</title> 
   </head> 
   <body> 
      <!-- expansion --> 
      <h1>${message:greeting} ${name}</h1> 
   </body> 
</html>

Elements

Tapestry possui um pequeno conjunto de elementos para serem usados ​​em Templates XML. Elementos são tags predefinidas definidas no namespace Tapestry -

https://tapestry.apache.org/schema/tapestry_5_4.xsd

Cada elemento é criado para um propósito específico. Os elementos de tapeçaria disponíveis são os seguintes -

<t: body>

Quando dois componentes estão aninhados, o modelo do componente pai pode ter que envolver o modelo do componente filho. O elemento <t: body> é útil nessa situação. Um dos usos de <t: body> é no Layout de modelo.

Em geral, a interface do usuário de uma aplicação web terá um cabeçalho, rodapé, menu comum, etc. Esses itens comuns são definidos em um modelo XML e são chamados de Layout de modelo ou Componente de layout. No Tapestry, ele precisa ser criado por um desenvolvedor de aplicativos. Um componente de layout é apenas outro componente e é colocado na pasta de componentes, que possui o seguinte caminho -src/main/«java|resources»/«package_name»/components.

Vamos criar um componente de layout simples chamado MyCustomLayout. O código para MyCustomLayout é o seguinte -

<!DOCTYPE html> 
<html xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <head> 
      <meta charset = "UTF-8" />
      <title>${title}</title>  
   </head> 
   <body> 
      <div>Sample Web Application</div> 
      <h1>${title}</h1> 
      <t:body/> 
      
      <div>(C) 2016 TutorialsPoint.</div> 
   </body> 
</html>
package com.example.MyFirstApplication.components;  

import org.apache.tapestry5.*; 
import org.apache.tapestry5.annotations.*; 
import org.apache.tapestry5.BindingConstants;  

public class MyCustomLayout { 
   @Property 
   @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL) 
      private String title; 
}

Na classe do componente MyCustomLayout, declaramos um campo de título e, usando a anotação, o tornamos obrigatório. Agora, altere o modelo HelloWorld.html para usar nosso layout personalizado, conforme mostrado no bloco de código abaixo.

<html>
   t:type = "mycustomlayout" title = "Hello World Test page"
      xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <h1>${message:greeting} ${name}</h1> 
</html>

Podemos ver aqui que o Template XML não possui tags head e body. Tapestry coletará esses detalhes do componente de layout e o <t: body> do componente de layout será substituído pelo modelo HelloWorld. Depois que tudo estiver feito, Tapestry emitirá marcação semelhante conforme especificado abaixo -

<!DOCTYPE html> 
<html> 
   <head> 
      <meta charset = "UTF-8" /> 
      <title>Hello World Test Page</title> 
   </head> 
   <body> 
      <div>Sample Web Application</div> 
      <h1>Hello World Test Page</h1> 
      <h1>Hello World!</h1> 
      <div>(C) 2016 TutorialsPoint.</div> 
   </body> 
</html>

Os layouts podem ser aninhados. Por exemplo, podemos estender nosso layout personalizado incluindo a funcionalidade de administração e usá-la para a seção administrativa conforme especificado abaixo.

<html t:type = "MyCommonLayout" 
   xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   
   <div><!-- Admin related items --><div> 
   <t:body/> 
  
</html>

<t: container>

O <t: container> é um elemento de nível superior e inclui um namespace de tapeçaria. Isso é usado para especificar a seção dinâmica de um componente.

Por exemplo, um componente de grade pode precisar de um modelo para identificar como renderizar suas linhas - tr (e coluna td) em uma tabela HTML.

<t:container xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"> 
   <td>${name}</td> 
   <td>${age}</td> 
</t:container>

<t: block>

O <t: block> é um espaço reservado para uma seção dinâmica no modelo. Geralmente, o elemento de bloco não é renderizado. Apenas os componentes definidos no modelo usam elemento de bloco. Os componentes injetarão dados dinamicamente no elemento de bloco e os renderizarão. Um dos casos de uso populares éAJAX.

O elemento de bloco fornece a posição exata e marcação para os dados dinâmicos a serem renderizados. Cada elemento de bloco deve ter uma propriedade Java correspondente. Só então ele pode ser renderizado dinamicamente. O id do elemento de bloco deve seguir as regras de identificador de variável Java. A amostra parcial é fornecida abaixo.

@Inject 
private Block block;  
<html t:type = "mycustomlayout" title = "block example" 
   xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd" 
   xmlns:p = "tapestry:parameter">  
<h1>${title}</h1>  
<!--  
   ... 
   ...  
--> 
<t:block t:id = "block"> 
   <h2>Highly dynamic section</h2> 
   I'v been updated through AJAX call 
   The current time is: <strong>${currentTime}</strong>
</t:block>  
<!--  
   ... 
   ...  
-->  
</html>

<t: conteúdo>

O elemento <t: content> é usado para especificar o conteúdo real do modelo. Em geral, toda a marcação é considerada parte do modelo. Se <t: content> for especificado, apenas a marcação dentro dele será considerada. Este recurso é usado por designers para criar uma página sem um componente de layout.

<t: remove>

O <t: remove> é exatamente o oposto do elemento de conteúdo. A marcação dentro do elemento remove não é considerada parte do template. Ele pode ser usado apenas para comentários do servidor e para fins de design.

Ativos

Ativos são arquivos de recursos estáticos, como folhas de estilo, imagens e arquivos JavaScript. Geralmente, os ativos são colocados no diretório raiz do aplicativo da web/src/main/webapp.

<head> 
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

Tapestry também trata os arquivos armazenados no Java Classpathcomo ativos. Tapestry fornece opções avançadas para incluir ativos no modelo por meio da opção de expansão.

  • Context - Opção para obter ativos disponíveis no contexto web.

<img src = "${context:image/tapestry_banner.gif}" alt = "Banner"/>

asset- Os componentes geralmente armazenam seus próprios ativos dentro do arquivo jar junto com as classes Java. A partir do Tapestry 5.4, o caminho padrão para armazenar ativos no caminho de classe éMETA-INF/assets. Para bibliotecas, o caminho padrão para armazenar ativos éMETA-INF/assets/«library_name»/. asset: também pode ligar context: expansão para obter ativos do contexto da web.

<img src = "${asset:context:image/tapestry_banner.gif}" alt = "Banner"/>

Os ativos podem ser injetados na página ou componente da tapeçaria usando a anotação Injetar e Caminho. O parâmetro para a anotação de caminho é o caminho relativo dos ativos.

@Inject 
@Path("images/edit.png") 
private Asset icon;

o Path parameter também pode conter símbolos de tapeçaria definidos no AppModule.java seção.

Por exemplo, podemos definir um símbolo, skin.root com o contexto de valor: skins / basic e usá-lo como mostrado abaixo -

@Inject 
@Path("${skin.root}/style.css") 
private Asset style;

Localização

Incluir recursos por meio de tapeçaria fornece funcionalidade extra. Uma dessas funcionalidades é “Localização”. A tapeçaria verificará o local atual e incluirá os recursos adequados.

Por exemplo, se o local atual é definido como de, então edit_de.png será incluído em vez de edit.png.

CSS

A tapeçaria possui suporte integrado para folhas de estilo. A tapeçaria vai injetartapestry.csscomo parte da pilha Javascript principal. Do Tapestry 5.4, tapeçaria incluibootstrap css frameworktambém. Podemos incluir nossa própria folha de estilo usando a tag de link normal. Neste caso, as folhas de estilo devem estar no diretório raiz da web -/src/main/webapp/.

<head> 
   <link href = "/css/site.css" rel = "stylesheet" type = "text/css"/>

A tapeçaria oferece opções avançadas para incluir folhas de estilo no modelo por meio da opção de expansão, conforme discutido anteriormente.

<head> 
   <link href = "${context:css/site.css}" rel = "stylesheet" type = "text/css"/>

Tapestry também fornece anotação de importação para incluir folha de estilo diretamente nas classes Java.

@Import(stylesheet="context:css/site.css") 
public class MyCommonLayout { 
}

Tapestry oferece muitas opções para gerenciar a folha de estilo por meio de AppModule.java. Algumas das opções importantes são -

  • A folha de estilo padrão da tapeçaria pode ser removida.

@Contribute(MarkupRenderer.class) 

public static void 
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) { 
   configuration.override("InjectDefaultStyleheet", null); 
}
  • O bootstrap também pode ser desabilitado substituindo seu caminho.

configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
  • Habilite a minimização dinâmica dos ativos (CSS e JavaScript). Precisamos incluirtapestry-webresources dependência (em pom.xml) também.

@Contribute(SymbolProvider.class) 
@ApplicationDefaults 

public static void contributeApplicationDefaults( 
   MappedConfiguration<String, String> configuration) { 
   
   configuration.add(SymbolConstants.MINIFICATION_ENABLED, "true"); 
} 

<dependency> 
   <groupId>org.apache.tapestry</groupId> 
   <artifactId>tapestry-webresources</artifactId> 
   <version>5.4</version> 
</dependency>

JavaScript do lado do cliente

A geração atual de aplicativos da web depende muito do JavaScript para fornecer uma rica experiência do lado do cliente. Tapestry reconhece isso e fornece suporte de primeira classe para JavaScript. O suporte a JavaScript está profundamente enraizado na tapeçaria e disponível em todas as fases da programação.

Anteriormente, Tapestry suportava apenas Prototype e Scriptaculous. Mas, a partir da versão 5.4, a tapeçaria reescreveu completamente a camada JavaScript para torná-la o mais genérica possível e fornecer suporte de primeira classe para JQuery, a biblioteca de fato para JavaScript. Além disso, a tapeçaria incentiva a programação JavaScript baseada em módulos e oferece suporte a RequireJS, uma implementação popular do lado do cliente de AMD (Asynchronous Module Definition - especificação JavaScript para suportar módulos e sua dependência de maneira assíncrona).

Localização

Os arquivos JavaScript são ativos do aplicativo Tapestry. De acordo com as regras de ativos, os arquivos JavaScript são colocados no contexto da web,/sr/main/webapp/ ou colocado dentro da jarra sob META-INF/assets/ location.

Vinculando arquivos JavaScript

A maneira mais simples de vincular arquivos JavaScript no modelo XML é usando diretamente a tag de script, que é - <script language = "javascript" src = "relative/path/to/js"></script>. Porém, a tapeçaria não recomenda essas abordagens. Tapestry oferece várias opções para vincular arquivos JavaScript diretamente na própria página / componente. Alguns deles são fornecidos abaixo.

  • @import annotation- A anotação @import fornece a opção de vincular várias bibliotecas JavaScript usando a expressão de contexto. Pode ser aplicado tanto à classe Page quanto ao seu método. Se aplicado a uma classe Page, ele se aplica a todos os seus métodos. Se aplicado a um método de página, ele se aplica apenas a esse método e, em seguida, Tapestry vincula a biblioteca JavaScript apenas quando o método é invocado.

@Import(library = {"context:js/jquery.js","context:js/myeffects.js"}) 

public class MyComponent { 
   // ... 
}
  • JavaScriptSupport interface - O JavaScriptSupport é uma interface definida por tapestry e possui um método, importJavaScriptLibrarypara importar arquivos JavaScript. O objeto JavScriptSupport pode ser facilmente criado simplesmente declarando e anotando com a anotação @Environmental.

@Inject @Path("context:/js/myeffects.js") 
private Asset myEffects;  

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
   javaScriptSupport.importJavaScriptLibrary(myEffects); 
}
  • JavaScripSupport só pode ser injetado em um componente usando o @Environmentalanotação. Para serviços, precisamos usar um@Inject anotação ou adicione-a como um argumento no método do construtor de serviço.

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
   // ... 
}
  • addScript method - É semelhante à interface JavaScriptSupport, exceto que usa o addScript método e o código é adicionado diretamente à saída na parte inferior da página.

void afterRender() { 
   javaScriptSupport.addScript(
      "$('%s').observe('click', hideMe());", container.getClientId()); 
}

Pilha de JavaScript

Tapestry permite que um grupo de arquivos JavaScript e folhas de estilo relacionadas sejam combinados e usados ​​como uma única entidade. Atualmente, Tapestry inclui pilhas baseadas em protótipo e baseadas em JQuery.

Um desenvolvedor pode desenvolver suas próprias pilhas, implementando o JavaScriptStack interface e registrá-lo no AppModule.java. Uma vez registrada, a pilha pode ser importada usando o@import anotação.

@Contribute(JavaScriptStackSource.class) 
public static void addMyStack(
   MappedConfiguration<String, JavaScriptStack> configuration) { 
   
   configuration.addInstance("MyStack", myStack.class); 
}  

@Import(stack = "MyStack") 
public class myPage { 
}