Excerpt | ||
---|---|---|
| ||
a brief guide for learning Tapestry, designed for those who already know JavaServer Faces (JSF) |
Scrollbar |
---|
This is a brief guide
Wiki Markup |
---|
{scrollbar} |
Tapestry for JSF Users
Wiki Markup |
---|
{float:right|background=#eee}
{contentbylabel:title=Related Articles|showLabels=false|showSpace=false|labels=new-users}
{float} |
This is a cheat sheet for learning Tapestry, designed for those who already know JavaServer Faces (JSF). Excerpt
Because both JSF and Tapestry are component oriented frameworks designed to serve mostly the same kinds of problems in similar ways, developers who already know JSF will find it very easy to learn Tapestry. In fact, Facelets, the default view technology in JSF 2.0, was created specifically to give JSF a Tapestry-like templating capability, so Facelets users should feel right at home.
Div | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
|
Since almost all modern JSF applications use Facelets as their view technology, we assume the use of Facelets here when discussing JSF features.
...
Concepts & Terminology | JSF | Tapestry |
---|---|---|
Java class associated with a page or component | "Backing Bean" | |
Component attributes/parameters | "attributes" | |
Common Attributes/Parameters | JSF | Tapestry |
HTML Attribute used for invisible instrumentation | jsfc="someComponentType" | |
CSS "class" attribute name | styleClass | class |
Alternating "zebra" striped rows | rowclasses="class1,class2" | class="${cycle:class1,class2}" using cycle binding prefix, or with CSS: .rowClass:nth-child(even) {background-color: #e8e8e8;} |
Output and Messages | JSF | Tapestry |
Escaped HTML from property | <h:outputText value="myBean.myValue"/> | ${myValue} |
Raw HTML from property | #{myBean.myValue} | |
Error messages | <h:message> and <h:messages> | <t:error> and <t:errors> (for forms) or <t:alerts> |
Image display | <h:graphicImage> | use standard <img> tag, but see Assets |
Conditionals and Looping | JSF | Tapestry |
Render-time loop | <ui:repeat> | |
Compile-time loop | <c:forEach> | |
Conditional | <c:if test="#{myBean.myValue}"> | |
Conditional | <ui:fragment rendered="#{myBean.someCondition}"/>...</ui:fragment> | |
Switch | <c:choose><c:when ... ></c:choose> | See Switching Cases |
Server-side comment | <ui:remove> | |
Links and Buttons | JSF | Tapestry |
Navigational link | <h:link outcome="nextpage.xhtml"/> | |
Event-triggering link, without form submission | not available | |
Form submission link | <h:commandLink> | |
Form submission button | <h:commandButton> | |
Link to Javascript file | <h:outputScript> | <script> or use @Import in component class |
Link to CSS file | <h:outputStylesheet> | <style> or use @Import in component class |
Grids, Tables and Trees | JSF | Tapestry |
Tabular data in <table> | <h:datatable> | |
Table used for layout | <h:panelGrid> with <h:panelGroup> | use standard <table> tag |
Hierarchical tree | depends on component library | |
Form Tags/Components | JSF | Tapestry |
Form | <h:form> | |
Single-line text input field | <h:inputText> | |
Password field | <h:inputSecret> | |
Select menu | <h:selectOneMenu> | |
Checkbox | <h:selectBooleanCheckbox> | |
Checkbox list | <h:selectManyCheckbox> | |
Radio button list | <h:selectOneRadio> | <t:radioGroup> with <t:radio> |
Multiple select menu | <h:selectManyListbox> | not available (but see Palette and Checklist) |
Hidden field | <h:inputHidden> | |
textarea tag | <h:inputTextarea> | |
Label tag | <h:outputLabel for="..."> |
...
Faces templates and Tapestry templates are superficially quite similar.
Section | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...
- The #{...} syntax in JSF does not encode the underlying string, so you have to use the <h:outputText> tag if your data may contain HTML reserved characters such as <, >, or &. In contrast, the ${...} syntax in Tapestry does encode the underlying string.
- In JSF, backing beans are not necessarily related one-to-one with page templates. Often several templates use the same backing bean, and one template may reference multiple backing beans. In Tapestry, they are always related one-to-one, and therefore you don't have to specify which component class your ${...} expressions are referencing.
Section | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...
JSF uses the Unified Expression Language with the #{...} or ${...} syntax for accessing Backing Bean properties. For its part, Tapestry uses the ${...} syntax with a similar but more intentionally limited expression language called Property Expressions. Both allow easy access to properties via the usual JavaBean conventions, but with Tapestry you don't have to specify which class the expression starts at (because it always starts at the component class corresponding to the template). Some comparisons:
| JSF Syntax | Tapestry Syntax |
---|---|---|
Property (calls getEmployeeName() or setEmployeeName()) | #{employeeBean.employeeName} | ${employeeName} |
Boolean property (calls isHourly() or setHourly()) | #{employeeBean.hourly} | ${hourly} |
Property chain | #{employeeBean.address.street} | ${address.street} |
Null-safe property chain | #{employeeBean.address.street} | ${address?.street} |
5th element in a List | #{employeeBean.employees[5].name} | ${employees.get(5).name} |
Negation | #{! employeeBean.hourly} | ${! hourly} |
Arithmetic & relational operators | +-*/% div mod | not available |
Relational operators | == != ne < lt > gt <= le >= ge | not available |
Ternary operator | #{myBean.foo < 0 ? 'bar' : 'baz'} | not available |
Method calling | #{myBean.employees.size()} | ${employees.size()} |
Iterated Range | not avaialble | ${1..10} |
Iterated Range (calculated) | not avaialble | ${1..groupList.size()} |
List | not available | ${ [ user.name, user.email, user.phone ] } |
Map | not available | ${ { 'id':'4039','type':'hourly' } } |
...
Tapestry applications can use JSR 303 Bean Validation annotations that JSF users should be familiar with:
Code Block | ||
---|---|---|
| ||
public class Employee {
@Validate("required,minlength=2,maxlength=100")
private String lastName;
@NotNull @Email private String email;
|
...
Note that by default Tapestry does not save property values across the Post-Redirect-Get cycle. This means that you have to consider how (and whether) to persist property values from one page to the next. The usual solution is to either make the values part of the page's Activation Context (which means the values will be appended to the URL) or @Persist the properties the values in the session.
...
- JavaServer Faces 2.0 vs. Tapestry 5: A Head-to-Head Comparison slides by Igor Drobiazko, June 2010.
- Composite Components: Advanced Topics and Example part of The Java EE 6 Tutorial from Oracle
...
Scrollbar |
---|