Personal tools

Kid言語使用

KidはシンプルなXMLベースのテンプレート言語です。ロジックを記述するための組み込み言語にはPythonを利用しています。構文規則は,XSLTやTAL,PHPなどの多くの既存テンプレート言語に影響を受けています。

Click here to get the file

Size 50.5 kB - File type text/plain

File contents

Kid Language Specification

Kid 言語仕様

著者: 	Ryan Tomayko
メールアドレス: 	rtomayko@gmail.com
リビジョン: 	5
更新日: 	2006-02-26
Copyright: 	2005, Ryan Tomayko

Kid is a simple XML based template language that uses embedded Python to do cool stuff. The syntax was inspired by a number of existing template languages, namely XSLT, TAL, and PHP.

KidはシンプルなXMLベースのテンプレート言語です。ロジックを記述するための組み込み言語にはPythonを利用しています。構文規則は,XSLTやTAL,PHPなどの多くの既存テンプレート言語に影響を受けています。

This document describes the template language and will be most useful as reference to those developing Kid templates. For information about using templates from Python, the command line, or in web environments, see the User's Guide.

この文書では,テンプレート言語の文法について言及しています。Kidテンプレートを開発する際のリファレンスとして利用すると便利でしょう。コマンドライン上,またはWebアプリケーションなど,Pythonからテンプレートを利用する方法については,ユーザーズガイド(未訳)をご覧下さい。

Contents

目次

    * 1   Synopsis
    * 2   The Kid Namespace
    * 3   Embedding Code Blocks (<?python?>)
    * 4   Content Producing Constructs
    * 5   Python Expression Substitution (${expr})
          o 5.1   Identifier Shortcut ($name)
          o 5.2   Escaping ($$)
    * 6   Default Imports
          o 6.1   XML() function
          o 6.2   document() function
          o 6.3   defined(name) and value_of(name, default) functions
    * 7   Attribute Language
          o 7.1   Repetition/Iteration (py:for)
          o 7.2   Conditionals (py:if)
          o 7.3   Dynamic Content (py:content)
          o 7.4   Replacing Content (py:replace)
          o 7.5   Stripping Tags (py:strip)
          o 7.6   Dynamic Attributes (py:attrs)
          o 7.7   Named Template Functions (py:def)
          o 7.8   Match Templates (py:match)
          o 7.9   Template Reuse (py:extends)
          o 7.10   Layout Templates (py:layout)
    * 8   Processing Order
    * 9   XML Comments
    * 10   Revision History
          o 10.1   Revision 5 (Kid v0.9)
          o 10.2   Revision 4 (Kid v0.6)
          o 10.3   Revision 3 (Kid v0.5)
          o 10.4   Revision 2
          o 10.5   Revision 1

1   Synopsis

1   概要


<?python
title = "Kidのテスト用ドキュメント"
fruits = [u"りんご", u"オレンジ", u"キウィ", u"M&M"]
from platform import system
?>
<html xmlns:py="http://purl.org/kid/ns#">
  <head>
    <title py:content="title">この部分は置換されます</title>
  </head>
  <body>
    <p>私の好きな果物:</p>
    <ul>
      <li py:for="fruit in fruits">
        私は ${fruit}s が好き。
      </li>
    </ul>
    <p py:if="system() == 'Linux'">
      偉いぞ!
    </p>
  </body>
</html>

Yields something like this:

このテンプレートは以下のように変換されます:

<?xml version="1.0" encoding="utf-8"?>
<html>
  <head>
    <title>Kidのテスト用ドキュメント</title>
  </head>
  <body>
    <p>These are some of my favorite fruits:</p>
    <ul>
      <li>私は りんご が好きです</li>
      <li>私は オレンジ が好きです</li>
      <li>私は キウィ が好きです</li>
      <li>私は M&M が好きです</li>
    </ul>
    <p>
      偉いぞ!
    </p>
  </body>
</html>

2   The Kid Namespace

2   KidのXML名前空間

All attributes described in this document must belong to the following namespace:

この文書に記述されているXMLのアトリビュートは,すべて以下のXML名前空間に定義されています:

http://purl.org/kid/ns#

The namespace prefix py is used throughout this document to indicate that an item belongs to the Kid/Python namespace.

"py"から始まる名前空間は,Kid/Python名前空間に属するものとして利用しています。

3   Embedding Code Blocks (<?python?>)

3   コードブロックを埋め込む (<?python?>)

The <?python?> processing instruction (PI) contains Python code and MAY occur anywhere that is legal for processing instructions to occur in an XML document.

<?python?> という「処理命令」(processing instruction ,PI)はPythonのコードを含み,正しいXML文書の処理命令の中にならどんな場所にも記述できます。

The rules for executing code found in a <?python?> PI is as follows:

<?python?>の中にあるコードを実行するためのルールは次のようになっています:

   1. <?python?> PIs located outside of the document element (e.g. root element) contain Document Level code. This code SHOULD be executed in a global, shared scope for the document. The code SHOULD be executed once when the template is loaded and shared between multiple invocations of the template.

   1. <?python?> 処理命令が,文書レベルのコードを含むエレメント(ルートエレメントのような)の外にある場合。テンプレートを読み込んだとき,または外部から呼び出されたとき,コードを一回だけ実行します。

   2. <?python?> PIs located within the document element contain Local Level code. This code is executed each time the document is processed with a local scope specific to the invocation and the shared document level global scope.

   2. <?python?> 処理命令がXML文書のエレメントの中にある場合。処理命令が存在するスコープが評価される場合,外部から呼び出された時に毎回実行します。

Document Level and Local Level code work exactly like Module Level and Function Level code in normal Python modules. For example, the following Kid template:

文書レベルにあるコードは,Pythonのモジュールレベルにあるコードと同じように動作します。ローカルレベルのコードは,Pythonモジュールの関数レベルにあるコードと同じように動作します。例えば,以下のようなテンプレートを見てみましょう:

<?python
x = 0
y = 0
?>
<html xmlns:py="http://purl.org/kid/ns#">
  <?python
  x = 1
  if x == 1:
    x = 10
  ?>
  <p py:content="x"/>
  <?python
  global y
  y = 30
  ?>
  <p py:content="y"/>
</html>

May be considered equivalent to the following Python module:

このコードは,以下のようなPythonのモジュールと同じと考えられます:

x = 0
y = 0
def expand(handler):
  handler.startDocument()
  handler.startElement('html')
  x = 1
  if x == 1:
    x = 10
  handler.element('p', content=x) # output p element with x as value
  global y
  y = 30
  handler.element('p', content=y) # output p element with value of y
  handler.endElement('html')
  handler.endDocument()

<?python?> PIs may contain any legal Python language construct including functions, classes, lamda forms, etc.

<?python?> 処理命令には文法的に正しいPythonの言語要素を記述できます。関数,クラス,lamdaなどを記述できます。

<?python
class Adder:
  def __init__(self, x, y):
    self.x = x
    self.y = y
  def doit(self):
    return self.x + self.y

foo = Adder(x=400, y=20)
x = foo.doit()
?>

Single line <?python?> PIs are okay too:

一行で <?python?> 処理命令を記述することもできます:

<?python x = 10 ?>

4   Content Producing Constructs

4   コンテンツを生成するための構造

There are multiple methods of generating content output from a template: py:content, py:replace, py:attrs, and ${} substitution. Each of these syntaxes have the same rules for what types of objects may result from the Python expression they contain.

テンプレートからコンテンツを出力するための方法には何種類かの方法があります。「py:content」や「py:replace」, 「py:attrs」などが利用できますし,または「${}」を利用できます。それぞれの文法には,Pythonの式からどんな結果を得るかによって、規則が存在します。

str, unicode

文字列,ユニコード文字列

    The string is inserted as XML CDATA. That is, it is non-parsable character data that does not contain markup. The following characters are encoded as XML entities when serialized: '<', '&'. Attribute values containing content also encode the quote character: '"'.
ElementTree.Element

    XMLのCDATAとして挿入される文字列です。構造をパースせず,マークアップを含まない文字列のデータです。シリアライズされたとき,'<','&'の文字はXMLエンティティとしてエンコードされます。内容を持つアトリビュート値は二重引用符(")でエンコードされます。

ElementTree.Element

ElementTree.Element

    When an ElementTree.Element is referenced from a content producing construct, the item is inserted into the document literally, i.e. it is not encoded as text, but becomes part of the output structure.

    ElementTree.Elementがコンテンツ出力中に参照されると,要素をそのまま挿入します。テキストとしてエンコードされず,XMLの構造の一部となります。

    The XML() and document() functions can be used to turn a string into structured content and to retrieve an XML document from a URL, respectively.

    XML()という関数を使うと,文字列を構造のあるコンテンツに変換できます。document()という関数は,URLからXML文書を取得し,コンテンツとして埋め込むことができます。

    Note that attribute values MUST NOT reference structured content. This applies to py:attrs and using ${} substitution in attribute values.

    注意すべきことは,アトリビュートの値はここで埋めるべきではない,ということです。py:attrや${}などを利用するようにしてください。

sequence

シーケンス

    If a sequence type (list, tuple, or other iterable) is referenced, the rules are applied to each of the items in the sequence. For example, you could reference a list containing an Element and a string.
Other

    シーケンスタイプ(リスト,タプルやどiterableなオブジェクト)を参照した場合,シーケンスのそれぞれの要素にルールを適用します。例えば, For example, you could reference a list containing an Element and a string.

Other

その他

    If the result of evaluating the expression is any other type, an attempt is made to coerce the value to unicode as if by calling unicode(expr) and processing continues as if the object were a string or unicode object initially.

    評価された結果がここに挙げたタイプでない場合は,unicode(expr)を実行してユニコードに強制的に変換しようとします。オブジェクトが内部的にはユニコード文字列,または文字列であったこととして処理を続けます。

5   Python Expression Substitution (${expr})

5   Pythonの式による置換 (${expr})

Attributes not belonging to the Kid namespace and text content MAY embed Python expressions by enclosing the expression within a dollar sign followed by curly braces: ${expr}. The result of evaluating the expression(s) is substituted with the rest of the attribute value or text content following rules defined for Content Producing Constructs.

Kidの名前空間に存在していないアトリビュートや,テキストの内部を動的に置換するためには,Pythonの式を埋め込むと良いでしょう。Pythonの式は,ドル記号の後に大括弧で囲み埋め込みます。置換の結果は,「コンテンツを生成するための構造」に記述したものに準じます。

<?python
verb = 'ran'
noun = 'store'
?>
<a title="I ${verb} to the ${noun}">...

この例は以下のようになります:

<a title="I ran to the store">...

If an attribute value consists purely of substitution expressions and all expressions evaluate to None, the attribute is removed. This can be avoided by using expr or '' to force a zero length string to be returned instead of None. For example:

アトリビュートの値がPythonの式のみで記述されていて,Pythonの式がNoneだった場合には,アトリビュートを削除します。この動作は,強制的に長さゼロの文字列('')を返すようにすることで防げます。以下が例です。

<?python
# set something to None
x = None
?>
<a title="${x}">...

この例は以下のようになります:

<a>...

一方,次の例は:

<?python x = None?>
<a title="${x or ''}">...

以下のように出力します:

<a title="">...

5.1   Identifier Shortcut ($name)

5.1   識別子を埋め込む ($name)

For simple expressions consisting entirely variable names and object access operators (.), the curly braces may be omitted:

変数名やオブジェクトアクセスのドット記号を含む場合は,大括弧を省略できます。

<a href="http://example.com/$page" title="$title">
   「ドット」も記述できます: $object.another.attribute
</a>

However, it is good practice to use the curly brace form as it sets the substitution off from the other text a bit more providing a stronger visual clue as to what's going on.

しかしながら,他の文字列から置換を行うPythonの式を明確に区切りたいとき,見た目で何が起こっているかを分かりやすくするためには,大括弧を使うのもよいでしょう。

5.2   Escaping ($$)

5.2   エスケープ ($$)

$$ is an escape. $${bla} will output ${bla}.

$$はエスケープに利用できます。"$${bla}" は "${bla}" という文字列を出力します。

6   Default Imports

6   デフォルトで利用できるモジュール

All templates have a few default imports for convenience.

全てのテンプレートには,デフォルトで利用できるモジュールがあります。

6.1   XML() function

6.1   XML() 関数

Python Expression substitution, py:content, and py:replace encode strings as text. That is, text is encoded according to the rules of the XML specification, which includes, among other things, replacing the literal characters < and & with their encoded counterparts (&lt; &amp;). If you have XML stored as a string and want it to be output as XML and not encoded text, you need to pass the string to the XML function.

Pythonの式による置換,py:content,およびpy:replaceは文字列をテキストとしてエンコードします。テキストはXMLの仕様に従ってエンコードされますので,"<"や"&"といった記号は実体参照文字列に置換されます。文字列としてXML自体を保持していて,テキストとしてではなくXMLとして出力したい場合,XML関数を通す必要があります。

For example, let's say there is a function, hello, that returns XML data that should be embedded in template output (let's say it returns <hello>world</hello>). Consider the following:

例えば,helloという関数があり,その関数はテンプレートに埋め込む(<hello>world</hello>のような)XMLテータを返すとしましょう。以下のようにするとどうなるでしょうか。

<p>${hello()}</p>

The result would be:

結果は以下のようになります:

<p>&lt;hello>world&lt;hello></p>

Calling the XML function would have given us the result we intended:

XML関数を呼ぶことで,望むような結果を得ることができます:

<p>${XML(hello())}</p>

<p><hello>world</hello></p>

6.2   document() function

6.2   document() 関数

The document function loads an XML document from a file or URL allowing it to be embedded in template output:

document関数はXML文書をファイルやURLから読み込み,テンプレートに置換して出力します:

<div py:content="document('header.html')"></div>

The document function resolves paths relative to the current template file (if the template location is available).

document関数は,テンプレートファイルがあるパスから相対的にパスを解釈します(テンプレートのパスが存在する場合)。

6.3   defined(name) and value_of(name, default) functions

6.3   defined(name) と value_of(name, default) 関数

defined returns True if the name exists in the Kid namespace. value_of returns either the named value or the optional default value if that name doesn't exist in the namespace. These two simple convenience functions may be more intuitive to many than hasattr(self, name) and getattr(self, name, default) which are exactly equivalent.

defined関数は,Kidの名前空間に引数として渡した名前(name)が存在していれば真を返します。value_of関数は,引数として渡した名前(name)の値を返します。名前空間に名前(name)が存在しなかった場合は,オプション引数のデフォルト値(default)を返します。二つのシンプルで便利な関数は,Pythonの組み込み関数hasattr(self,name)やgetattr(self,name,default)と同じ機能を提供していますが,より直感的に利用できます。

7   Attribute Language

7   アトリビュート言語

7.1   Repetition/Iteration (py:for)

7.1   繰り返し/イテレーション (py:for)

<element py:for="target_list in expression_list" />

Works exactly like the Python for statement.

上記のコードはPythonのfor文とまったく同じ動作をします。

The py:for attribute may appear on any element to signify that the element should be processed multiple times, once for each value in the sequence specified:

"py:for"アトリビュートは複数回評価したいエレメントに記述します。シーケンスが持つ値についてそれぞれ繰り返しを行います。

<?python
bottles = range(1, 101)
bottles.reverse()
?>
<p py:for="num in bottles">
   <span py:content="num">X</span> 本のビール瓶が床にあります,
   一本飲み干し,片づけると<span py:content="num - 1">X - 1</span>
   本になります。
</p>

The py:for attribute is the first attribute to be processed if present. All other py: attributes are processed for each iteration of the loop.
7.2   Conditionals (py:if)

"py:for"アトリビュートは,一番最初に評価するアトリビュートです。他のpy:アトリビュートは,繰り返しの最中に毎回評価 します。

7.2   Conditionals (py:if)

7.2   条件分岐 (py:if)

<element py:if="expr" />

The py:if attribute may appear on any element to signify that the element and its decendant items should be output only if the boolean expression specified evaluates to true in Python:

"py:if"アトリビュートは,式が真になった場合にのみ出力したいアトリビュートに記述します。子供のエレメントも表示/非表示の影響を受けます。:

<p py:if="5 * 5 == 25">
  Pythonは正しくかけ算を行えるようだ
</p>

The py:if attribute is processed after the py:for attribute and is evaluated for each iteration. If the result of evaluating expr as a boolean expression is false in Python, no further py: attributes are processed for the current iteration or, if not in a py:for, at all.

"py:if"アトリビュートは"py:for"アトリビュートの後に評価し,繰り返しの最中に毎回評価します。評価結果がPythonで偽として扱われる値の場合,これ以上"py:"アトリビュートの評価を行いません。

Note

注意

Evaluated as a boolean expression in Python, None, False, [], (), {}, 0, and '' are all considered to be false.

Pythonでは,None,False,[],(),{},0や''はすべて偽と見なされます。

7.3   Dynamic Content (py:content)

7.3   動的コンテンツ (py:content)

<element py:content="expr" />

This attribute MAY appear on any element to signify that the decendant items of the element are to be replaced with the result of evaluating expr.

このアトリビュートは,Pythonの式として評価した結果を,子供のエレメント部分に入れ替えたい場合にエレメントに記述します。

<p py:content="time.strftime('%C %c')">The Time</p>

Results in:

上記のコードは以下のように出力します:

<p>Tues, Jun 26, 2004 02:03:53 AM</p>

py:content is a Content Producing Construct and can output both character and structured data.
7.4   Replacing Content (py:replace)

"py:content"は「コンテンツを生成するための構造」のひとつです。文字列と構造のあるデータを出力できます。

7.4   Replacing Content (py:replace)

7.4   コンテンツの置換 (py:replace)

<element py:replace='expr' />

py:replace is shorthand for specifying a py:content and a py:strip="True" on the same element:

"py:replace"を使うと,"py:content"と"py:strip="True""を同じエレメントに表記した場合と同じ挙動を,より短く記述できます:

<?python
x = 10
?>
<p><span py:replace="x">...</span></p>

... results in:

上記コードは以下のように出力します:

<p>10</p>

... and is equivelant to specifying:

また,次のコードと同じになります:

<?python #
x = 10
?>
<p><span py:strip="" py:content="x">...</span></p>

The py:replace attribute is processed after the py:for and py:if attributes. py:strip and py:content attributes are not processed and are discarded.

"py:replace"アトリビュートは,"py:for"や"py:if"アトリビュートの後に評価します。"py:strip"と"py:content"アトリビュートは評価されず,無視されます。

py:replace is a Content Producing Construct and can output both character and structured data.
7.5   Stripping Tags (py:strip)

"py:replace"は「コンテンツを生成するための構造」のひとつです。文字列と構造のあるデータを出力できます。

7.5   Stripping Tags (py:strip)

7.5   タグを省略する (py:strip)

<element py:strip="expr" />

The py:strip attribute may apppear on any element to signify that the containing element should not be output. If the attribute value is blank (no expr at all) or if the result expr is a boolean expression that evaluates to true, the element is not output, but all descendant elements are processed normally. If expr is not blank and the result of evaluating expr as a boolean expression is false, processing continues as if the attribute did not exist.

"py:strip"アトリビュートは内包するエレメントを出力から除外したい場合に,エレメントに記述し利用します。アトリビュートの値が空白(式を書かない)であるか,式を評価して真だった場合に,エレメントを出力しません。続くエレメントは通常通り評価します。もし式が空白でなく,評価した値が偽の場合は,アトリビュートを無視して評価を続けます。

The py:strip attribute MAY appear on an element with any other kid attribute. However, if both a py:replace and a py:strip exist on the same element, the py:strip attribute is ignored and discarded.

"py:strip"アトリビュートは他のkidアトリビュートを伴って記述します。"py:replace"と"py:strip"が同じエレメントにある場合は,"py:strip"アトリビュートは無視します。

The py:strip attribute is processed after the py:for and py:if attributes. If omission is eminent, the py:content attribute is processed normally but attribute interpolation does not occur.

"py:strip"アトリビュートは"py:for"と"py:if"の後に評価します。"py:strip"が機能した場合でも,"py:content"アトリビュートは機能します。ただし,アトリビュート(タグ)自体は出力されません。

7.6   Dynamic Attributes (py:attrs)

7.6   動的なアトリビュート置換 (py:attrs)

<element py:attrs="expr" />

The py:attrs attribute may appear on any element to specify a set of attributes that should be set on the element when it is processed. The expression specified MUST evaluate to one of the following types of values:

"py:attrs"アトリビュートは,エレメント中のアトリビュートを変更したい歳に利用します。式は次に挙げるうちのどれかである必要があります:

dict
    A dictionary with keys specifying attribute names and values specifying attribute values. These are added to the attributes of the current element by calling element.attrib.update(mapping), where element is an ElementTree Element object and mapping is the dictionary returned from the expression. Outer curly braces are not necessary to write down.

辞書(dict)
    アトリビュート名と値を記述した辞書(dictionary)。辞書に記載された内容をもとに,"py:attrs"の置かれたエレメントに対しアトリビュートの置き換えを行います。大括弧({,})は省略することができます。

list
    A list of tuples of the form (name, value) is also acceptable. Each item of the list is added to the current set of attributes by iterating over the list and calling element.set(name, value).
keyword arguments

リスト
    アトリビュート名と値の組となるタプルのリストを記述することもできます。リストを元に,"py:attrs"の置かれたエレメントに対しアトリビュートの置き換えを行います。

keyword arguments
    The attributes can also be specified as comma separated keyword arguments of the form name=value.

キーワード引数
    カンマ区切りのキーワード引数でアトリビュートを指定することもできます。「名前=値」のように記述します。

The following lines:

以下が記述の具体例です:

<elem py:attrs="{'a':1, 'ns:b':2}" />
<elem py:attrs="'a':1, 'ns:b':2" />
<elem py:attrs="(('a',1), ('ns:b',2))" />
<elem py:attrs="a=1, ns:b=2" />

will all produce the same output:

上記の例は,どれも次のような出力になります:

<elem a="1" ns:b="2" />

Note that attributes whose values are None will be removed. If a blank attribute is desired, an empty string should be used.

アトリビュートの値としてNoneが指定されると,アトリビュート自体が削除されますので注意が必要です。空のアトリビュートを挿入したい場合は,空の文字列('')を利用して下さい。

If the expression specified is an empty dictionary or an empty list, the attributes are not modified in any way.

アトリビュートの値に相当する部分が空の辞書,または空のリストの場合は,アトリビュートの変更は行われません。

py:attrs is a Content Producing Construct, but can output only character data.

"py:attrs"は「コンテンツを生成するための構造」ですが,文字列データのみを出力します。XMLのエレメントやタグを含む構造は出力しません。

7.7   Named Template Functions (py:def)

7.7   テンプレート関数 (py:def)

<element py:def="template_name(arg_list)" />

The py:def attribute may appear on any element to create a "Named Template Function". Markup contained within an py:def element is not output during normal template expansion but can be referenced from other Content Producing Constructs to insert the markup at the point referenced.

"py:def" アトリビュートは「テンプレート関数」を作成したいエレメントに設置します。"py:def"の存在するエレメントが内包するエレメントは,通常出力されません。別の「コンテンツを生成するための構造」から呼び出されたときに,マークアップとして出力されます。

Like normal Python functions, Named Template Functions have an optional argument list that may use all of the jazzy features of Python argument lists like variable and keyword arguments.

通常のPython関数と同様,テンプレート関数には変数やキーワード引数を渡すことができます。

Named Template Functions are invoked exactly like normal Python functions. They are generally invoked from Content Producing Constructs like py:content or ${} substitution.

テンプレート関数は,通常のPython関数と同じように呼び出されます。"py:content"のような「コンテンツを生成するための構造」から呼び出されることが多いでしょう。

Here we will define two Named Template Functions: display_list and display_dict. The first function takes a sequence and the second a mapping. We can invoke these functions from the same template by invoking them from a content producing construct:

テンプレート関数は以下のようにして定義します。以下の例では,"display_list"と"display_dict"という関数を定義しています。display_list関数はシーケンスを引数にとり,display_dict関数は辞書を引数に取ります。同じテンプレート内にある「コンテンツを生成するための構造」から呼び出すことができます:

<html xmlns:py="http://purl.org/kid/ns#">
   <body>
      <ul py:def="display_list(seq)">
         <li py:for="item in seq" py:content="item" />
      </ul>

      <table py:def="display_dict(mapping)">
         <tr>
            <th>Key</th>
            <th>Value</th>
         </tr>
         <tr py:for="key, value in mapping.items()">
            <td py:content="key" />
            <td py:content="value" />
         </tr>
      </table>

      ${display_list(['apple', 'orange', 'kiwi'])}

      <div py:replace="display_dict({'x' : 'y', 'p' : 'q'})">
         Key/Value Table replaces this text
      </div>
   </body>
</html>

Serialized as XML this becomes something like:

XMLとして評価すると,以下のような出力になります:

<?xml version="1.0" encoding="utf-8"?>
<html>
   <body>
      <ul>
         <li>apple</li><li>orange</li><li>kiwi</li>
      </ul>
      <table>
         <tr>
            <th>Key</th>
            <th>Value</th>
         </tr>
         <tr>
            <td>x</td>
            <td>y</td>
         </tr>
         <tr>
            <td>p</td>
            <td>q</td>
         </tr>
      </table>
   </body>
</html>

7.8   Match Templates (py:match)

7.8   マッチテンプレート (py:match)

<element py:match="expr" />

The py:match attribute may appear on any element to create a "Match Template". Markup contained within a Match Template element is not output during normal template expansion. Instead, these constructs set up filters for expansion output that are capable of transforming content as it is generated.

"py:match" アトリビュートは「マッチテンプレート」を作成したい場所に設置します。マッチテンプレートが内包するマークアップは通常出力されません。その代わり,コンテンツを出力するためのフィルタを作成します。

Match Templates are generally used to insert content dynamically based on patterns in template expansion or to provide "custom tag" functionality similar to that found in JSP taglibs or XSLT.

マッチテンプレートは,特定のパターンを持ったコンテンツを動的にテンプレートに埋め込む目的で利用されます。JSPのtablibsやXSLTにある「カスタムタグ」のようなものです。

A Match Template has two parts: the match expression part (expr) and the body part (the element and it's descendants).

マッチテンプレートには,「マッチ式」と「本文("py:match"のあるエレメントと内包するエレメント)」という二つのパートから構成されています。

Match Templates are processed as follows:

マッチテンプレートは以下のように処理されます:

   1. Each element that is output from a template goes through the Match Template Filter.
   2. The Match Template Filter visits each of the Match Templates defined in the current template and the templates the current template extends in the order that they are defined and evaluates the associated match expression.
   3. If the match expression returns true as a boolean expression, the match template's body is expanded and replaces the original element and all of its descendants.

   1. テンプレート上の個々のエレメントが,マッチテンプレートのフィルタを通ります
   2. マッチテンプレートのフィルタは,現在利用しているテンプレート,および呼び出しているテンプレート上に定義されているマッチテンプレートを調べ,評価します
   3. 「マッチ式」が真を返した場合,マッチテンプレートを出力し,エレメント,および内包するエレメントを置き換えます

In both the match expression and in the match template's body, the item name is bound to the Element that is being output. However, there are some limitations to what can be accessed at each phase:

マッチ式,およびマッチテンプレートの内部では,出力しようとしているエレメントにアイテム名をバインドします。ただし,個々のフェーズでアクセスできるものについては制限があります。:

   1. During match expression evaluation, only the item Element and none of its descendants are available. This means that match expressions are limited to testing matches based on the immediate Element's tag and attributes [1].

   1. マッチ式を評価中は,アイテムの要素のみが利用でき,内包する要素は利用できません。マッチ式では,テスト用にエレメントのタグとアトリビュートしか利用できないということを意味しています(注:1)。

   2. During match template expansion (that is, when the match expression is true), the element's descendants are available and may be referenced from Content Producing Constructs to output bits and pieces of the matched items structure.

   2. マッチテンプレートを展開中(マッチ式が真だったとき),エレメントが内包するエレメントを利用でき,文字列などを出力するために「コンテンツを生成するための構造」から利用できます。

[1]	This is due to the streaming nature of the Kid processor. During normal template expansion, the entire tree is never fully retained in memory.

(注:1)	この制限は,Kidプロセッサの処理の流れから来ています。通常のテンプレートを展開中は,テンプレート上のすべてのツリーがメモリ上にあるわけではないのです。

7.8.1   Example

7.8.1   例

The following simple example shows how to create a custom tag <greeting> that outputs one of two provided values based on the time of day the template is expanded:

以下に,カスタムタグを作るための簡単な例を示します。<greeting>というタグは,タグに提供されている2つの値のうち,ひとつ時間によってを選び,出力します。

<?xml version="1.0" encoding="utf-8"?>
<?python
from time import localtime
def timeofday():
    """Get time of day ('am' or 'pm')"""
    return localtime().tm_hour < 12 and 'am' or 'pm'
?>
<html xmlns:py="http://purl.org/kid/ns#">
  <!-- define the greeting match template -->
  <span py:match="item.tag == 'greeting'"
        py:replace="item.get(timeofday())">
  </span>

  <head>
    <title>Time of day demo</title>
  </head>
  <body>
    <p>
      Good <greeting am="Morning!" pm="Afternoon" />
    </p>
  </body>
</html>

An important thing to note is that the py:match expression and the match template body have access to the <greeting> element via the variable item. The item.get(timeofday()) bit retrieves the value of the am attribute or the pm attribute based on what is returned from the timeofday function.

"py;match"の式とマッチテンプレートの本文は<greeting>のエレメントにアクセスしているという点に注目して下さい。"item.get(timeofday())"という部分が,timeofday関数に基づいて,'am'アトリビュート,または'pm'アトリビュートを取得しています。

At 9:00 AM, output from this template would look like this:

午前9:00には,出力は以下のようになります。

<html>
  <head>
    <title>Time of day demo</title>
  </head>
  <body>
    <p>
      Good Morning!
    </p>
  </body>
</html>

The obvious question at this point is how to reuse Match Templates? The example above demonstrates the use of a Match Template from the same main template but it is often desirable to have "libraries" of Match Templates that could be used by multiple individual templates. The answer is to have the main template extend a common template containing the Match Templates needed. We can rewrite the above example as two separate templates: main.kid and common.kid.

マッチテンプレートを再利用するためにはどうすればいいか,という疑問を持たれる方がいるかも知れません。上の例では,メインテンプレート上にマッチテンプレートを定義し,利用していますが,マッチテンプレートのライブラリを用意し,他のテンプレートから利用したい場面が多いはずです。マッチテンプレートを定義したテンプレートを読み込んで("extend")利用するとよいでしょう。上の例を以下のように,main.kidとcommon.kidという複数のテンプレートに書き換えてみましょう。

The common template would look like this:

"common.kid"テンプレート以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<?python
from time import localtime
def timeofday():
    """Get time of day ('am' or 'pm')"""
    return localtime().tm_hour < 12 and 'am' or 'pm'
?>
<html xmlns:py="http://purl.org/kid/ns#">
  <!-- define the greeting match template -->
  <span py:match="item.tag == 'greeting'"
        py:replace="item.get(timeofday())">
  </span>
</html>

"main.kid"テンプレートは以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<html py:extends="'common.kid'">
  <head>
    <title>Time of day demo</title>
  </head>
  <body>
    <p>
      Good <greeting am="Morning!" pm="Afternoon" />
    </p>
  </body>
</html>

When a template extends another template (or set of templates), all of the Match Templates and Named Template Functions of the extended templates are available as if they were defined locally.

別のテンプレートを読み込む際,すべての読み込んだテンプレートに定義されたマッチテンプレートとテンプレート関数はテンプレート内で定義されたのと同じように利用できます。

Warning

注意

Match templates are an experimental feature. Syntax and semantics may change significantly or be removed entirely in future release. Actually, this statement applies to many aspects of Kid but this one is especially unstable.

マッチテンプレートは実験中の機能です。将来のリリースでは,文法や記法が大幅に変更されたりすべて削除される可能性があります。この機能はKidの仕様に矛盾しませんが,とりわけ不安定です。

7.9   Template Reuse (py:extends)

7.9   テンプレートの再利用 (py:extends)

<root py:extends="template1, template2, ...">

The py:extends attribute may appear on the root element to specify that the template should inherit the Named Template Functions and Match Templates defined in another template (or set of templates). If a py:extends attribute is specified, it MUST be on the root element of the document.

"py:extends"アトリビュートは,ルートエレメントに設置し,他のテンプレートに定義されているテンプレート関数やマッチテンプレートを利用したい場合に利用します。"py:extends"は,必ずルートエレメントに設置する必要があります。

The py:extends may contain a list of Python expressions separated by commas that reference templates. The rules for what types of values may be specified are:

"py:extends"には,他のテンプレートを参照するPython式のリストをコンマ区切りで記述します。記述できるPython式のルールは以下です。

string

文字列

    The name of a template file, relative to the current template file.

    Example:

    テンプレートファイルの名前を文字列で記述します。パスは,現在のテンプレートからの相対パスとして解釈されます。

    以下が例です。:

    <html py:extends="'common.kid'" />

module or Template class

モジュール,またはテンプレートのクラス

    The py:extends variable references a module or a Template class. If a module is referenced, an attempt is made to find a class named Template belonging to the that module.

    "py:extends"の変数はモジュール,またはテンプレートのクラスを参照します。モジュールが参照されると,モジュールに属するテンプレートを探すよう試みます。
    
    Example:

    以下が例です:

    <?python
    import common
    ?>
    <html py:extends="common" ...

Multiple templates may be referenced by separating each by a comma. The following example references templates common and forms, imported using the import hooks and a template filename named other.kid:

カンマ区切りで複数のテンプレートを記述できます。以下の例では,commonとformsという2つのテンプレートを参照し,'other.kid'というテンプレートを読み込みます。:

<?python
import common, forms
?>
<html py:extends="common, forms, 'other.kid'" ...

7.9.1   Example

7.9.1   例

For example, there is a template named common.kid that defines a template function, display_errors, and a match template that converts <b> elements to <strong> elements with uppercase content:

"common.kid"という名前のテンプレートがあるとします。このテンプレートにはdisplay_errorsというテンプレート関数が定義されています。また,<b>エレメントのコンテンツを大文字にしつつ,<strong>エレメントに変換するマッチテンプレートが定義されています。

<html xmlns:py="http://purl.org/kid/ns#">

  <ul py:def="display_errors(errors)">
    <li py:for="error in errors" py:content="error" />
  </ul>

  <strong py:match="item.tag == 'b'"
    py:content="item.text.upper()" />

</html>

The functions and match templates may be imported into another template by referencing them with py:extends:

"py:extends"から参照することで,テンプレート関数とマッチテンプレートを別のテンプレートに取り込むことができます。

<html py:extends="'common.kid'"
      xmlns:py="http://purl.org/kid/ns#">
  <head>
    <title>Errors</title>
  </head>
  <body>
    <p>The following <b>errors</b> were found:</p>
    ${ display_errors(["Field is required", "Must be phone number.."]) }
  </body>
</html>

The <b>errors</b> item is transformed to <strong>ERRORS</strong> and the error list is displayed. Both the match template and the named template function are available in the derived template as if they were defined locally.

<b>errors</b>というアイテムは<strong>ERRORS</strong>に変換されて出力され,エラーのリストが出力されます。マッチテンプレートとテンプレート関数は,ローカルに定義されているのと同じように,参照されたテンプレート上で利用できます。

7.10   Layout Templates (py:layout)

7.10   レイアウトテンプレート (py:layout)

<root py:layout="base_layout">

The py:layout attribute may appear on the root element to specify that a content template should use the referenced template as a layout template. This allows separation of individual page content from site-wide layout elements such as headers, menus, footers, etc. Match Templates, Named Template Functions, and layout parameters defined in a content template will be applied to the layout template. If a py:layout attribute is specified, it MUST be on the root element of the document.

"py:layout"アトリビュートは,ルートエレメントに設置し,テンプレートのコンテンツをレイアウトテンプレートとして利用したい際に利用します。レイアウトテンプレートを使うと,ヘッダ,メニューやフッタといった個々の部品をページから切り離すことができるようになります。レイアウトテンプレートの内部では,マッチテンプレートやテンプレート関数,テンプレート中に定義されたレイアウトパラメーターを利用できます。"py:layout"アトリビュートは,必ずルートエレメントに設置する必要があります。

The py:layout attribute may contain a single Python expression that references a layout template. The rules for what types of values may be specified are:

"py:layout"アトリビュートはレイアウトテンプレートを参照する単一のPython式から構成されます。Python式のルールは以下になります:

string

文字列


    The name of a template file, relative to the current template file.

    Example:

    <html py:layout="'base_layout.kid'" />

    テンプレートファイルの名前を文字列で記述します。パスは,現在のテンプレートからの相対パスとして解釈されます。

    以下が例です。:

    <html py:layout="'base_layout.kid'" />


module or Template class

モジュール,またはテンプレートのクラス

    The py:layout variable references a module or a Template class. If a module is referenced, an attempt is made to find a class named Template belonging to the that module.

    "py:layout"の変数はモジュール,またはテンプレートのクラスを参照します。モジュールが参照されると,モジュールに属するテンプレートを探すよう試みます。

    Example:

    <?python
    import base_layout
    ?>
    <html py:extends="base_layout" ...

7.10.1   Example

7.10.1   例

For example, here is a base template named base_layout.kid that contains header, content, and footer sections:

base_layout.kidというテンプレートがあるとします。このテンプレートには,ヘッダ,コンテンツ,フッタのセクションがあります。

<html xmlns:py="http://purl.org/kid/ns#">

  <head>
    <title>App Name - ${page_title}</title>

    <link href="layout.css" type="text/css" rel="stylesheet" />
    ${page_specific_css()}
  </head>

  <body>
    <h1>Now viewing: ${page_title} of App Name</h1>

    <content>Default content</content>

    <div class="footer">Page Footer Text</div>
  </body>

</html>

Note how some sections were left to be filled in by the content template. Page-specific functions, match templates, and layout parameters may be defined in a separate template and then applied to the base template with py:layout:

いくつかのセクションは置換されずに残ることに注意して下さい。ページ固有の関数,マッチテンプレート,レイアウトパラメータは別のテンプレートに定義し,"py:layout"を使ってベーステンプレートを割り当てます。

<?python
layout_params['page_title'] = "Content Page 1 of 10"
?>
<html py:layout="'base_layout.kid'"
      xmlns:py="http://purl.org/kid/ns#">

  <link py:def="page_specific_css()"
    href="layout.css" type="text/css" rel="stylesheet" />

  <div py:match="item.tag == 'content'">
    <ul>
      <li>Content Item 1</li>
      <li>Content Item 2</li>
      <li>Content Item 3</li>
    </ul>
  </div>

</html>

Both the match template and the named template function are applied to the base layout template when the content template is rendered. Also note how the page_title is inserted into the layout_params dict. Items placed in layout_params are passed to the base layout template along with template keyword arguments. The layout_params dict can only be modified in the outer python block before the root element in the page.

マッチテンプレートとテンプレート関数は,テンプレートをレンダリングする際に,ベースとなるレイアウトテンプレート上に適用されます。また,テンプレートのタイトルがレイアウトパラメータに指定されていることにも注目して下さい。layout_paramsに指定された値は,テンプレートのキーワード引数と一緒にベースとなるレイアウトテンプレートに渡されます。layout_paramsという辞書(dictionary)はルートエレメントのPythonブロックでのみ変更できます。

8   Processing Order

8   処理の順番

The order that py: attributes are processed is as follows:

"py:"アトリビュートが処理される順番は以下になります。

   1. py:def
   2. py:match
   3. py:for
   4. py:if
   5. py:replace
   6. py:strip
   7. py:attrs
   8. py:content

Attribute substitution occurs after all other attributes are processed and MUST NOT be processed for py: attributes.

アトリビュートの置換("py:attr)は,より高位のアトリビュートの後に実行されます。"py:"アトリビュート自体を置換することはできません。

9   XML Comments

9   XMLコメント

Kid templates may contain XML comments. The comments will appear in the serialized output of a template, but will not be processed by the Python Expression Substitution rules.

KidテンプレートにはXMLのコメントを記述できます。コメントはテンプレートの出力に現れますが,Python式は評価されません。

<!--this is a comment-->
<!-- and so is this -->

Sometimes it is useful to have comments in a template that will not appear when the template is serialized. To do this simply prefix the comment text with a ! character.

出力時には現れないようなコメントを使えると便利な場面もあるでしょう。コメント文字列の先頭に感嘆符(!)を置くと,コメント部分はレンダリング時に出力されません。

<!--!this will not be serialized-->
<!-- !this will also not be serialized -->

10   Revision History

10.1   Revision 5 (Kid v0.9)

    * Add py:layout.

10.2   Revision 4 (Kid v0.6)

    * Add py:extends.
    * Add py:match.
    * Add py:attrs.
    * py:omit renamed py:strip.
    * Kid namespace changed from http://nabelis.cx/ns/kid# to http://purl.org/kid/ns#.
    * Removed requirement of <?python?> blocks to start with a comment.
    * Expression substitution syntax changed from {} to ${}.

10.3   Revision 3 (Kid v0.5)

    * Changed processing instruction from <?kid?> to <?python?>.
    * Changed namespace prefixes from kid: to py:.

10.4   Revision 2

    * Added detail for each attribute on when it is processed in relation to other attributes and whether the result of other attributes modify behavior.
    * Fixed a few minor typos and grammatical issues.
    * Added editorial notes where things are a bit shaky.

10.5   Revision 1

    * Initial public version.

Pythonな求人
r = urlopen("http://www.webcore.co.jp/recruit")
About this blog
■Author
atsこと柴田淳です。Atsushiはガイジンにうまく発音して頂けないので,これからはJunというペンネームで行こうと思っていましたがあんまり使ってません。
Webcore株式会社 代表取締役
■TRIVIAL TECHNOLOGIES 2.0
トリビアル・テクノロジー 2.0,「トリテク 2.0」と呼んでください。
Blog(ブログ)サイトです。Plone上で動く,オープンソースのBlog Product - COREBlog2を使っています。
 
最近書いた本,Mook
みんなのPython Webアプリ編
Pythonの基礎から,Webアプリやフレームワークの仕組みまで,つまることなく一気に学べる書籍です。「みんなのPython」と一緒に読んでください:-)。
みんなのPython
Pythonの入門書です。基本的なことから分かりやすく解説するよう勤めました。Pythonをはじめたいと思っている人,JavaやC++,PerlやRubyを学ぼうと思って躓いてしまった人はぜひ読んで下さい。
 

Powered by Plone, the Open Source Content Management System