 |
java.net Forums
"Tapestry In Action" is the definitive guide to using the open-source Tapestry
web application framework. This books guides the reader from the fundamentals of Tapestry all
the way through to advanced topics such as packaging components for reuse and managing
client-side JavaScript. The book finishes with an in-depth examination of a complete J2EE
application.
Discussion Moderator:
Howard M Lewis Ship
Showing messages 1 through 20 of 20.
-
stylesheet files
2004-06-09 15:18:53 c_jinx
I'm currently reading the book. Tapestry looks powerfull and I'm playing to learn more. There is one thing I haven't quite figured yet. And it should be trivial, or so I think.
Suppose I have one CSS file for Mozilla browsers and another one for IE browsers. How do I link a different stylesheet file to a web page, depending on the browser used?
-
stylesheet files
2004-06-10 07:28:05 hlship
Well, first off, how are you determining which browser is being used? Let's assume you can trust the headers.
When you use the @Shell component, you can specify a stylesheet parameter.
Normally, you bind stylesheet to a fixed value: ognl:assets.stylesheet
Instead, you need to compute it dynamically:
ognl:stylesheetForBrowser
And in your Java code:
public IAsset getStylesheetForBrowser()
{
if ( ... is IE ...)
return getAsset("IEStylesheet");
if (...is Opera ...)
return getAsset("OperaStylesheet");
... etc. ...
return getAsset("DefaultStylesheet");
}
Of course, you must provide context-asset elements for each of those stylesheet assets.
-
First impressions from Tapestry
2004-06-03 01:14:32 vtec
We have started development of Tapestry based application about 3 weeks ago. This is our first Tapestry project so we are learning on the go both from the new Manning book and sources / debugging. While we are experienced Java/JSP developers (>5years) so far the Tapestry development is very painful.
The framework is incredibly fragile, it does not give us any usefull simplified abstraction. Whenever you implement any Java code callback you must have complete knowledge about the Sequence Diagram of Tapestry Service that would invoke your callback, you have to exactly now Tapestry types of all Component's Parameters you want to access. Some combinations work some do not (it is not a bug it is a feature). Otherwise you may either damage the so called "rewinding" process or get uninitialized parameter values. In other words you have to know all the internals of framework to safely use it.
The framework just gets into your way when robust applicaiton behaviour is required - even the standard Table component is vulnerable to random combination of browsing and back && refresh buttons. The framework by default does not redirects client when serving POST request - so when the client subsequently clicks refresh button in his browser he have to confirm that he wants to repeat the action - and duplicit POST request is handled by server. You have to manualy prevent this by throwing RedirectionExceptions in your callbacks and only that forces Tapestry to send redirect to your client instead of simple forwarding.
Inside the frameworks it is quite obvious to abuse Exceptions in this way - instead of reporting some error condition they are used as normal program flow - it hapens within each request , no matter how expensive is to create new Exception instance(if only singleton instances would be used)!
We will have to use lot of Javascript and DHTML in our application and I am starting to afraid of this in context of Tapestry application.
I just hope the as we are learning more and more details about Tapestry thinks would be easier as the overall architecture of Tapestry seems to be quite smart.
-
First impressions from Tapestry
2004-06-03 10:38:03 stephenh
I'll prefix this by saying that, aside from my awe at a wicked-fast (small) site I did with Struts/Velocity/Prevayler, Tapestry is the best Java web framework around and we will be starting our 3rd project with it soon.
What being said, I have to agree with the vtec's post that the rewinding/callback business in Tapestry is fragile and has a higher-than-expected learning curve. It took me about two weeks to feel like I had mastered it on our first project, but now that I have stepped away, I probably have forgotten it all.
I'll give Tapestry and Howard their due respect, as the rewind/postback problem is indeed a hard problem to solve, and Tapestry goes a long way to solving it much better than any other Java web framework I've seen.
However, I've also used ASP.NET for several projects and it uses a similar rewind/postback idiom that is so smooth and intuitive that it has spoiled me; I've never had it exception out on me for doing the right thing at the wrong time.
I think if the Tapestry developers could watch for common newbie rewind mistakes and have a dead-simple time for when you are supposed to mess with objects in a rewind/postback (e.g. ASP.NET has OnInit -> something like rewinding is done -> OnLoad -> server-side events are done -> OnPreRender -> rendering is done -> OnUnload) and then somehow keep the newbie developer from doing things anywhere in Tapestry's comparable OnInit/OnLoad/OnPreRender/OnUnload hooks that would mess up the complicated rewinding/event/rendering code that is going on behind the scenes, Tapestry would be that much sweeter. My naive hunch is that Tapestry doing both rewinding and events during the same tree traversal is causing the confusion.
(Note, perhaps my last paragraph analysis is horribly wrong, I skipped out on most of our 2nd project so am sketchy on Tapestry internals, this is just my best guess as I remember grasping for the right idiom ~6-8 months ago).
-
First impressions from Tapestry
2004-06-03 06:53:55 hlship
These are interesting comments, but also highly a-typical.
I have not once heard of Tapestry as "fragile".
Dealing with refreshes and the browser back button are painful in any web application ... HTML simply wasn't intended to be used in this way. Even so, Tapestry provides the support needed (Hidden, ListEdit, FormConditional) components to address these complex situations. For the majority of standard forms (which do not use conditionals or loops within a form), these issues simply don't occur.
A token-based approach to eliminating multipe posts has been used succesfully on many Tapestry (and non-Tapestry) projects. Constructing a component for this purpose is quite easy, and an "official" component will likely debut in Tapestry 3.1.
You comment about RedirectException was especially puzzling. Tapestry has the PageRedirectException for forcing the activationg of a new page to render the response. It also has the RedirectException which will perform either a client-side or server-side redirect as appropriate.
To me it sounds like you are fighting Tapestry rather than working with it. Tapestry is designed to solve 90%+ of your problems, and give you the freedom to address those last few problems in an application specific manner (by creating new components and new engine services, typically).
-
First impressions from Tapestry
2004-06-03 17:03:47 mchnz
I'm not so sure all the comments are highly a-typical, perhaps some words are ill-chosen - I wouldn't say that Tapestry is fragile - but initially the framework looks so good that it sets up some inflated expectations.
Tapestry provides several powerful simplifications of the web development. Initially it makes web development appear to be very similar to GUI development. It seems to step the developer away from having to think of the browser as a browser - much like .Net.
But when you start to use Tapestry for real, it starts to dawn on you that you still have to be aware of the browser request-response cycle. Things that looked easy are now a little harder: you have to stop using persistent properties for some data; do some extra work in the setting up the hidden fields or token tracking; and stop using cycle.activate() in some situations. This is unexpected. The learning curve starts to get a bit steeper.
Initially there is some uncertainty about where/when in the render-cycle it's safe to do what. This is also unexpected, because at the beginning this all looks pretty much a no-brainer.
And other issues pop up. Such as the need for FormConditional instead of Conditional (not mentioned in many places). Or the need to keep some table state in the session - which has implication for multiple browser windows, back buttons etc. You have to think about these issues and deal with them.
Once you start to understand these things, using Tapestry becomes easier, and the cleanness and power of .page/.html/.java triad kicks in.
Over time, initial expectations will be clarified by better documentation/FAQs etc.
With the addition of browser-page persisted page-properties, and internal support for an (optional) token-based approach to back-button prevention, and some clarification of the rendering cycle (via better interfaces or documentation), Tapestry could evolve to hide/automate more aspects of the server-browser
interaction.
-
First impressions from Tapestry
2004-06-04 14:30:01 vjeran
I totally agree with you. I started using Tapestry 2-3 months ago, and got totaly hooked, but I also experienced much more difficulties than initially thought.
At first it looked like only difficulty will be different way of thinking comparing to typical "push" frameworks, offering you much power since developing Tapestry's apps felt like Swing app developing. Templating is also best I ever seen. But when I went deeper into it, I've seen that I need to know a lot about internal request lifecycle, and some of Tapestry's commodities can only be used in certain situations. A lot of potential pitfalls for not-so-careful or not-so-knowing developer.
I'm currently getting quite known with Tapestry and I can do so much with it with so little work, but I needed to read a book, was discussing a lot on mailing list, and generally invested a lot of effort that I doubt every new developer will have nerves for. I think this framework will have to invest more in simplicity to be trully succesufull and widespread, especially now when competitor like JSF is out, with much stronger marketing, so it is not the only java component web framework around.
Typical developer that is willing to try Tapestry will come to web site, read a docs there (not buy the book), try the framework for 2-3 weeks, not discuss on mailing list, and if all the major features found in docs are working well, decide to use it.
I'm not currently convinced that it will go so smoothly as one would expect when starting to use it (complicated parameters, only server side state persistence - no client side as in ASP.NET or JSF, question when to forget page if using persistent properties, no support for invalidating session etc.. ). Good thing is that most of problems are identified, and will be worked on, it's just that sometimes I wish there would be 5 Howards working constantly on it :-)
-
First impressions from Tapestry
2004-06-03 07:59:51 vtec
Thanks for your words I hope this conversation can help both of us to do our jobs
better.
Once again about the RedirectException - we use this code sequence:
String pageURL = cycle.getEngine()
.getService( org.apache.tapestry.Tapestry.EXTERNAL_SERVICE )
.getLink( cycle, cycle.getPage(), new Object[]{pageName}).getURL();
System.out.println("new RedirectException("+pageURL+")");
throw new org.apache.tapestry.RedirectException(pageURL);
When HTTP POST form submission is being processed, this code causes the client browser to send another
HTTP GET request to see the page displaying results of previous POST . This way the end user may
subsequently refresh his browser window and only the HTTP GET operation is repeated - so the action
triggered by the form submission is not repeated. This is very obvious solution since Struts times
however the demonstrated code seems to be too complex for such a basic service.
To demonstrate what I mean by the that maybe too strong word consider this simple scenario:
You have several ActionLinks inside your page. The page can be in several logical states. State changes
are triggered by clicking these ActionLinks. In each state some of these links are disabled. You
cannot enable/disable these links in a way required by the state model inside the listeners trigerred by these links
- this would disrupt the rewinding. But this is exactly what the Swing programmer would do in such situation.
We recently run into many more of these "be carefull" situations.
-
First impressions from Tapestry
2004-06-03 08:33:51 hlship
I don't use ActionLinks, I use DirectLinks. ActionLinks have such state problems problems and, unlike Forms, there isn't a reasonable solution.
If you notice, the book does not mention ActionLink, and I would have removed ActionLink already, except for objections from established users.
In 3.1, there will be more facilities for moving persistent state to the client side, in the form of query parameters and cookies.
-
First impressions from Tapestry
2004-06-03 10:06:48 vtec
I think this is basic precondition for the rewinding to not modify any involved
component util end of rewinding process - e.g. delay any programatic changes in
components until "non-rewinding" pageBeginRender(). But I had to relieve this fact
using try and fail approach.
Anyway my colleague just discovered that I was using less suitable version
of Table components (TableFormPages,TableFormRows,...) in situation when more
lightweight (TablePages,TableRows) would be sufficient. With these we got rid
of Action service and rewinding and most of our problems just disappeared.
And life is once again wonderfull ;-)
I hope our bet on Tapestry is gona pay off . It is incredibly powerfull but we
also have to learn a lot. Despite our struggling with the build-in Table component
it would definitely need take much longer time to develop comparable thing using
traditional JSP & custom tags. The build-in Table component supports paging,
column sorting, server side data caching, editable cells with automatic cell-value
change detection, CSS-based customization and many more features we have yet to discover.
Let's hope that with our groving experience we would be able to master the other
more complex build-in components faster and easier.
Regards
Vitek
-
rewind
2004-06-02 13:54:16 melvinma
I read your book but still not sure exactly how rewinding is done. I have used some of its features such as doing multiple selections on objects. It is really, really cool! Please explain the rewinding in more details to me.
Thanks,
Melvin
-
rewind cycle
2004-06-03 08:41:02 hlship
It's so natural for people to see how rendering works ... we walk the component tree, and allow each component to render out some HTML. If there are conditionals or loops, its natural to see those execute.
Along the way, the looping components (Foreach or ListEdit) are getting collections of objects and updating transient page properties. Other form element components have parameters bound to those transient properties, or properties nested within. The form element components read those properties and render HTML.
Now picture that exact process, but imagine that each form element component is *updating* properties rather then *reading* properties.
That's exactly what happens in the rewind cycle.
We go through the render a second time, but in the new request. The only shared information we have is persistent page properties (whose values are reconsistuted in the new request) and any data that comes up in the form submission.
We want to update page properties, and nested properties. So we redo the render and want to do the exact same set of operations NOW as we did BEFORE.
Things go wrong when the underlying data changes. If your page has a property ... say a list of CartItem objects from a shopping cart, and the number of items changes between the render and the form submission (maybe the user hit the browser back button), Tapestry will be able to tell, and throws an exception because values simply are not going to map to the right CartItem objects.
Using the ListEdit component, you have more control, since it creates hidden fields with the ids of each object, making it easier to recover when the underlying set of objects changes. You can suppliment this with a HIdden object that detects if each object has changed
-
rewind cycle
2004-06-04 11:22:22 melvinma
How did you get "the component tree" in the second page?
For example, I got my data (a list of people) and then present these people in a multiple selection box. Then I click on the submit button. On this request, Tapestry gets my previous list of people from Session or Tapestry redo a database query to get the same list?? If Tapestry gets my list of people from session, does people object have to be serializable?
Thank you again for the wonderful product and your help,
Melvin
-
Tapestry Apps and Portals
2004-06-02 07:22:58 wimsycal
Let me start off by saying that I know very little about Tapestry.
I was told that Tapestry applications wouldn't play well in a portal environment, namely a JSR 168 portal or possibly one using WSRP mainly due to the fact that the servlet stuff is hidden in Tapestry.
I am very interested in this because, I am researching different web frameworks to give our developers more choices. Right now, everything is done in Struts. Tapestry seems by far the easiest to pick up, from what I have read so far. I also like JSF for the simple fact that some of our application parts really would fit better as a component that can be shared with other applications.
Thanks for your advice.
-
Tapestry Apps and Portals
2004-06-02 13:25:27 hlship
Tapestry does not support the Porlet API. This is planned for release 3.1, and should not be a lot of work, because Tapestry buries the Servlet API deep enough that most applications never see it.
Like JSF, Tapestry will have its own abstraction around either Porlet API or Servlet API.
-
Tapestry vs JSF
2004-05-28 08:33:35 mramirez
You have probably have been asked this question a million times but here it is again. Could you compare and contrast JSF and Tapestry?
-
Tapestry vs JSF
2004-06-01 07:10:25 hlship
I get this all the time. I haven't delved very deeply into JSF, but I've read the documentation and examples. David Geary owes me a copy of his book, as well!
JSF is much more code-heavy than Tapestry. Tapestry gets more done with less code and less XML.
JSF arbitrarily puts a lot of very XML-ish configuration information into the JSP. I find it kludgey and ugly. Tapestry seperates the stuff that should be XML into a standalone XML file. This is the page specification, where you can define the types and configurations of your components. You can do it right in the Tapestry HTML template as well, the choice is yours (this is implicit vs. declared components).
JSF claims that it will, ahem, *eventually*, support multiple UIs with a single set of components. Therefore, there's a *lot* of (to me) uneceessary abstractions to hide the fact that JSF is spewing out HTML. I personally believe that the single-UI nirvana is neither obtainable nor desirable (and I'm sure we'll pick up that discussion in a new thread).
JSF does support the portlet API as well as the servlet API. Tapestry 3.0 does not, but this is a priority for Tapestry 3.1.
Tapestry HTML templates are very clean, meaning that they can be previewed in a standard WYSIWYG editor. JSF templates are more-JSP-than-thou, with tons of non-HTML directives inside.
Tapestry is truly open source. It has evolved to fit its users needs over the last four years. JSF is new and untested, and as a "standard", can't evolve with the speed that a focused open-source project can.
Tapestry is all about enhancing dev eloper productivity. If you believe that developer productivity starts and ends with being able to drag an icon into some window and have your tool spew out code to make it work, then Tapestry can't compete with JSF.
If you believe that productivity comes from having a simple, consistent, efficient framework that provides excellent feedback, you're on the right track. Tapestry gives you the tools to solve problems unique to your application. It doesn't wall you off from the underlying Servlet API, it just makes the Servlet API irrelvant 99% of the time.
Tapestry has a simple component object model and a simple (but easily expandable) request processing cycle.
Tapestry components can, themselves, have templates and be assembled from other components. JSF components are, in fact, taglibs that can only produce HTML output in code.
Tapestry components may contain links and forms, and can process requests related to them independently of the page. For example, MindBridge's Table component (similar to the DataGrid JSF component) labels colums and can resort the table as the columns are clicked. It can also renders out and handles a set of links for page navigation. You can have as many tables on a page as you want, spread across as few or as many forms as you want, and it all works properly at runtime ... with no special support from the containing page.
Results Not Standards No matter how bright the folks on an expert panel are, there's a world of difference between making a product and making a specification. Specifications are full of compromises and hidden agendas. Tapestry's agenda is as open as the code: be the best way to develop web applications; eliminate uncessary coding so that you can concentrate on what counts: your application's specific business logic.
-
Tapestry vs JSF
2004-06-01 14:04:08 mramirez
Thank you for your quick response. I am new to Java. I am comming from a Coldfusion/Php backrgound. I plan to purchase your book to get me started with Tapestry. I thinks gonna be fun :)
-
Welcome to the Tapestry In Action Forum
2004-05-27 09:44:13 hlship
Hello, I'm Howard M. Lewis Ship, the creator of Tapestry, and the author of "Tapestry In Action", the definitive guide to Tapestry.
I'm looking forward to a great discussion about Tapestry and the book. If you don't already have a copy of the book (shame on you!), two chapters are available for free on Manning's web site.
In addition, a lot of resources about Tapestry are available on the Tapestry Home Page and the Tapestry Wiki.
-
Welcome to the Tapestry In Action Forum
2004-08-31 07:06:14 pdiscipio
Hi,
How can I create a new component with tapestry
|
Showing messages 1 through 20 of 20.
|
|