Apache Tapestry - เทมเพลต

ให้เราพิจารณาเทมเพลต XML ของ Tapestry ในส่วนนี้ XML Template คือเอกสาร XML ที่มีรูปแบบสมบูรณ์ เลเยอร์การนำเสนอ (ส่วนติดต่อผู้ใช้) ของเพจคือเทมเพลต XML เทมเพลต XML มีมาร์กอัป HTML ปกตินอกเหนือจากรายการที่ระบุด้านล่าง -

  • เนมสเปซ Tapestry
  • Expansions
  • Elements
  • Components

ตอนนี้ให้เราพูดคุยในรายละเอียด

เนมสเปซ Tapestry

Tapestry Namespaces ไม่ใช่อะไรนอกจากเนมสเปซ XML ควรกำหนดเนมสเปซในองค์ประกอบรากของเทมเพลต ใช้เพื่อรวมส่วนประกอบของ Tapestry และข้อมูลที่เกี่ยวข้องกับส่วนประกอบในเทมเพลต เนมสเปซที่ใช้บ่อยที่สุดมีดังนี้ -

  • xmlns: t =“ https://tapestry.apache.org/schema/tapestry_5_4.xsd” - ใช้เพื่อระบุองค์ประกอบส่วนประกอบและคุณสมบัติของ Tapestry

  • xmlns: p =“ tapestry: parameter” - ใช้เพื่อส่งโค้ดไปยังส่วนประกอบต่างๆโดยพลการ

ตัวอย่างของ Tapestry Namespace มีดังต่อไปนี้ -

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

การขยาย

การขยายเป็นวิธีการที่ง่ายและมีประสิทธิภาพในการเปลี่ยนเทมเพลต XML แบบไดนามิกระหว่างขั้นตอนการแสดงผลของเพจ การขยายใช้ไวยากรณ์ $ {<name>} มีตัวเลือกมากมายในการแสดงการขยายในเทมเพลต XML ให้เราดูตัวเลือกที่ใช้บ่อยที่สุด -

การขยายทรัพย์สิน

แมปคุณสมบัติที่กำหนดไว้ในคลาสเพจที่เกี่ยวข้อง เป็นไปตามข้อกำหนด Java Bean สำหรับนิยามคุณสมบัติในคลาส Java ก้าวไปอีกขั้นโดยละเว้นกรณีสำหรับชื่อคุณสมบัติ ให้เราเปลี่ยนตัวอย่าง“ Hello World” โดยใช้การขยายคุณสมบัติ บล็อกโค้ดต่อไปนี้คือคลาสเพจที่แก้ไข

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

จากนั้นเปลี่ยนเทมเพลต XML ที่เกี่ยวข้องดังที่แสดงด้านล่าง

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

ที่นี่เราได้กำหนด name เช่น Java Bean Property ในคลาสเพจและประมวลผลแบบไดนามิกในเทมเพลต XML โดยใช้ส่วนขยาย ${name}.

การขยายข้อความ

แต่ละคลาสของเพจอาจมีหรือไม่มีไฟล์คุณสมบัติที่เกี่ยวข้อง - «page_name».propertiesในโฟลเดอร์ทรัพยากร ไฟล์คุณสมบัติเป็นไฟล์ข้อความธรรมดาที่มีคู่คีย์ / ค่าเดียว (ข้อความ) ต่อบรรทัด ให้เราสร้างไฟล์คุณสมบัติสำหรับ HelloWorld Page ที่ -

“ /src/main/resources/com/example/MyFirstApplication/pages/helloworld.properties” และเพิ่มข้อความ“ Greeting”

Greeting = Hello

Greeting สามารถใช้ข้อความในเทมเพลต XML เป็น ${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>

องค์ประกอบ

Tapestry มีองค์ประกอบชุดเล็ก ๆ ที่จะใช้ในเทมเพลต XML องค์ประกอบคือแท็กที่กำหนดไว้ล่วงหน้าซึ่งกำหนดไว้ภายใต้เนมสเปซ Tapestry -

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

แต่ละองค์ประกอบถูกสร้างขึ้นเพื่อวัตถุประสงค์เฉพาะ องค์ประกอบพรมที่มีอยู่มีดังนี้ -

<t: body>

เมื่อคอมโพเนนต์สองคอมโพเนนต์ซ้อนกันแม่แบบของคอมโพเนนต์หลักอาจต้องห่อเทมเพลตขององค์ประกอบลูก องค์ประกอบ <t: body> มีประโยชน์ในสถานการณ์นี้ หนึ่งในการใช้ <t: body> อยู่ในเค้าโครงเทมเพลต

โดยทั่วไปส่วนติดต่อผู้ใช้ของเว็บแอปพลิเคชันจะมี Common Header, Footer, Menu เป็นต้นรายการทั่วไปเหล่านี้ถูกกำหนดไว้ในเทมเพลต XML และเรียกว่า Template Layout หรือ Layout Component ใน Tapestry จำเป็นต้องสร้างโดยนักพัฒนาแอปพลิเคชัน Layout Component เป็นเพียงส่วนประกอบอื่นและอยู่ภายใต้โฟลเดอร์ Components ซึ่งมีเส้นทางต่อไปนี้ -src/main/«java|resources»/«package_name»/components.

ให้เราสร้างองค์ประกอบเค้าโครงอย่างง่ายที่เรียกว่า MyCustomLayout. รหัสสำหรับ MyCustomLayout มีดังนี้ -

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

ในคลาสคอมโพเนนต์ MyCustomLayout เราได้ประกาศฟิลด์หัวเรื่องและโดยใช้คำอธิบายประกอบเราได้กำหนดให้เป็นข้อบังคับ ตอนนี้เปลี่ยนเทมเพลต HelloWorld.html เพื่อใช้เค้าโครงที่กำหนดเองของเราดังที่แสดงในบล็อกโค้ดด้านล่าง

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

เราจะเห็นได้ที่นี่ว่าเทมเพลต XML ไม่มีแท็กส่วนหัวและส่วนเนื้อหา Tapestry จะรวบรวมรายละเอียดเหล่านี้จากองค์ประกอบเค้าโครงและ <t: body> ขององค์ประกอบเค้าโครงจะถูกแทนที่ด้วยเทมเพลต HelloWorld เมื่อทุกอย่างเสร็จสิ้น Tapestry จะปล่อยมาร์กอัปที่คล้ายกันตามที่ระบุด้านล่าง -

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

เลย์เอาต์สามารถซ้อนกันได้ ตัวอย่างเช่นเราอาจขยายเค้าโครงที่กำหนดเองของเราโดยรวมฟังก์ชันการดูแลระบบและใช้สำหรับส่วนผู้ดูแลระบบตามที่ระบุไว้ด้านล่าง

<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> เป็นองค์ประกอบระดับบนสุดและมีเนมสเปซแบบ tapestry ใช้เพื่อระบุส่วนไดนามิกของส่วนประกอบ

ตัวอย่างเช่นคอมโพเนนต์กริดอาจต้องการเทมเพลตเพื่อระบุวิธีการแสดงผลแถว - tr (และคอลัมน์ td) ภายในตาราง HTML

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

<t: block>

<t: block> เป็นตัวยึดสำหรับส่วนไดนามิกในเทมเพลต โดยทั่วไปองค์ประกอบบล็อกจะไม่แสดงผล เฉพาะส่วนประกอบที่กำหนดในเทมเพลตเท่านั้นที่ใช้องค์ประกอบบล็อก คอมโพเนนต์จะฉีดข้อมูลแบบไดนามิกลงในองค์ประกอบบล็อกและแสดงผล หนึ่งในกรณีการใช้งานที่เป็นที่นิยมคือAJAX.

องค์ประกอบบล็อกให้ตำแหน่งที่แน่นอนและมาร์กอัปสำหรับข้อมูลไดนามิกที่จะแสดงผล ทุกองค์ประกอบของบล็อกควรมีคุณสมบัติ Java ที่สอดคล้องกัน จากนั้นจึงสามารถแสดงผลแบบไดนามิกได้ id ขององค์ประกอบบล็อกควรเป็นไปตามกฎตัวระบุตัวแปร Java ตัวอย่างบางส่วนมีให้ด้านล่าง

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

องค์ประกอบ <t: content> ใช้เพื่อระบุเนื้อหาจริงของเทมเพลต โดยทั่วไปแล้วมาร์กอัปทั้งหมดถือเป็นส่วนหนึ่งของเทมเพลต หากระบุ <t: content> ระบบจะพิจารณาเฉพาะมาร์กอัปที่อยู่ภายในเท่านั้น ฟีเจอร์นี้ถูกใช้โดยนักออกแบบเพื่อออกแบบเพจโดยไม่มีองค์ประกอบเค้าโครง

<t: ลบ>

<t: remove> ตรงข้ามกับองค์ประกอบเนื้อหา มาร์กอัปภายในองค์ประกอบลบไม่ถือเป็นส่วนหนึ่งของเทมเพลต สามารถใช้สำหรับความคิดเห็นของเซิร์ฟเวอร์เท่านั้นและเพื่อวัตถุประสงค์ในการออกแบบ

สินทรัพย์

เนื้อหาคือไฟล์ทรัพยากรแบบคงที่เช่นสไตล์ชีตรูปภาพและไฟล์ JavaScript โดยทั่วไปเนื้อหาจะอยู่ในไดเรกทอรีรากของเว็บแอปพลิเคชัน/src/main/webapp.

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

Tapestry ยังจัดการไฟล์ที่เก็บไว้ในไฟล์ Java Classpathเป็นสินทรัพย์ Tapestry มีตัวเลือกขั้นสูงในการรวมเนื้อหาไว้ในเทมเพลตผ่านตัวเลือกการขยาย

  • Context - ตัวเลือกในการรับเนื้อหาที่มีอยู่ในบริบทของเว็บ

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

asset- ส่วนประกอบมักจะเก็บทรัพย์สินของตัวเองไว้ในไฟล์ jar พร้อมกับคลาส Java เริ่มจาก Tapestry 5.4 เส้นทางมาตรฐานในการจัดเก็บเนื้อหาใน classpath คือMETA-INF/assets. สำหรับไลบรารีเส้นทางมาตรฐานในการจัดเก็บสินทรัพย์คือMETA-INF/assets/«library_name»/. asset: ยังสามารถโทร context: การขยายเพื่อรับเนื้อหาจากบริบทของเว็บ

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

สามารถแทรกเนื้อหาลงใน Tapestry Page หรือ Component ได้โดยใช้คำอธิบายประกอบแบบ Inject และ Path พารามิเตอร์สำหรับคำอธิบายประกอบพา ธ คือพา ธ สัมพัทธ์ของเนื้อหา

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

Path parameter ยังสามารถมีสัญลักษณ์ Tapestry ที่กำหนดไว้ในไฟล์ AppModule.java มาตรา.

ตัวอย่างเช่นเราสามารถกำหนดสัญลักษณ์ skin.root พร้อมบริบทของค่า: สกิน / พื้นฐานและใช้ตามที่แสดงด้านล่าง -

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

การแปล

การรวมทรัพยากรผ่านผ้าม่านให้ฟังก์ชันพิเศษ หนึ่งในฟังก์ชันดังกล่าวคือ“ การแปลเป็นภาษาท้องถิ่น” Tapestry จะตรวจสอบสถานที่ปัจจุบันและรวมทรัพยากรที่เหมาะสม

ตัวอย่างเช่นหากตั้งค่าภาษาปัจจุบันเป็น deแล้ว edit_de.png จะถูกรวมไว้แทน edit.png

CSS

Tapestry มีการรองรับสไตล์ชีตในตัว พรมจะฉีดtapestry.cssเป็นส่วนหนึ่งของสแต็ก Javascript หลัก จาก Tapestry 5.4 พรมรวมถึงbootstrap css frameworkเช่นกัน. เราสามารถรวมสไตล์ชีตของเราเองโดยใช้แท็กลิงก์ปกติ ในกรณีนี้สไตล์ชีตควรอยู่ในไดเรกทอรีรากของเว็บ -/src/main/webapp/.

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

Tapestry มีตัวเลือกขั้นสูงในการรวมสไตล์ชีตไว้ในเทมเพลตผ่านตัวเลือกการขยายตามที่กล่าวไว้ก่อนหน้านี้

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

Tapestry ยังมีคำอธิบายประกอบการนำเข้าเพื่อรวมสไตล์ชีตลงในคลาส Java โดยตรง

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

Tapestry มีตัวเลือกมากมายในการจัดการสไตล์ชีตผ่าน AppModule.java ตัวเลือกที่สำคัญบางส่วน ได้แก่ -

  • สไตล์ชีตเริ่มต้นของ Tapestry อาจถูกลบออก

@Contribute(MarkupRenderer.class) 

public static void 
deactiveDefaultCSS(OrderedConfiguration<MarkupRendererFilter> configuration) { 
   configuration.override("InjectDefaultStyleheet", null); 
}
  • Bootstrap ยังสามารถปิดใช้งานได้โดยการลบล้างเส้นทาง

configuration.add(SymbolConstants.BOOTSTRAP_ROOT, "classpath:/METAINF/assets");
  • เปิดใช้งานการย่อขนาดเนื้อหาแบบไดนามิก (CSS และ JavaScript) เราจำเป็นต้องรวมtapestry-webresources การพึ่งพา (ใน 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 ฝั่งไคลเอ็นต์

การสร้างเว็บแอปพลิเคชันในปัจจุบันขึ้นอยู่กับ JavaScript เป็นอย่างมากเพื่อมอบประสบการณ์ฝั่งไคลเอ็นต์ Tapestry รับทราบและให้การสนับสนุนระดับเฟิร์สคลาสสำหรับ JavaScript การสนับสนุน JavaScript นั้นฝังแน่นอยู่ใน Tapestry และพร้อมใช้งานในทุกขั้นตอนของการเขียนโปรแกรม

ก่อนหน้านี้ Tapestry เคยรองรับเฉพาะ Prototype และ Scriptaculous แต่จากเวอร์ชัน 5.4 Tapestry จะเขียนเลเยอร์ JavaScript ใหม่ทั้งหมดเพื่อให้เป็นแบบทั่วไปที่สุดและให้การสนับสนุนระดับเฟิร์สคลาสสำหรับ JQuery ซึ่งเป็นไลบรารี de-facto สำหรับ JavaScript นอกจากนี้ tapestry ยังสนับสนุนการเขียนโปรแกรม JavaScript ที่ใช้ Modules และสนับสนุน RequireJS ซึ่งเป็นการนำ AMD ไปใช้งานฝั่งไคลเอ็นต์ที่เป็นที่นิยม (Asynchronous Module Definition - ข้อกำหนด JavaScript เพื่อรองรับโมดูลและการอ้างอิงในลักษณะอะซิงโครนัส)

สถานที่

ไฟล์ JavaScript เป็นทรัพย์สินของ Tapestry Application ตามกฎของเนื้อหาไฟล์ JavaScript จะถูกวางไว้ภายใต้บริบทของเว็บ/sr/main/webapp/ หรือวางไว้ในโถด้านล่าง META-INF/assets/ location.

การเชื่อมโยงไฟล์ JavaScript

วิธีที่ง่ายที่สุดในการเชื่อมโยงไฟล์ JavaScript ในเทมเพลต XML คือการใช้แท็กสคริปต์โดยตรงซึ่งก็คือ - <script language = "javascript" src = "relative/path/to/js"></script>. แต่ผ้าม่านไม่แนะนำวิธีการเหล่านี้ Tapestry มีตัวเลือกมากมายในการเชื่อมโยงไฟล์ JavaScript ใน Page / Component บางส่วนเหล่านี้ได้รับด้านล่าง

  • @import annotation- คำอธิบายประกอบ @import มีตัวเลือกในการเชื่อมโยงไลบรารี JavaScript หลายรายการโดยใช้นิพจน์บริบท สามารถใช้ได้กับทั้ง Page class และ method หากนำไปใช้กับคลาสเพจจะใช้กับวิธีการทั้งหมด หากใช้กับเมธอดของเพจจะใช้กับเมธอดนั้นเท่านั้นจากนั้น Tapestry จะลิงก์ไลบรารี JavaScript ก็ต่อเมื่อมีการเรียกใช้เมธอด

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

public class MyComponent { 
   // ... 
}
  • JavaScriptSupport interface - JavaScriptSupport เป็นอินเทอร์เฟซที่กำหนดโดย Tapestry และมีวิธีการ importJavaScriptLibraryเพื่อนำเข้าไฟล์ JavaScript สามารถสร้างวัตถุ JavScriptSupport ได้อย่างง่ายดายเพียงแค่ประกาศและใส่คำอธิบายประกอบด้วย @Environmental annotation

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

@Environmental 
private JavaScriptSupport javaScriptSupport;  
void setupRender() { 
   javaScriptSupport.importJavaScriptLibrary(myEffects); 
}
  • JavaScripSupport สามารถแทรกลงในส่วนประกอบโดยใช้ไฟล์ @Environmentalคำอธิบายประกอบ สำหรับบริการเราจำเป็นต้องใช้ไฟล์@Inject คำอธิบายประกอบหรือเพิ่มเป็นอาร์กิวเมนต์ในเมธอดตัวสร้างบริการ

@Inject 
private JavaScriptSupport javaScriptSupport; 
public MyServiceImpl(JavaScriptSupport support) { 
   // ... 
}
  • addScript method - สิ่งนี้คล้ายกับอินเทอร์เฟซ JavaScriptSupport ยกเว้นว่าจะใช้ไฟล์ addScript วิธีการและรหัสจะถูกเพิ่มโดยตรงในผลลัพธ์ที่ด้านล่างของหน้า

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

กอง JavaScript

Tapestry อนุญาตให้รวมกลุ่มของไฟล์ JavaScript และสไตล์ชีตที่เกี่ยวข้องและใช้เป็นเอนทิตีเดียว ปัจจุบัน Tapestry มีสแต็กที่ใช้ Prototype และ JQuery

นักพัฒนาสามารถพัฒนาสแต็กของตนเองได้โดยใช้ไฟล์ JavaScriptStack และลงทะเบียนในไฟล์ AppModule.java. เมื่อลงทะเบียนแล้วสามารถนำเข้าสแต็กโดยใช้ไฟล์@import คำอธิบายประกอบ

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

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