Tales Programming Guide
Examples of TALES syntax
TALES Quick Guide
This is a quick refence guide to learn and use TALES, I think it stands for Template Attribute Language Expression Syntax or something like that.
Other CMF frameworks use this syntax so learning this is not simply an excercise in esoteric Plone incantations.
Quick Syntax Introduction
TALES adds it own special attributes to normal htmltags to provide a template language. The attributes then render the expressions inside these new tags according to the rules of the language.<htmltag attribute="expresion">This is the basic syntax.</htmltag>
<title tal:content="root/Members/kurt/mypictures/title">My personal title for mypictures will go here</title>
<a href="#" tal:attribute="href string: http://www.google.com">Click to Search Internets. The Google url will replace href="#"</a>
<i tal:omit-tag="python: context.checkpreference('itialics')">Let this python object figure out it we really want these itialics.</i>
<b tal:replace="string: I am a xml compliant short tag" />
I will talk about attributes and expressions soon, but let me talk quickly about paths(which are special types of expressions) and the concept of acquisition. Then I will show detailed examples of TALES Attributes and TALES Expressions.
Paths
Paths look like normal file system paths or url paths and use '/', but there is a subtle difference. Under ZOPE/Plone, these are not real filesystem paths, but internal paths within the object database.| root/Members/kurt | My user folder |
| context/absolute_url | The absolute url of the current context(page) |
| request/Name | The variable "Name" from a post/get request string |
| context/title | The title of the current context |
Aquisistion
Within this concept of paths there is the powerful concept of acquisistion. If a object at the end of the path does not exist, Plone looks backwards in the path for it.So lets say I just uploaded logo.png to mypictures.
Now lets say some one tries to goto http://meld.gatech.edu/Members/kurt/logo.png/edit
Plone will try the following steps until it finds one or not.
| /root/Members/kurt/pictures/logo.png/edit | This doesn't exist! |
| /root/Members/kurt/pictures/edit | Either does this... |
| /root/Members/kurt/edit | Either does this... |
| /root/Members/edit | Here is one. Use it. |
TALES Attributes
Expressions will be discussed shortly, for now I will show examples of the few attributes TALES uses.content | <i tal:content="expression">This text will by replaced by the expression</i> |
replace | <b tal:replace="expression" /> # This entire bold tag will be completely replaced by the expressio |
attributes | <a tal:attributes="href expression" href="#">A link</a> # The "href" value will be replaced by expression <a tal:attributes="href expression1" tal:content="expression2" href="#">A link</a> # Like above, but "A link" will be replaced by expression2 |
condition | <p tal:condition="expression">If expression is false this entire tag, additional tal:s and this text gets nuked</p> |
on-error | <p tal:on-error="expression1" tal:replace="expression2">This will be replaced if expression1 is an error. Its considered bad style to use this however.</p>bad way: |
define | <p tal:define="myvariable expression> ... <i tal:content="anytalexpression">myvariable can be now accessed by any tal expression between the "p" tags</i> ... </p> |
omit-tag | <p tal:omit-tag="expression">If expression is true then omit this entire tag leaving this text alone</p> |
repeat | <ul tal:repeat="myvariable expression1"> <li tal:content="expression2">"li" will be filled with expression2(which references myvariable) for each object returned by expression1</li> </ul> |
TALES Expressions
Builtin expression variables:
| container | <div tal:content="container">Show what plone container we are in</div> |
| context or here | <div tal:content="context/somesubobject" /> # The root object for the current context |
| default | <div tal:content="context/myobject/default" /> # The default behaviour for myobject, whatever that my be |
| modules | <div tal:content="modules/string/atoi expression" /> A container for imported modules, in this case the default string module's atoi method. |
| nothing | <div tal:condition="nothing" tal:content...>This wont be replaced</div> # This is equvalent to Python's None |
| loop or repeat | <div tal:content="loop" /> # The current object in a tal:repeat(not shown) <li tal:content="loop/item" /> # The "li" will contain the value of "item" in the current "loop" object |
| options | These are the options passed to a template, which occurs when the tem- plate is called from a script or other method, not through the Web. |
| request | <div tal:content="request/HTTP_USER_AGENT">The users browser will go here</div> <b tal:content="request/REMOTE_ADDRR">The users browser will go here</b> <i tal:content="request/variable">The value of 'variable' from the query request string will go here</i> |
| root | For example, root/Control_Panel gives you the control panel for Zope. |
| template | This is this template being called. For example, template/id is the ID of the template being rendered. |
| traverse_subpath | This contains a list of the elements still to be traversed. This is an advanced variable, and it’s recommend you understand traversal and acquisition before using this. |
| user | <b tal:content="user/getUserName">The username of the current user goes here</b> |
| CONTEXTS | <i tal:replace="CONTEXTS" /> # This is a list of most of th above values. |
Path expressions:
These don't require that a default content type is prepended to them, because they are references in some way to the variables defined above.| context/message | <i tal:replace="context/message">Replace this "i" tag with the content in "context/message". message is an object within the context scope.</i> |
| | | <title tal:content="context/folderA/title|context/folderB/title">If a title object exists for contex/folderA, use it. Otherwise use a title object from context/folderB.</title> |
| title | <i tal:replace="title">If title was defined with tal:define="title expression" or tal:repeat="title expression", replace the "i" tag with it's value.</i> |
Nonpath Expressions:
These require a default content type prepended to them so Plone knows where to get them. They are often combined with path expressions.| structure | <i tal:replace="structure context/somehtml">Dont escape the html in somehtml</i> <i tal:replace="structure myvariable">If myvariable has html, replace this entire tag with it and escape html</i> |
| python: | <i tal:replace="python: 1 + 1">Show what 1 + 1 is </i> <i tal:omit-tag="python: 1 + 2 == 3">Remove "i" tag and don't itialicize this text</i> |
| string: | <i tal:content="context/flags/keepenglish|string: Bonjour Monde!">Hello World!</i> |
Programming Expressions:
You should not do any heavy duty programming in tal. These contrusts are limited and shoul rely on underlying logic. If your tal logic gets too complex, you probaby need to refactor your code and put your logic in Script Objects or pthone external methods, and use tal to call them.| not | <b tal:condition="expression">If expression show this</b> <b tal:condition="not: expression">else show this</b> |
| loop / repeat | <ul tal:repeat="myitem context/itemList"> <p>Repeat this text and set myitem to each item in context/itemList<brf /> <li> <p>Name of person inside each item:<div tal:replace="myitem/name" /></p><br /> <p>loop in this context is not a tal attribute, but a object variable set in the local context of a tal:repeat</p> <b tal:content="loop/number">What number of the repeat loop are we on will be put here starting at one.</b> <b tal:content="loop/index">Like number above, but this starts the loop count at zero instead of one. Usefull for programming.</b> <b tal:condition="loop/start">This the start of the list</b><br /> <b tal:condition="loop/end">This is the end of the list</b><br /> <b tal:condition="loop/first">This is the first appearance of this element in the list</b><br /> <b tal:condition="loop/last">This is the last appearance of this element in the list</b><br /> </li> </ul> |

