TurboGears - ภาษาแม่แบบ Genshi

Genshi เป็นภาษาเทมเพลตที่ใช้ XML มันคล้ายกับKidซึ่งเคยเป็นเครื่องมือแม่แบบสำหรับ TurboGears เวอร์ชันก่อนหน้า Genshi และ Kid ได้รับแรงบันดาลใจจากภาษาแม่แบบที่รู้จักกันดีอื่น ๆ เช่นHSLT, TAL และ PHP.

เทมเพลต Genshi ประกอบด้วยคำสั่งการประมวลผล คำสั่งเหล่านี้เป็นองค์ประกอบและคุณลักษณะในเทมเพลต คำสั่ง Genshi ถูกกำหนดไว้ในเนมสเปซhttp://genshi.edgewall.org/. ดังนั้นจึงต้องมีการประกาศเนมสเปซนี้ในองค์ประกอบหลักของเทมเพลต

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
...
</html>

การประกาศด้านบนหมายความว่าเนมสเปซเริ่มต้นถูกตั้งค่าเป็น XHTML และคำสั่ง Genshi มีคำนำหน้า "py"

คำสั่ง Genshi

คำสั่งหลายอย่างถูกกำหนดไว้ใน Genshi รายการต่อไปนี้แจกแจงคำสั่งของ Genshi -

  • py:if
  • py:choose
  • py:for
  • py:def
  • py:match
  • py:with
  • py:replace
  • py:content
  • py:attrs
  • py:strip

ส่วนเงื่อนไข

Genshi มีคำสั่งสองประการสำหรับการแสดงเนื้อหาตามเงื่อนไขคือ py: if และ py: choose

py: ถ้า

เนื้อหาขององค์ประกอบคำสั่งนี้จะแสดงผลก็ต่อเมื่อนิพจน์ใน if clauseประเมินเป็นจริง สมมติว่าข้อมูลในบริบทเทมเพลตคือ{‘foo’:True, ‘bar’:’Hello’}คำสั่งต่อไปนี้ -

<div>
   <b py:if = "foo">${bar}</b>
</div>

จะส่งผลให้

Hello

อย่างไรก็ตามผลลัพธ์นี้จะไม่แสดงผลหาก ‘foo’ is set to False.

คำสั่งนี้ยังสามารถใช้เป็นองค์ประกอบได้ ในกรณีนี้<py:if> จะต้องปิดโดยสอดคล้องกัน </py:if>

<div>
   <py:if test = "foo">
      <b>${bar}</b>
   </py:if>
</div>

py: เลือก

การประมวลผลตามเงื่อนไขขั้นสูงเป็นไปได้ด้วยการใช้ py:choose ร่วมกับ py:when และ py:otherwiseคำสั่ง คุณสมบัตินี้คล้ายกับswitch – case สร้างใน C/C++.

นิพจน์ใน py:choose คำสั่งถูกตรวจสอบด้วยค่าต่างๆที่ระบุด้วย py:whenทางเลือกอื่นและเนื้อหาที่เกี่ยวข้องจะถูกแสดงผล ทางเลือกเริ่มต้นสามารถระบุได้ในรูปแบบpy:otherwise คำสั่ง

<div py:choose = "foo”>
   <span py:when = "0">0</span>
   <span py:when = "1">1</span>
   <span py:otherwise = "">2</span>
</div>

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ py:choose และ py:whenคำสั่ง รูปแบบ HTML โพสต์ข้อมูลเพื่อ / ทำเครื่องหมาย URL marks() ฟังก์ชันเปลี่ยนเส้นทางเครื่องหมายและผลลัพธ์ในรูปแบบของวัตถุพจนานุกรมไปที่ total.htmlแม่แบบ การแสดงเงื่อนไขของresult Pass/Fail ทำได้โดยใช้ py:choose และ py:when คำสั่ง

สคริปต์ HTML ของการป้อนเครื่องหมาย (marks.html) มีดังนี้ -

<html>
   <body>
      <form action = "http://localhost:8080/marks" method = "post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
   </body>
</html>

รหัสที่สมบูรณ์ของ root.pyมีดังนี้ marks() ตัวควบคุมกำลังส่งเครื่องหมายและผลลัพธ์ไปที่ total.html แม่แบบ -

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
      def marksform(self):
      return {}
		
   @expose("hello.templates.total")
      def marks(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      ttl = int(phy)+int(maths)
      avg = ttl/2
		
      if avg ≥ 50:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl, 'result':2}
      else:
         mydata = {'phy':phy, 'maths':maths, 'total':ttl,'result':1}
	
      return mydata

total.html ในโฟลเดอร์ template ได้รับข้อมูลพจนานุกรมและแยกวิเคราะห์ในเอาต์พุต html ตามเงื่อนไขดังนี้ -

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <head>
      <title>TurboGears Templating Example</title>
   </head>
	
   <body>
      <h2>Hello, Welcome to TurboGears!.</h2>
      <h3>Marks in Physics: ${phy}.</h3>
      <h3>Marks in Maths: ${maths}.</h3>
      <h3>Total Marks: ${total}</h3>
		
      <div py:choose = "result">
         <span py:when = "1"><h2>Result: Fail</h2></span>
         <span py:when = "2"><h2>Result: Pass</h2></span>
      </div>
		
   </body>
</html>

เริ่มเซิร์ฟเวอร์ (หากยังไม่ได้ทำงาน)

Gearbox server –reload –debug

ป้อน http://localhost::8080/marksform ในเบราว์เซอร์ -

total.html จะแสดงผลลัพธ์ต่อไปนี้ -

py: สำหรับ

องค์ประกอบใน py: สำหรับคำสั่งซ้ำสำหรับแต่ละรายการในรายการที่ทำซ้ำได้โดยปกติจะเป็นวัตถุ Python List ถ้าitems = [1,2,3] มีอยู่ในบริบทเทมเพลตสามารถทำซ้ำได้โดยทำตาม py: for directive -

<ul>
   <li py:for = "item in items">${item}</li>
</ul>

ผลลัพธ์ต่อไปนี้จะแสดงผล -

1
2
3

ตัวอย่างต่อไปนี้แสดงข้อมูลฟอร์ม HTML ที่แสดงผลในเทมเพลต total.html โดยใช้ py: สำหรับคำสั่งสามารถใช้ได้ดังนี้ -

<py:for each = "item in items">
   <li>${item}</li>
</py:for>

สคริปต์ฟอร์ม HTML

<html>
   <body>
	
      <form action = "http://localhost:8080/loop" method="post">
         <p>Marks in Physics:</p>
         <p><input type = "text" name = "phy" /></p>
         <p>Marks in Chemistry:</p>
         <p><input type = "text" name = "che" /></p>
         <p>Marks in Maths:</p>
         <p><input type = "text" name = "maths" /></p>
         <p><input type = "submit" value = "submit" /></p>
      </form>
		
   </body>
</html>

loop() ตัวควบคุมอ่านข้อมูลแบบฟอร์มและส่งไปยัง total.template ในรูปแบบของวัตถุรายการ

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose("hello.templates.marks")
   def marksform(self):
   return {}
	
   @expose("hello.templates.temp")
   def loop(self, **kw):
      phy = kw['phy']
      maths = kw['maths']
      che = kw['che']
      l1 = []
      l1.append(phy)
      l1.append(che)
      l1.append(maths)
		
   return ({'subjects':['physics', 'Chemistry', 'Mathematics'], 'marks':l1})

เทมเพลต temp.html ใช้ py: for loop เพื่อแสดงเนื้อหาของวัตถุ dict ในรูปแบบของตาราง

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <body>
      <b>Marks Statement</b>
      <table border = '1'>
         <thead>
            <py:for each = "key in subjects"><th>${key}</th></py:for>
         </thead>
         <tr>
            <py:for each = "key in marks"><td>${key}</td></py:for>
         </tr>
      </table>
   </body>
</html>

เริ่มเซิร์ฟเวอร์ (หากยังไม่ได้ทำงาน)

gearbox server –reload –debug

ป้อน http://localhost::8080/marksform ในเบราว์เซอร์

ผลลัพธ์ต่อไปนี้จะแสดงในเบราว์เซอร์เมื่อส่งแบบฟอร์มด้านบน

py: def

คำสั่งนี้ใช้ในการสร้างมาโคร มาโครคือตัวอย่างโค้ดเทมเพลตที่ใช้ซ้ำได้ เช่นเดียวกับฟังก์ชัน Python มีชื่อและสามารถเลือกพารามิเตอร์ได้ คุณสามารถแทรกเอาต์พุตของมาโครนี้ที่ตำแหน่งใดก็ได้ในเทมเพลต

คำสั่ง py: def เป็นไปตามไวยากรณ์ต่อไปนี้ -

<p py:def = "greeting(name)">
   Hello, ${name}!
</p>

มาโครนี้สามารถแสดงผลด้วยค่าตัวแปรเป็นพารามิเตอร์ 'name'

${greeting('world')}
${greeting('everybody)}

คำสั่งนี้สามารถใช้กับไวยากรณ์เวอร์ชันอื่นได้ดังนี้ -

<py:def function = "greeting(name)">
   <p>Hello, ${name}! </p>
</py:def>

ในตัวอย่างต่อไปนี้ macro() ตัวควบคุมใน root.py ส่งไฟล์ dict ออบเจ็กต์ที่มีสองคีย์ name1 และ name2 ไปยังเทมเพลต macro.html

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name1':'TutorialPoint', 'name2':'TurboGears'}

เทมเพลต macro.html นี้มีคำจำกัดความของมาโครที่เรียกว่าคำทักทาย ใช้เพื่อสร้างข้อความทักทายสำหรับข้อมูลที่ได้รับจากคอนโทรลเลอร์

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:def example</h2>
		
      <div>
         <div py:def = "greeting(name)">
            Hello, Welcome to ${name}!
         </div>
				
         <b>
            ${greeting(name1)}
            ${greeting(name2)}
         </b>
			
      </div>
   </body>
</html>

เริ่มเซิร์ฟเวอร์โดยใช้กระปุกเกียร์

gearbox serve –reload –debug

เรียกใช้ตัวควบคุมมาโคร () โดยป้อน URL ต่อไปนี้ในเบราว์เซอร์ -

http://localhost:8080/macro

ผลลัพธ์ต่อไปนี้จะแสดงผลในเบราว์เซอร์ -

py: กับ

คำสั่งนี้ช่วยให้คุณกำหนดนิพจน์ให้กับตัวแปรโลคัล ตัวแปรท้องถิ่นเหล่านี้ทำให้การแสดงออกภายใน verbose น้อยลงและมีประสิทธิภาพมากขึ้น

สมมติว่าให้ x = 50 ในข้อมูลบริบทสำหรับเทมเพลตต่อไปนี้จะเป็น py: with directive -

<div>
   <span py:with = "y = 50; z = x+y">$x $y $z</span>
</div>

มันจะส่งผลต่อไปนี้ -

50 50 100

นอกจากนี้ยังมีเวอร์ชันทางเลือกสำหรับ py: พร้อมคำสั่ง -

<div>
   <py:with = "y = 50; z = x+y">$x $y $z</py:with>
</div>

ในตัวอย่างต่อไปนี้ตัวควบคุม macro () จะส่งคืนอ็อบเจ็กต์ dict พร้อมคีย์ชื่อ phy และ maths

from hello.lib.base import BaseController
from tg import expose, request

class RootController(BaseController):
   @expose('hello.templates.macro')
   def macro(self):
      return {'name':'XYZ', 'phy':60, 'maths':70}

เทมเพลต macro.html เพิ่มค่า phy และคีย์คณิตศาสตร์โดยใช้ py: with directive

<html xmlns = "http://www.w3.org/1999/xhtml"
   xmlns:py = "http://genshi.edgewall.org/"
   lang = "en">
	
   <body>
      <h2>py:with example</h2>
      <h3>Marks Statement for : ${name}!</h3>
		
      <b>Phy: $phy Maths: $maths
         <span py:with = "ttl = phy+maths">Total: $ttl</span>
      </b>
		
   </body>
	
</html>

เบราว์เซอร์จะแสดงผลลัพธ์ต่อไปนี้ตาม URL http://localhost:8080/macro

คำสั่งการจัดการโครงสร้าง

py:attrs คำสั่งเพิ่มแก้ไขหรือลบแอตทริบิวต์จากองค์ประกอบ

<ul>
   <li py:attrs = "foo">Bar</li>
</ul>

ถ้า foo = {‘class’:’collapse’} มีอยู่ในบริบทเทมเพลตซึ่งตัวอย่างข้อมูลข้างต้นจะแสดงผล

<ul>
   <li class = "collapse">Bar</li>
</ul>

py:content คำสั่งแทนที่เนื้อหาที่ซ้อนกันด้วยผลของการประเมินนิพจน์ -

<ul>
   <li py:content = "bar">Hello</li>
</ul>

ระบุ bar = 'Bye' ในข้อมูลบริบทสิ่งนี้จะสร้างขึ้น

<ul>
   <li>Bye</li>
</ul>

py:replace คำสั่งแทนที่องค์ประกอบของตัวเองด้วยผลของการประเมินนิพจน์ -

<div>
   <span py:replace = "bar">Hello</span>
</div>

ให้ bar = 'Bye' ในข้อมูลบริบทมันจะสร้างขึ้น

<div>
   Bye
</div>