codemash-tapestry.pdf
DESCRIPTION
TRANSCRIPT
![Page 1: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/1.jpg)
© 2010 Howard M. Lewis Ship
Tapestry 5: Java Power, Scripting EaseHoward M. Lewis Ship
1
![Page 2: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/2.jpg)
© 2010 Howard M. Lewis Ship
Howard Lewis Ship
• Creator, Apache Tapestry
• Author, "Tapestry in Action"
• Independent Consultant
2
![Page 3: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/3.jpg)
© 2010 Howard M. Lewis Ship
What is Tapestry?
3
![Page 4: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/4.jpg)
© 2010 Howard M. Lewis Ship
Java4
![Page 5: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/5.jpg)
© 2010 Howard M. Lewis Ship
Open Source
5
![Page 6: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/6.jpg)
© 2010 Howard M. Lewis Ship
Component Based
6
![Page 7: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/7.jpg)
© 2010 Howard M. Lewis Ship
Developer Focused
7
![Page 8: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/8.jpg)
© 2010 Howard M. Lewis Ship
Convention over
Configuration8
![Page 9: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/9.jpg)
© 2010 Howard M. Lewis Ship
Concise9
![Page 10: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/10.jpg)
© 2010 Howard M. Lewis Ship
Fast!10
![Page 11: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/11.jpg)
© 2010 Howard M. Lewis Ship
Mature11
![Page 12: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/12.jpg)
© 2010 Howard M. Lewis Ship
Tapestry Elements
12
![Page 13: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/13.jpg)
© 2010 Howard M. Lewis Ship
Tapestry Templates
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> <h1>Please Login</h1>
<t:form> <t:label for="userId"/> <t:textfield value="userId"/> <br/> <t:label for="password"/> <t:passwordfield value="password"/> <br/> <input type="submit" value="Login"/> </t:form></html>
Login.tml
Login
form
label
textfield
label
passwordfield
13
![Page 14: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/14.jpg)
© 2010 Howard M. Lewis Ship
Page Classes
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd"> <body> <h1>Please Login</h1>
<t:form> <t:label for="userId"/> <t:textfield value="userId"/> <br/> <t:label for="password"/> <t:passwordfield value="password"/> <br/> <input type="submit" value="Login"/> </t:form></html>
Login.tml
public class Login{ @Property private String userId;
@Property private String password;
Object onSuccess() { … }}
Login.java
14
![Page 15: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/15.jpg)
© 2010 Howard M. Lewis Ship
Page Flows
public class Login{ @Property private String userId;
@Property private String password;
void onValidate() { … }
Object onSuccess() { …
return UserProfile.class; }}
Login.java
public class UserProfile{ … }
UserProfile.java
15
![Page 16: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/16.jpg)
© 2010 Howard M. Lewis Ship
Inversion of Control
public class Login{ @Property private String userId;
@Property private String password;
…
@Inject private Session session;
@CommitAfter Object onSuccess() { …
User user = (User) session. …
user.setLastLogin(new Date());
return UserProfile.class; }}
Login.java
Inject IoC Service into field
Yourcode
Tapestry Services
16
![Page 17: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/17.jpg)
© 2010 Howard M. Lewis Ship
Meta-Programming
public class Login{ @Property private String userId;
@Property private String password;
@InjectPage private UserProfile userProfilePage; …
@Inject private Session session;
@CommitAfter Object onSuccess() { …
User user = (User) session. …
user.setLastLogin(new Date());
return userProfilePage; }}
Login.java
Generate getter & setter
Commit Hibernate transaction
17
![Page 18: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/18.jpg)
© 2010 Howard M. Lewis Ship
State Management
public class UserProfile{ @Property @SessionState private UserEntity user;
@Property @Persist private Date searchStart;
}
UserProfile.java
Shared global value (any page)
This page only
18
![Page 19: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/19.jpg)
© 2010 Howard M. Lewis Ship
Component
Template
Java Class
Message Catalog
Meta-Programming
Injections
19
![Page 20: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/20.jpg)
© 2010 Howard M. Lewis Ship
!Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves."
Alan Kay, co-designer of the Smalltalk programming language
20
![Page 21: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/21.jpg)
© 2010 Howard M. Lewis Ship
Developer Productivity
21
![Page 22: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/22.jpg)
© 2010 Howard M. Lewis Ship22
![Page 23: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/23.jpg)
© 2010 Howard M. Lewis Ship23
Live Class Reloading
![Page 24: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/24.jpg)
© 2010 Howard M. Lewis Ship24
![Page 25: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/25.jpg)
© 2010 Howard M. Lewis Ship
Non-Tapestry Exception Reporting
25
![Page 26: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/26.jpg)
© 2010 Howard M. Lewis Ship
Index does not contain a property named 'now'
Available properties: class, componentResources, currentTime
26
![Page 27: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/27.jpg)
© 2010 Howard M. Lewis Ship27
![Page 28: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/28.jpg)
© 2010 Howard M. Lewis Ship
Scaffolding
28
![Page 29: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/29.jpg)
@Entitypublic class BoardGame{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @NonVisual private long id;
@Validate("required") private String title;
private String creator;
private String publisher;
private Date published;
private boolean inPrint;
@Validate("required") @Column(nullable = false) private Genre genre;
@Validate("required") @Column(nullable = false) private Theme theme;
@Validate("min=1") private Integer minPlayers;
@Validate("min=1") private Integer maxPlayers;
@Validate("min=1,max=5") private Integer rating;
@DataType("longtext") private String notes;
© 2010 Howard M. Lewis Ship
BoardGame.java
29
![Page 30: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/30.jpg)
© 2010 Howard M. Lewis Ship30
![Page 31: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/31.jpg)
© 2010 Howard M. Lewis Ship
Property Types
Naming Conventions
Annotations
Explicit Overrides
Localized Messages
Be
an
Ed
itF
orm
Parameters
31
![Page 32: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/32.jpg)
© 2010 Howard M. Lewis Ship32
![Page 33: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/33.jpg)
© 2010 Howard M. Lewis Ship
Feedback &Exploration
33
![Page 34: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/34.jpg)
© 2010 Howard M. Lewis Ship
Flow
34
![Page 35: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/35.jpg)
© 2010 Howard M. Lewis Ship
!PHP and Rails have taught us that development speed is more important than we thought it was ... you really don’t understand a feature till you’ve built it, so the faster you can build them the faster you understand them."
Tim Bray, Director of Web Technologies, Sun Microsystems
35
![Page 36: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/36.jpg)
© 2010 Howard M. Lewis Ship
Internationalization
36
![Page 37: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/37.jpg)
© 2010 Howard M. Lewis Ship37
![Page 38: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/38.jpg)
© 2010 Howard M. Lewis Ship
page-title=Erstellen Sie eine neue Brettspieladd-game=Spiel hinzufŸgengame-added=Added Brettspiel
modern=Modernenmedieval=Mittelalterbible=Bibelabstract=Zusammenfassung
war_game=Kriegsspielcard=Karterole_playing=Rollenspielecooperative=Genossenschaft
creator-label=Sch!pferpublisher-label=Verlagpublished-label=Ver!ffentlichtinprint-label=Im Drucktheme-label=Themaminplayers-label=Mindest-Spielermaxplayers-label=Maximale Spielernotes-label=Notation
Index_de.properties
<html t:type="layout" title="message:page-title" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter">
<strong>${message}</strong>
<t:beaneditform submitlabel="message:add-game" object="game" />
</html>
Index.tml
38
![Page 39: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/39.jpg)
© 2010 Howard M. Lewis Ship
Tapestry Components
39
![Page 40: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/40.jpg)
© 2010 Howard M. Lewis Ship
Nested Components
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <head> <title>${title}</title> </head> <body> … <div id="menu"> <ul> <li t:type="loop" source="pageNames" value="pageName" class="prop:classForPageName"> <t:pagelink page="prop:pageName">${pageName}</t:pagelink> </li> </ul> </div>
…
Layout.tml
Layout
title : StringpageNames : List
pageName : String
Index
Layout
Loop PageLink
40
Render property pageName
![Page 41: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/41.jpg)
© 2010 Howard M. Lewis Ship
Layout Components
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <head> <title>${title}</title> </head> <body>
. . .
<t:body/>
. . .
</body></html>
Layout.tml
<html t:type="layout" title="message:page-title" xmlns:t="http://tapestry.apache.org/schema/ ↵ tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter">
<t:beaneditform submitlabel="message:add-game" object="game" />
</html>
Index.tml
#
$
%
&
'
41
![Page 42: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/42.jpg)
© 2010 Howard M. Lewis Ship
Component Parameters
public class Layout{ /** The page title, for the <title> element and the <h1> element. */ @Property @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL) private String title;
@Property @Parameter(defaultPrefix = BindingConstants.LITERAL) private String sidebarTitle;
@Property @Parameter(defaultPrefix = BindingConstants.LITERAL) private Block sidebar;
@Property private String pageName;
Layout.java
42
![Page 43: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/43.jpg)
© 2010 Howard M. Lewis Ship
Non-Template Components
public class OutputDate{ private final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
@Parameter(required = true, allowNull = false) private Date date;
void beginRender(MarkupWriter writer) { writer.write(formatter.format(date)); }}
OutputDate.java
43
![Page 44: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/44.jpg)
© 2010 Howard M. Lewis Ship
Component Rendering
Start
SetupRender
BeginRender
Render Template
Render Body
AfterRender
CleanupRender
End
true
falsetrue
true
false
false
false
true
void beginRender(MarkupWriter writer) { writer.write(formatter.format(date)); }
OutputDate.java
44
![Page 45: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/45.jpg)
© 2010 Howard M. Lewis Ship45
![Page 46: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/46.jpg)
© 2010 Howard M. Lewis Ship46
![Page 47: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/47.jpg)
© 2010 Howard M. Lewis Ship47
<t:actionlink t:id="selectGame" context="game" zone="gameDetail"> ${game.title}</t:actionlink>
Games.tml
@Property private BoardGame game, selectedGame;
@InjectComponent private Zone gameDetail;
Object onActionFromSelectGame(BoardGame game) { selectedGame = game;
return gameDetail.getBody(); }
Partial Page Updates
<t:zone id="gameDetail" t:id="gameDetail"> <t:if test="selectedGame"> <strong>${selectedGame.title}</strong> by <strong>${selectedGame.creator}</strong> <br /> For ${selectedGame.minPlayers} - ↵${selectedGame.maxPlayers} players. </t:if></t:zone>
Games.tml
Games.java
.../games.selectGame/3
![Page 48: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/48.jpg)
© 2010 Howard M. Lewis Ship
Encapsulation
48
![Page 49: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/49.jpg)
© 2010 Howard M. Lewis Ship
TapestryPerformance
49
![Page 50: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/50.jpg)
© 2010 Howard M. Lewis Ship
Request Processing Speed
50
![Page 51: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/51.jpg)
© 2010 Howard M. Lewis Ship
Java == Fast
51
![Page 52: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/52.jpg)
© 2010 Howard M. Lewis Ship
No Reflection
52
![Page 53: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/53.jpg)
© 2010 Howard M. Lewis Ship
Page Pooling
53
![Page 54: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/54.jpg)
© 2010 Howard M. Lewis Ship
GZIP Compression
54
![Page 55: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/55.jpg)
© 2010 Howard M. Lewis Ship
Scalability55
![Page 56: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/56.jpg)
© 2010 Howard M. Lewis Ship
JavaScript Aggregation
56
![Page 57: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/57.jpg)
© 2010 Howard M. Lewis Ship
Far Future Expires Header
57
![Page 58: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/58.jpg)
© 2010 Howard M. Lewis Ship
Caching58
![Page 59: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/59.jpg)
© 2010 Howard M. Lewis Ship
Content Delivery Network
59
![Page 60: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/60.jpg)
© 2010 Howard M. Lewis Ship
!Architecture is the decisions that you wish you could get right early in a project."
Martin Fowler, Chief Scientist, ThoughtWorks
60
![Page 61: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/61.jpg)
© 2010 Howard M. Lewis Ship
Conclusion
61
![Page 62: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/62.jpg)
© 2010 Howard M. Lewis Ship62
![Page 63: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/63.jpg)
© 2010 Howard M. Lewis Ship
Infrastructure
63
![Page 64: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/64.jpg)
© 2010 Howard M. Lewis Ship
Performance
64
![Page 65: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/65.jpg)
© 2010 Howard M. Lewis Ship
Tapestry: The Expert is Built In
65
![Page 66: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/66.jpg)
© 2010 Howard M. Lewis Ship
Tapestry 5 In Production
66
![Page 67: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/67.jpg)
© 2010 Howard M. Lewis Ship
http://tapestry.apache.org
67
•Downloads•Mailing Lists•Component Reference•User's Guide•Wiki
![Page 68: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/68.jpg)
© 2010 Howard M. Lewis Ship68
http://jumpstart.doublenegative.com.au/
•Application Skeleton•Detailed tutorials
![Page 69: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/69.jpg)
© 2010 Howard M. Lewis Ship69
http://chenillekit.codehaus.org/
![Page 70: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/70.jpg)
© 2010 Howard M. Lewis Ship
http://github.com/hlship/t5intro
70
![Page 71: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/71.jpg)
© 2010 Howard M. Lewis Ship
http://howardlewisship.com
Tapestry 5 Development and SupportOn-site / Hands-on Tapestry Training
71
![Page 72: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/72.jpg)
© 2010 Howard M. Lewis Ship
Image Credits© 2006 Chris Waltonhttp://www.flickr.com/photos/philocrites/245011706/
© 2010 Nataline Funghttp://www.flickr.com/photos/metaphora/3384569933/
© 2006 Martino Sabiahttp://www.flickr.com/photos/ezu/297634534/
© 2008 Alan Grinberghttp://www.flickr.com/photos/agrinberg/2465119180/
© 2008 Manu Gómezhttp://www.flickr.com/photos/manugomi/2884678938/
© 2006 Tom Maglieryhttp://www.flickr.com/photos/mag3737/267638148/
© 2003 A. Lipsonhttp://www.andrewlipson.com/escher/relativity.html
© 2010 viernesthttp://www.flickr.com/photos/viernest/3380560365/
© 2007 Jojo Cencehttp://www.flickr.com/photos/jojocence/1372693375/
© 2007 Patrick Dirdenhttp://www.flickr.com/photos/sp8254/2052236004/
© 2010 Dani Ihtathohttp://www.flickr.com/photos/ihtatho/627226315/
72
![Page 73: Codemash-Tapestry.pdf](https://reader034.vdocuments.us/reader034/viewer/2022051608/540f02238d7f72927e8b4fba/html5/thumbnails/73.jpg)
© 2010 Howard M. Lewis Ship
Image Credits© 2008 Christophe Delaerehttp://www.flickr.com/photos/delaere/2514143242/
© 2007 Marina Campos Vinhalhttp://www.flickr.com/photos/marinacvinhal/379111290/
© 2006 kris247http://www.flickr.com/photos/kris247/86924080/
73
© Randal Munroehttp://xkcd.com/303/
© 2010 Howard M. Lewis Shiphttp://www.flickr.com/photos/hlship/3388927572/
© 2008 Howard M. Lewis Shiphttp://www.flickr.com/photos/hlship/3107467741/