TurboGears - Ngôn ngữ mẫu Genshi

Genshi là một ngôn ngữ khuôn mẫu dựa trên XML. Nó tương tự nhưKid, từng là công cụ mẫu cho các phiên bản trước của TurboGears. Genshi cũng như Kid được lấy cảm hứng từ các ngôn ngữ mẫu nổi tiếng khác nhưHSLT, TALPHP.

Mẫu Genshi bao gồm các chỉ thị xử lý. Các Chỉ thị này là các phần tử và thuộc tính trong một mẫu. Các chỉ thị Genshi được xác định trong một không gian tênhttp://genshi.edgewall.org/. Do đó không gian tên này cần được khai báo trong phần tử gốc của mẫu.

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

Khai báo trên có nghĩa là không gian tên mặc định được đặt thành XHTML và các chỉ thị Genshi có tiền tố 'py'.

Genshi Directives

Một số chỉ thị được định nghĩa trong Genshi. Danh sách sau liệt kê các chỉ thị Genshi -

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

Phần có điều kiện

Genshi cung cấp hai chỉ thị để hiển thị có điều kiện nội dung - py: if và py: select.

py: nếu

Nội dung của phần tử của chỉ thị này sẽ chỉ được hiển thị nếu biểu thức trong if clauseđánh giá đúng. Giả sử rằng dữ liệu trong ngữ cảnh mẫu là{‘foo’:True, ‘bar’:’Hello’}, chỉ thị sau -

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

sẽ cho kết quả

Hello

Tuy nhiên, đầu ra này sẽ không được hiển thị nếu ‘foo’ is set to False.

Chỉ thị này cũng có thể được sử dụng như một phần tử. Trong trường hợp này<py:if> phải được đóng bằng tương ứng </py:if>

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

py: chọn

Có thể xử lý có điều kiện nâng cao với việc sử dụng py:choose kết hợp với py:whenpy:otherwisecác chỉ thị. Tính năng này tương tự nhưswitch – case xây dựng trong C/C++.

Biểu hiện trong py:choose chỉ thị được kiểm tra với các giá trị khác nhau được xác định với py:whencác lựa chọn thay thế và nội dung tương ứng sẽ được hiển thị. Một giải pháp thay thế mặc định có thể được cung cấp dưới dạngpy:otherwise chỉ thị.

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

Ví dụ sau minh họa việc sử dụng py:choosepy:whencác chỉ thị. Biểu mẫu HTML đăng dữ liệu lên / đánh dấu URL. Cácmarks() hàm chuyển hướng các dấu và kết quả dưới dạng một đối tượng từ điển đến total.htmlbản mẫu. Hiển thị có điều kiện củaresult Pass/Fail đạt được bằng cách sử dụng py:choosepy:when các chỉ thị.

Tập lệnh HTML nhập dấu (marks.html) như sau -

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

Mã hoàn chỉnh của root.pylà như sau. Cácmarks() bộ điều khiển đang gửi điểm và kết quả tới total.html mẫu -

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

Các total.html trong thư mục mẫu nhận dữ liệu từ điển và phân tích cú pháp nó trong đầu ra html có điều kiện như sau:

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

Khởi động máy chủ (nếu chưa chạy)

Gearbox server –reload –debug

Đi vào http://localhost::8080/marksform trong trình duyệt -

Các total.html sẽ hiển thị đầu ra sau -

py: cho

Phần tử trong chỉ thị py: for được lặp lại cho từng mục trong một đối tượng có thể lặp lại, thường là đối tượng Danh sách Python. Nếuitems = [1,2,3] có mặt trong ngữ cảnh mẫu, nó có thể được lặp lại bằng cách sau py: for chỉ thị -

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

Kết quả sau sẽ được hiển thị:

1
2
3

Ví dụ sau cho thấy dữ liệu biểu mẫu HTML được hiển thị trong mẫu total.html sử dụng py: for chỉ thị cũng có thể được sử dụng như sau:

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

Tập lệnh biểu mẫu 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>

Các loop() bộ điều khiển đọc dữ liệu biểu mẫu và gửi nó đến total.template dưới dạng một đối tượng danh sách.

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

Mẫu temp.html sử dụng vòng lặp py: for để hiển thị nội dung của đối tượng dict dưới dạng một bảng.

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

Khởi động máy chủ (nếu chưa chạy)

gearbox server –reload –debug

Đi vào http://localhost::8080/marksform trong trình duyệt.

Kết quả sau sẽ được hiển thị trong trình duyệt khi mẫu trên được gửi.

py: def

Chỉ thị này được sử dụng để tạo macro. Macro là một đoạn mã mẫu có thể sử dụng lại. Giống như một hàm Python, nó có một tên và có thể có các tham số tùy chọn. Đầu ra của macro này có thể được chèn vào bất kỳ vị trí nào trong mẫu.

Lệnh py: def tuân theo cú pháp sau:

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

Macro này có thể được hiển thị với một giá trị biến thành tham số 'name'.

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

Chỉ thị này cũng có thể được sử dụng với một phiên bản cú pháp khác như sau:

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

Trong ví dụ sau, macro() điều khiển trong root.py gửi một dict đối tượng có hai khóa name1 và name2 vào mẫu 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'}

Mẫu macro.html này chứa định nghĩa về macro được gọi là lời chào. Nó được sử dụng để tạo thông điệp chào mừng cho dữ liệu nhận được từ bộ điều khiển.

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

Khởi động máy chủ bằng hộp số

gearbox serve –reload –debug

Gọi bộ điều khiển macro () bằng cách nhập URL sau vào trình duyệt -

http://localhost:8080/macro

Kết quả sau sẽ được hiển thị trong trình duyệt -

py: với

Chỉ thị này cho phép bạn gán các biểu thức cho các biến cục bộ. Các biến cục bộ này làm cho biểu thức bên trong ít dài dòng hơn và hiệu quả hơn.

Giả sử rằng x = 50 được cung cấp trong dữ liệu ngữ cảnh cho một mẫu, sau đây sẽ là lệnh py: with -

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

Nó sẽ dẫn đến kết quả sau:

50 50 100

Một phiên bản thay thế cho py: với chỉ thị cũng có sẵn -

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

Trong ví dụ sau, bộ điều khiển macro () trả về một đối tượng dict với các khóa tên, phy và toán học.

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}

Mẫu macro.html thêm giá trị của các khóa phy và toán học bằng cách sử dụng lệnh py: with.

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

Trình duyệt sẽ hiển thị đầu ra sau để phản hồi lại URL http://localhost:8080/macro

Hướng dẫn thao tác cấu trúc

Các py:attrs chỉ thị thêm, sửa đổi hoặc loại bỏ các thuộc tính khỏi phần tử.

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

Nếu foo = {‘class’:’collapse’} có trong ngữ cảnh mẫu, đoạn mã trên sẽ hiển thị.

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

Các py:content chỉ thị thay thế mọi nội dung lồng nhau bằng kết quả đánh giá biểu thức -

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

Cho bar = 'Bye' trong dữ liệu ngữ cảnh, điều này sẽ tạo ra

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

Các py:replace chỉ thị thay thế chính phần tử bằng kết quả đánh giá biểu thức -

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

Cho bar = 'Bye' trong dữ liệu ngữ cảnh, nó sẽ tạo ra

<div>
   Bye
</div>