Apache Tapestry - Modelli

Consideriamo il modello XML di Tapestry in questa sezione. XML Template è un documento XML ben formato. Il livello di presentazione (interfaccia utente) di una pagina è un modello XML. Un modello XML ha un normale markup HTML in aggiunta agli elementi indicati di seguito:

  • Spazio dei nomi di Tapestry
  • Expansions
  • Elements
  • Components

Vediamoli ora in dettaglio.

Spazio dei nomi di Tapestry

Gli spazi dei nomi Tapestry non sono altro che spazi dei nomi XML. Gli spazi dei nomi devono essere definiti nell'elemento radice del modello. Viene utilizzato per includere i componenti Tapestry e le informazioni relative ai componenti nel modello. Gli spazi dei nomi più comunemente usati sono i seguenti:

  • xmlns: t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” - Viene utilizzato per identificare gli elementi, i componenti e gli attributi di Tapestry.

  • xmlns: p = "tapestry: parameter" - Viene utilizzato per passare blocchi arbitrari di codice ai componenti.

Un esempio di Tapestry Namespace è il seguente:

<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>

Espansioni

L'espansione è un metodo semplice ed efficiente per modificare dinamicamente il modello XML durante la fase di rendering della pagina. L'espansione utilizza la sintassi $ {<name>}. Ci sono molte opzioni per esprimere l'espansione nel modello XML. Vediamo alcune delle opzioni più comunemente utilizzate:

Espansioni di proprietà

Mappa la proprietà definita nella classe Page corrispondente. Segue la specifica Java Bean per la definizione della proprietà in una classe Java. Fa un ulteriore passo avanti ignorando i casi per il nome della proprietà. Cambiamo l'esempio "Hello World" utilizzando l'espansione della proprietà. Il seguente blocco di codice è la classe Page modificata.

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

Quindi, modifica il modello XML corrispondente come mostrato di seguito.

<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>

Qui abbiamo definito name come Java Bean Property nella classe Page e elaborato dinamicamente nel modello XML utilizzando l'espansione ${name}.

Espansione dei messaggi

Ogni classe Page può o non può avere un file di proprietà associato - «page_name».propertiesnella cartella delle risorse. I file delle proprietà sono file di testo semplice con un'unica coppia chiave / valore (messaggio) per riga. Creiamo un file di proprietà per HelloWorld Page su -

"/Src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties" e aggiungi un messaggio "Saluto".

Greeting = Hello

Il Greeting il messaggio può essere utilizzato nel modello XML come ${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>

Elementi

Tapestry ha un piccolo insieme di elementi da utilizzare nei modelli XML. Gli elementi sono tag predefiniti definiti nello spazio dei nomi Tapestry -

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

Ogni elemento è creato per uno scopo specifico. Gli elementi dell'arazzo disponibili sono i seguenti:

<t: body>

Quando due componenti sono nidificati, il modello del componente padre potrebbe dover avvolgere il modello del componente figlio. L'elemento <t: body> è utile in questa situazione. Uno degli usi di <t: body> è nel layout del modello.

In generale, l'interfaccia utente di un'applicazione web avrà un'intestazione, un piè di pagina, un menu e così via comuni. Questi elementi comuni sono definiti in un modello XML e viene chiamato layout modello o componente layout. In Tapestry, deve essere creato da uno sviluppatore di applicazioni. Un componente di layout è solo un altro componente e viene posizionato nella cartella dei componenti, che ha il seguente percorso:src/main/«java|resources»/«package_name»/components.

Creiamo un semplice componente di layout chiamato MyCustomLayout. Il codice per MyCustomLayout è il seguente:

<!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; 
}

Nella classe del componente MyCustomLayout, abbiamo dichiarato un campo del titolo e, utilizzando l'annotazione, lo abbiamo reso obbligatorio. Ora, cambia il modello HelloWorld.html per utilizzare il nostro layout personalizzato come mostrato nel blocco di codice di seguito.

<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>

Possiamo vedere qui che il modello XML non ha tag head e body. Tapestry raccoglierà questi dettagli dal componente di layout e il <t: body> del componente di layout verrà sostituito dal modello HelloWorld. Una volta che tutto è stato fatto, Tapestry emetterà un markup simile come specificato di seguito -

<!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>

I layout possono essere annidati. Ad esempio, possiamo estendere il nostro layout personalizzato includendo funzionalità di amministrazione e utilizzarlo per la sezione di amministrazione come specificato di seguito.

<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>

<T: container> è un elemento di primo livello e include uno spazio dei nomi arazzo. Viene utilizzato per specificare la sezione dinamica di un componente.

Ad esempio, un componente della griglia potrebbe aver bisogno di un modello per identificare come visualizzare le sue righe - tr (e colonna td) all'interno di una tabella HTML.

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

<t: block>

Il <t: block> è un segnaposto per una sezione dinamica nel modello. Generalmente, l'elemento di blocco non esegue il rendering. Solo, i componenti definiti nel modello utilizzano l'elemento blocco. I componenti inseriranno i dati dinamicamente nell'elemento block e lo renderanno. Uno dei casi d'uso più diffusi èAJAX.

L'elemento block fornisce la posizione e il markup esatti per il rendering dei dati dinamici. Ogni elemento del blocco dovrebbe avere una proprietà Java corrispondente. Solo allora può essere renderizzato dinamicamente. L'id dell'elemento block dovrebbe seguire le regole dell'identificatore di variabile Java. Di seguito viene fornito il campione parziale.

@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: content>

L'elemento <t: content> viene utilizzato per specificare il contenuto effettivo del modello. In generale, tutto il markup è considerato parte del modello. Se viene specificato <t: content>, verrà considerato solo il markup al suo interno. Questa funzione viene utilizzata dai designer per progettare una pagina senza un componente di layout.

<t: remove>

Il <t: remove> è esattamente l'opposto dell'elemento di contenuto. Il markup all'interno dell'elemento remove non è considerato parte del modello. Può essere utilizzato solo per i commenti del server e per scopi di progettazione.

Risorse

Le risorse sono file di risorse statiche come fogli di stile, immagini e file JavaScript. In genere, le risorse vengono collocate nella directory principale dell'applicazione Web/src/main/webapp.

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

Tapestry tratta anche i file archiviati nel file Java Classpathcome beni. Tapestry fornisce opzioni avanzate per includere Risorse nel modello tramite l'opzione di espansione.

  • Context - Opzione per ottenere risorse disponibili nel contesto web.

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

asset- I componenti di solito memorizzano le proprie risorse all'interno del file jar insieme alle classi Java. A partire da Tapestry 5.4, il percorso standard per archiviare le risorse in classpath èMETA-INF/assets. Per le biblioteche, il percorso standard per archiviare le risorse èMETA-INF/assets/«library_name»/. asset: può anche chiamare context: espansione per ottenere risorse dal contesto web.

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

Gli asset possono essere inseriti nella pagina o nel componente Tapestry utilizzando Inject e Path annotation. Il parametro per l'annotazione Path è il percorso relativo degli asset.

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

Il Path parameter può anche contenere simboli Tapestry definiti nel file AppModule.java sezione.

Ad esempio, possiamo definire un simbolo, skin.root con value context: skins / basic e usarlo come mostrato di seguito -

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

Localizzazione

Includere risorse tramite arazzo fornisce funzionalità extra. Una di queste funzionalità è "Localizzazione". Tapestry controllerà la lingua corrente e includerà le risorse appropriate.

Ad esempio, se la locale corrente è impostata come de, poi edit_de.png sarà incluso al posto di edit.png.

CSS

Tapestry ha il supporto per fogli di stile integrato. Tapestry inietteràtapestry.csscome parte dello stack JavaScript principale. Da Tapestry 5.4, l'arazzo includebootstrap css frameworkanche. Possiamo includere il nostro foglio di stile usando il normale tag di collegamento. In questo caso, i fogli di stile dovrebbero essere nella directory principale del web -/src/main/webapp/.

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

Tapestry fornisce opzioni avanzate per includere fogli di stile nel modello tramite l'opzione di espansione come discusso in precedenza.

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

Tapestry fornisce anche l'annotazione di importazione per includere il foglio di stile direttamente nelle classi Java.

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

Tapestry fornisce molte opzioni per gestire il foglio di stile tramite AppModule.java. Alcune delle opzioni importanti sono:

  • Il foglio di stile predefinito dell'arazzo può essere rimosso.

@Contribute(MarkupRenderer.class) 

public static void 
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) { 
   configuration.override("InjectDefaultStyleheet", null); 
}
  • Bootstrap può anche essere disabilitato sovrascrivendo il suo percorso.

configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
  • Abilita la riduzione dinamica delle risorse (CSS e JavaScript). Dobbiamo includeretapestry-webresources anche dependency (in pom.xml).

@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 lato client

L'attuale generazione di applicazioni web dipende fortemente da JavaScript per fornire una ricca esperienza lato client. Tapestry lo riconosce e fornisce un supporto di prima classe per JavaScript. Il supporto JavaScript è profondamente radicato nell'arazzo e disponibile in ogni fase della programmazione.

In precedenza, Tapestry supportava solo Prototype e Scriptaculous. Ma, dalla versione 5.4, tapestry ha riscritto completamente il livello JavaScript per renderlo il più generico possibile e fornire un supporto di prima classe per JQuery, la libreria di fatto per JavaScript. Inoltre, tapestry incoraggia la programmazione JavaScript basata su moduli e supporta RequireJS, una popolare implementazione lato client di AMD (Asynchronous Module Definition - specifica JavaScript per supportare i moduli e la sua dipendenza in modo asincrono).

Posizione

I file JavaScript sono risorse dell'applicazione Tapestry. In conformità con le regole delle risorse, i file JavaScript vengono inseriti nel contesto web,/sr/main/webapp/ o posto all'interno del barattolo sotto META-INF/assets/ location.

Collegamento di file JavaScript

Il modo più semplice per collegare i file JavaScript nel modello XML è utilizzare direttamente il tag script, che è: <script language = "javascript" src = "relative/path/to/js"></script>. Ma l'arazzo non consiglia questi approcci. Tapestry fornisce diverse opzioni per collegare i file JavaScript direttamente nella Pagina / Componente stesso. Alcuni di questi sono riportati di seguito.

  • @import annotation- L'annotazione @import fornisce l'opzione per collegare più librerie JavaScript utilizzando l'espressione di contesto. Può essere applicato sia alla classe Page che al suo metodo. Se applicato a una classe Page, si applica a tutti i suoi metodi. Se applicato al metodo di una pagina, si applica solo a quel metodo e quindi Tapestry collega la libreria JavaScript solo quando il metodo viene invocato.

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

public class MyComponent { 
   // ... 
}
  • JavaScriptSupport interface - JavaScriptSupport è un'interfaccia definita da arazzo e ha un metodo, importJavaScriptLibraryper importare file JavaScript. L'oggetto JavScriptSupport può essere facilmente creato semplicemente dichiarando e annotando con l'annotazione @Environmental.

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

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
   javaScriptSupport.importJavaScriptLibrary(myEffects); 
}
  • JavaScripSupport può essere iniettato solo in un componente utilizzando l'estensione @Environmentalannotazione. Per i servizi, dobbiamo utilizzare un file@Inject annotazione o aggiungerlo come argomento nel metodo del costruttore del servizio.

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
   // ... 
}
  • addScript method - È simile all'interfaccia JavaScriptSupport tranne per il fatto che utilizza l'estensione addScript metodo e il codice viene aggiunto direttamente all'output in fondo alla pagina.

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

Stack JavaScript

Tapestry consente di combinare e utilizzare un gruppo di file JavaScript e relativi fogli di stile come un'unica entità. Attualmente, Tapestry include stack basati su prototipi e basati su JQuery.

Uno sviluppatore può sviluppare i propri stack implementando il JavaScriptStack e registralo nel file AppModule.java. Una volta registrato, lo stack può essere importato utilizzando il file@import annotazione.

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

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