Return-Path: X-Original-To: apmail-tapestry-dev-archive@www.apache.org Delivered-To: apmail-tapestry-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 1EB289C9F for ; Tue, 16 Dec 2014 16:19:33 +0000 (UTC) Received: (qmail 78760 invoked by uid 500); 16 Dec 2014 16:19:33 -0000 Delivered-To: apmail-tapestry-dev-archive@tapestry.apache.org Received: (qmail 78711 invoked by uid 500); 16 Dec 2014 16:19:32 -0000 Mailing-List: contact commits-help@tapestry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tapestry.apache.org Delivered-To: mailing list commits@tapestry.apache.org Received: (qmail 78702 invoked by uid 99); 16 Dec 2014 16:19:32 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Dec 2014 16:19:32 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 4AFEFAC092D for ; Tue, 16 Dec 2014 16:19:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r932985 - in /websites/production/tapestry/content: cache/main.pageCache component-parameters.html principles.html Date: Tue, 16 Dec 2014 16:19:31 -0000 To: commits@tapestry.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141216161932.4AFEFAC092D@hades.apache.org> Author: buildbot Date: Tue Dec 16 16:19:31 2014 New Revision: 932985 Log: Production update by buildbot for tapestry Modified: websites/production/tapestry/content/cache/main.pageCache websites/production/tapestry/content/component-parameters.html websites/production/tapestry/content/principles.html Modified: websites/production/tapestry/content/cache/main.pageCache ============================================================================== Binary files - no diff available. Modified: websites/production/tapestry/content/component-parameters.html ============================================================================== --- websites/production/tapestry/content/component-parameters.html (original) +++ websites/production/tapestry/content/component-parameters.html Tue Dec 16 16:19:31 2014 @@ -157,12 +157,12 @@

A component may have any number of parameters. Each parameter has a specific name, a specific Java type (which may be a primitive value), and may be optional or required.

Within a component class, parameters are declared by using the @Parameter annotation on a private field, as we'll see below.

Parameter Bindings

In Tapestry, a parameter is not a slot into which data is pushed: it is a connection between a field of the component (marked with the @Parameter annotation) and a property or resource of the component's container. (Components can be nested, so the container can be either the page or another component.)

This short snippet demonstrates a bit about how Tapestry operates. Pages and services within the application are injected with the @Inject annotation. The method names, onValidateFromForm() and onSuccessFromForm(), inform Tapestry about when each method is to be invoked. This naming convention identifies the event that is handled, ("validate" and "success") and the id of the component from which the event is triggered (the "form" component).

The "validate" event is triggered to perform cross-field validations, and the "success" event is only triggered when there are no validation errors. The onSuccessFromForm() method's return value directs Tapestry on what to do next: jump to another page within the application (here identified as the class for the page, but many other options exist). When there are exceptions, the page will be redisplayed to the user.

By contrast, in Tapestry 4 the Form component's listener parameter would be bound to the method to invoke, by name. Further, the listener method had to be public. The Tapestry 5 approach not only supports multiple listeners, but also provides an improved separation of view concerns (inside the page's HTML template) and logic concerns, inside the Java class.

In many cases, additional information about the event is available and can be passed into the method simply by adding parameters to the method. Again, Tapestry will adapt to your parameters, in whatever order you supply them.

Tapestry also saves you needless effort: the @Property annotation marks a field as readable and writable; Tapestry will provide the accessor methods automatically.

Finally, Tapes try 5 explicitly separates actions (requests that change things) and rendering (requests that render pages) into two separate requests. Performing an action, such as clicking an action link or submitting a form, results in a client-side redirect to the new page. This is the "Post/Redirect/Get" pattern (alternatively "Post-Then-Redirect", or "Redirect After Post"). This helps ensure that URLs in the browser are book-markable ... but also requires that a bit more information be stored in the session between requests (using the @Persist annotation).

Principle 3 – Differentiate Public vs. Internal APIs

An issue plaguing much ancient versions of Tapestry (4 and earlier) was the lack of a clear delineation between private, internal APIs and public, external APIs. The fact that your code would extend from base objects but that many of the methods on those base objects were "off limits" further confused the issue. This has been identified as a key factor in the "steep learning curve of Tapestry" meme.

Designed from a clean slate, Tapestry 5 is much more ruthless about what is internal vs. external.

First of all, anything inside the org.apache.tapestry5.internal package is internal. It is part of the implementation of Tapestry. It is the man behind the curtain. You should not ever need to directly use this code. It is a bad idea to do so, because internal code may change from one release to the next without concern for backwards compatibility.

Icon
- -

If you ever find yourself forced to make use of internal APIs, please bring it up on the developer mailing list; this is how we know which services should be exposed as public, and fall under the backwards compatibility umbrella.

+

If you ever find yourself forced to make use of internal APIs, please bring it up on the developer mailing list; this is how we know which services should be exposed as public, and fall under the backwards compatibility umbrella.

- - -

Principle 4 – Ensure Backwards Compatibility

- -

Older versions of Tapestry were plagued by backwards compatibility problems with every major release. Tapestry 5 did not even attempt to be backwards compatible to Tapestry 4. Instead, it laid the ground work for true backwards compatibility going forwards.

- -

Tapestry 5's API is based largely on naming conventions and annotations. Your components are just ordinary Java classes; you annotate fields to allow Tapestry to maintain their state or to allow Tapestry to inject resources, and you name (or annotate) methods to tell Tapestry under what circumstances a method should be invoked.

- -

Tapestry will adapt to your classes. It will call your methods, passing in values via method parameters. Instead of the rigidness of a fixed interface to implement, Tapestry will simply adapt to your classes, using the hints provided by annotations and simple naming conventions.

- -

Because of this, Tapestry 5 can change internally to a great degree without it affecting any of the application code you write. This has finally cracked the backwards compatibility nut, allowing you to have great assurance that you can upgrade to future releases of Tapestry without breaking your existing applications.

- -

This is already evident in Tapestry 5.1, 5.2 and 5.3 where major new features and improvements have occurred, while remaining 100% backwards compatible to Tapestry 5.0 – as long as you've avoided the temptation to use internal APIs.

- -
- -

Footnotes
ReferenceNotes
- - 1 - - - The component id can be omitted, leaving the method name onSuccess(), but that may cause confusion on a page that has multiple Form components triggering events, so it's best to be specific about the source of the event. -

+

Principle 4 – Ensure Backwards Compatibility

Older versions of Tapestry were plagued by backwards compatibility problems with every major release. Tapestry 5 did not even attempt to be backwards compatible to Tapestry 4. Instead, it laid the ground work for true backwards compatibility going forwards.

Tapestry 5's API is based largely on naming conventions and annotations. Your components are just ordinary Java classes; you annotate fields to allow Tapestry to maintain their state or to allow Tapestry to inject resources, and you name (or annotate) methods to tell Tapestry under what circumstances a method should be invoked.

Tapestry will adapt to your classes. It will call your methods, passing in values via method parameters. Instead of the rigidness of a fixed interface to implement, Tapestry will simply adapt to your classes, using the hints provided by annotations and simple naming conven tions.

Because of this, Tapestry 5 can change internally to a great degree without it affecting any of the application code you write. This has finally cracked the backwards compatibility nut, allowing you to have great assurance that you can upgrade to future releases of Tapestry without breaking your existing applications.

This is already evident in Tapestry 5.1, 5.2 and 5.3 where major new features and improvements have occurred, while remaining 100% backwards compatible to Tapestry 5.0 – as long as you've avoided the temptation to use internal APIs.