Author: hlship
Date: Fri Jan  5 11:35:14 2007
New Revision: 493155

URL: http://svn.apache.org/viewvc?view=rev&rev=493155
Log:
Record some notes about case insensitivity

Modified:
    
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html
    tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml

Modified: 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html?view=diff&rev=493155&r1=493154&r2=493155
==============================================================================
--- 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html 
(original)
+++ 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html 
Fri Jan  5 11:35:14 2007
@@ -5166,11 +5166,12 @@
        <div id="contentWrapper"></div>
        <div id="contentStash"></div>
        <div id="storeArea"><div tiddler="Assets" modifier="HowardLewisShip" 
modified="200701032350" created="200611241951" tags="">The concept of Assets is 
unchanged from Tapestry 4.\n\nThere will be an &quot;exclusion list&quot; of 
file name extensions. Files with that extension will require an md5sum as part 
of the URI.  The default exclusion list with be &quot;.class&quot;. For other 
file types (particularily .js, .css, etc.) the file will be the file, and 
relative file names will work.\n\nSome kind of hook will be necessary to 
support schemes like Akamai, where assets are stored externally. This should 
also take into account localization.\n\nSome kind of folder aliasing will be 
necessary.  I may want &quot;/assets/dojo/&quot; to map on the classpath to 
&quot;/org/apache/tapestry/dojo/dojo_0_0_4/&quot;.  When handling updates to 
big packages such as Dojo, I don't want to have to sort through some ungodly 
number of changes between 0.0.4 and 0.0.5, I want to create a new dojo_0_0
 _5 folder, drop the contents in, delete the dojo_0_0_4 folder, and update the 
mapping of &quot;/assets/dojo/&quot;.\n\nUpdate: the aliasing is in place and 
very nice; the default CSS stylesheet is 
&quot;/asset/tapestry/default.css&quot;  not 
&quot;/asset/org/apache/tapestry/default.css&quot;.</div>
+<div tiddler="CaseInsensitivity" modifier="HowardLewisShip" 
modified="200701051934" created="200701051933" tags="">One aspect of 
&quot;pretty&quot; URLs for Tapestry pages is that case should not matter.  The 
user should be able to manually type a URL without respect to case, and have it 
//just work//.  Turns out that's hard on a number of fronts.\n\n! Page 
Names\n\nIn Tapestry 4 and in the current Tapestry 5 code base, that is a 
problem.  Tapestry starts with a page name, and uses that to hunt around and 
locate the page class and from there, the page template, etc.\n\nThat hunting 
around tends to be problematic, because ClassLoader.getResource() is case 
//specific//.  In addition, ClassLoader doesn't directly provide any way to 
introspect the available classes.\n\nYou'd think that you could, as a page is 
first accesssed, record its name in a case insensitve cache somewhere.  
However, that doesn't work.  First, in a cluster, the server handling the 
request may simply never h
 ave handled a request for that page before, so it won't have an up-to date 
cache.  Likewise, after a server restart, existing requests (possibly cached in 
a browser's bookmarks) \n\nHowever, I've been doing some research.  
ClassLoader.getResources() , passed a folder name (such as 
&quot;org/example/myapp/pages/&quot;) will yield one or more URLs for the 
folders.  Some of these will be URLs for file systems, some will be URLs for 
JARs.  You can differentiate by the value returned from 
URL.openConnection().\n\nFor file system URLs, opening the stream provides a 
list of the files and folders for that package.  Using this, we can identify 
the protential classes, and identify sub-folders/sub-packages to recursively 
scan.\n\nFor JAR URLs, we can cast to JARURLConnection and obtain the JarFile 
instance for the entire JAR.  From there we can obtain a list of 
entries.\n\nCombining these two approaches should allow us, at application 
startup, to locate all page instances.  We'll be ab
 le to build a case-insensitive mapping from logical page name to Java class 
name.\n\n! Component Ids\n\nComponent ids and id paths show up in some URLs 
(primarily action URLs, but even so). As currently implemented, ids are case 
sensitive. With some work, it should be possible to make accessing a component 
by its id, or id path, case insensitive.  This should include errors if two 
components have the same case-insensitive id.\n\n! Query Parameters\n\nNot sure 
this is as relevant, because the types of URLs that matter will usually not 
include any query parameters.  In terms of form submissions ... well, the 
entire client side is wired case sensitivly, so making form submissions case 
inensitive seems like a useless exercise.</div>
 <div tiddler="ComponentActionRequest" modifier="HowardLewisShip" 
modified="200610081335" created="200610080113" tags="">Component actions are 
actions that reflect user interaction with a component within a page. Again, 
this falls into several broad categories:\n\n* Links that perform a server-side 
action, and result in a page refresh, or a new page being displayed.\n* Ajax 
style links, which perform a server-side action, and refresh only part of the 
page.\n* Forms which perform a server-side action, followed by a page refresh 
(or new page being displayed).\n* Ajax style forms, which trigger an action, 
followed by a refresh of part of the page.\n* Other user interactions, which 
result in a server side action, and a partial page refresh.\n\nIn all of these 
cases, one or more ComponentEvents is fired. The result of ComponentEvent 
determines whether a partial page render or a full page render occurs.\n\nIn 
the later case, a client side redirect is sent, to force the browser to i
 nitial a new PageRenderRequest.  This addresses an issue in Tapestry 4, in 
that following a link or form submission, the URL would indicate details about 
the previous page, not the newly displayed page, and clicking the browser 
refresh button could cause a server side operation to occur again (which would 
often be quite undersirable).\n\n!URI 
Format\n\n{{{\n/page-name.event-type/component-id-path/id\n}}}\n\nHere 
page-name is the LogicalPageName.  The event-type is a string that identifies 
the type of event (and will ultimately be used to select an event handler 
method).  \n\nThe component-id-path is a dot-separated series of component ids, 
used to identify a specific component within the overall page.\n\nThe id is 
optional, and may be repeated. The id value or values will be provided to the 
event handler method.\n\nExample: /Login.submit/form  (the URI for a form 
component on page Login).\n\nExample: /admin/UserProfile/action/menu.delete/37  
(component menu.delete of the Use
 rProfile page, with an id of 37).\n</div>
 <div tiddler="ComponentDocumentation" modifier="HowardLewisShip" 
modified="200611231534" created="200611231533" tags="parameters">Tapestry needs 
a JavaDoc-like, or JavaDoc-based tool to extract documentation about component 
parameters (and mixins) and present it in a useable format.  In Tapestry 4, you 
could document the public getters and setters, but in Tapestry 5, the 
annotations are on the private instance variables, which are generally not 
documented.</div>
 <div tiddler="ComponentEvent" modifier="HowardLewisShip" 
modified="200610081359" created="200610081351" tags="requests events">Component 
events represent the way in which incoming requests are routed to user-supplied 
Java methods.\n\nComponent events //primarily// originate as a result of a 
ComponentActionRequest, though certain other LifecycleEvents will also 
originate component events.\n\nEach component event contains:\n* An event type; 
a string that identifies the type of event\n* An event source; a component that 
orginates the event (where applicable)\n* A context; an array of strings 
associated with the event\n\nEvent processing starts with the component that 
originates the event.\n\nHandler methods for the event within the component are 
invoked.\n\nIf no handler method aborts the event, then handlers for the 
originating component's container are invoked.\n\nThis containues until 
handlers for the page (the root component) are invoked, or until some handler 
method aborts
  the event.\n\nThe event is aborted when a handler method returns a non-null, 
non-void value.  The interpretation of that value varies based on the type of 
event.\n\nEvents are routed to handler methods using the @~OnEvent 
annotation.\n\nThis annotation is attached to a method within a component 
class.  This method becomes a handler method for an event.\n\nThe annotation 
allows events to be filtered by event type or by originating 
component.\n\n{{{\n  @OnEvent(value=&quot;submit&quot;, 
component=&quot;form&quot;)\n  String handleSubmit()\n  {\n    // . . .\n\n   
return &quot;PostSubmit&quot;;\n  }\n}}}\n\nIn the above hypothetical example, 
a handler method is attached to a particular component's submit event.  After 
processing the data in the form, the LogicalPageName of another page within the 
application is returned. The client browser will be redirected to that 
page.\n\nHandler methods need not be public; they are most often package 
private (which facilitated UnitTesting 
 of the component class).\n\nHandler methods may take parameters.  This is most 
useful with handler methods related to links, rather than forms.\n\nAssociated 
with each event is the context, a set of strings defined by the application 
programmer.\n\nParameters are coerced (see TypeCoercion) from these strings.  
Alternately, a parameter of type String[] receives the set of strings.\n\n{{{\n 
 @OnEvent(component=&quot;delete&quot;)\n  String deleteAccount(long 
accountId)\n  {\n    // . . .\n\n   return &quot;AccountPage&quot;;\n  
}\n}}}\n\nHere, ther first context value has been coerced to a long and passed 
to the deleteAccount() method. Presemuable, an action link on the page, named 
&quot;delete&quot;, is the source of this event.\n\n</div>
 <div tiddler="ComponentMixins" modifier="HowardLewisShip" 
modified="200701032348" created="200610051234" tags="mixins">One of the more 
exciting ideas in Tapestry 5 is //mixins//; the ability to add behavior to a 
component without writing code. \n\nIt is expected that much common behavior, 
especially for form control components, will be provided by mixins. Further, 
many Ajax techniques will take the form of mixins applied to otherwise ordinary 
components.\n\nA mixin is an additional component class that operates //with// 
the main component. For a component element within the page, the functionality 
is provided by the main component class and by\nthe mixin.  \n\nMixins are 
primarily about rendering. Mixin render methods are //mixed in// to the 
components' render methods. In effect, the different rendering phases of a 
component are different AOP-like //joinpoints//, and the mixins can provide 
//before advice//.\n\nMixins can be specified for an //instance// of a 
component, or c
 an be specified as part of the //implementation// of a component.\n\nIn the 
former case, the @Component annotation will be supplemented with a @Mixin 
annotation. The @Mixin is a list of one or more mixin classes for that 
component.\n\n==''Todo: Template syntax for mixins?''== The mixins attribute 
allows a comma-separated list of component mixins names (logical names, not 
class names).\n\nIn the latter case, the @ComponentClass annotation will be 
supplemented with a @Mixin annotation.\n\nMixins can be configured.  They can 
have parameters, just like ordinary components. When a formal parameter name is 
ambiguous, it will be prefixed with the unqualified class name. Thus, you might 
have to say, &quot;MyMixin.parameterName=someProperty&quot; if 
&quot;parameterName&quot; is ambiguous (by ambiguous, we mean, a parameter of 
more than one mixin or of the component itself).  \n\nThis disambiguation is 
//simple//. It is assumed that the unqualified class name will be sufficient to 
uni
 quely identify a mixin. That is, it is expected that you will not have the 
same class name even in different packages (as mixins, on a single component). 
In a //degenerate case// where this is not so, it will be necessary to 
disambiguate the mixin name by create a subclass of the mixin with a new 
name.\n\n==''Todo: how are mixins on a component implementation configured?''== 
The @Mixin and @MixinClass annotations, on fields, support this.\n\nMixins may 
have persistent state, just as with ordinary components.\n\n</div>
-<div tiddler="ComponentTemplates" modifier="HowardLewisShip" 
modified="200701032344" created="200610201801" tags="">There are some issues 
related to component templates.\n\nFirstly, people are really interested in 
seeing the return of InvisibleInstrumentation.  =That is coming.= That is now 
available.\n\nSecondly, the idea that templates are well-formed XML documents 
is causing some issues.\n\nThe problem is related to entities and 
doctypes.\n\nUnless you provide a doctype for the template, 
[[entities|http://www.htmlhelp.com/reference/html40/entities/]] don't work; 
they result in template parse errors.\n\nIf you provide a standard doctype, 
say\n{{{\n &lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 
Transitional//EN&quot;\n            
&quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;\n}}}\n\nYou also get 
parse errors, because the DTD does some odd things with comments that the Java 
SAX parser doesn't seem to understand.\n\nI've had better luck with the XHTML 
doctyp
 e:\n{{{\n&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 
Transitional//EN&quot;\n&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;\n}}}\n\nBut
 this doesn't render quite the way I want it to.\n\nFurther, entities in the 
text are converted to unicode by the parser, then converted to &lt;numeric&gt; 
entities on output.  Not quite WYSIWYG and potentially confusing.\n\nIt may be 
necessary to discard SAX and build a limited XML parser that allows entities to 
be passed through unchanged (they would become a special type of document 
token).\n\nLastly, the question is how to get the correct DOCTYPE into the 
rendered output, espcially in the common case that a Border component provides 
the outer tags, as is common in Tapestry 4.  This may have to be configured as 
a annotation on page classes.</div>
+<div tiddler="ComponentTemplates" modifier="HowardLewisShip" 
modified="200701051919" created="200610201801" tags="">There are some issues 
related to component templates.\n\nFirstly, people are really interested in 
seeing the return of InvisibleInstrumentation.  =That is coming.= That is now 
available.\n\nSecondly, the idea that templates are well-formed XML documents 
is causing some issues.\n\nThe problem is related to entities and 
doctypes.\n\nUnless you provide a doctype for the template, 
[[entities|http://www.htmlhelp.com/reference/html40/entities/]] don't work; 
they result in template parse errors.\n\nIf you provide a standard doctype, 
say\n{{{\n &lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 
Transitional//EN&quot;\n            
&quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;\n}}}\n\nYou also get 
parse errors, because the DTD does some odd things with comments that the Java 
SAX parser doesn't seem to understand.\n\nI've had better luck with the XHTML 
doctyp
 e:\n{{{\n&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 
Transitional//EN&quot;\n&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;\n}}}\n\nBut
 this doesn't render quite the way I want it to.\n\nFurther, entities in the 
text are converted to unicode by the parser, then converted to //numeric// 
entities on output.  Not quite WYSIWYG and potentially confusing.\n\nIt may be 
necessary to discard SAX and build a limited XML parser that allows entities to 
be passed through unchanged (they would become a special type of document 
token).\n\nLastly, the question is how to get the correct DOCTYPE into the 
rendered output, espcially in the common case that a Border component provides 
the outer tags, as is common in Tapestry 4.  This may have to be configured as 
a annotation on page classes.\n\n! Template Location\n\nConcensus is building 
that templates should //not//  have a  {{{.html}}} extension, but something 
specific to Tapestry, perhaps {{{.tap}}} or {{{.
 tsp}}}.\n\n\nFurther, there are invalid, but present, security concerns that 
the templates should live on the classpath or in WEB-INF, but not in the root 
folder.  Both of these issues would simplify things for Tapestry.\n</div>
 <div tiddler="DeveloperProcedures" modifier="HowardLewisShip" 
modified="200610281525" created="200610281524" tags="">Tapestry is a big chunk 
of code, growing every day. We need to not step on each other's toes.\n\n//At 
this time, Tapestry is pretty single threaded, with Howard setting up the main 
infrastructure.  Soon there's going to be a crowd of folks working on it, and 
we need to coordinate on this ahead of time.//\n\nBasic guidelines:\n\n* 
WorkInYourOwnBranch\n* WatchCodeCoverage\n* FocusOnTesting\n* 
DontTouchInternals\n</div>
 <div tiddler="DontTouchInternals" modifier="HowardLewisShip" 
modified="200611241953" created="200611241953" tags="">Very few of the Tapestry 
committers will need to touch anything inside the internals package.  When this 
occurs, some online discussion may be mandated.  The goal of Tapestry is to 
ensure that most work for commiters and for developers is in the domain of 
creating components, not tinkering with internals.</div>
 <div tiddler="DynamicPageState" modifier="HowardLewisShip" 
modified="200611241832" created="200609211610" tags="">Tapestry 4 has left 
tracking of dynamic page state as an exercise to the developer.  Mostly, this 
is done using the ''parameters'' parameter of the ~DirectLink 
component.\n\n''Update: As I've thought this one through, I don't think it is 
viable outside of Forms. It will end up with long URLs and a constant ambiguity 
about whether each link should include or exclude the page state.  So this one 
is unlikely to get implemented.''\n\nDynamic page state is anything that isn't 
inside a persistent page property. For the most part, this includes page 
properties updated by a For component\n\nIt seems likely that this information 
could be automatically encoded into ~URLs.  \n\nI'm envisioning a service that 
accumulates a series of //commands//. Each command is used to store a bit of 
page state. The commands are serializable.  The commands are ultimately 
serialized into a M
 IME string and attached as a query parameter to each URL.\n\nWhen such a link 
is triggered, the commands are de-serialized and each executed in turn. Only 
when that is finished is any further event processing executed, including 
calling into to user code.\n\nMy outline for this is to store a series of 
tuples; each tuple is a component id plus the command to 
execute.\n\n{{{\npublic interface ComponentCommand&lt;T&gt;\n{\n  void 
execute(T component);\n}\n}}}\n\nThese commands should be immutable.\n\nSo a 
component, such as a For loop component, could provide itself and a 
ComponentCommand instance (probably a static inner class) to some kind of 
PageStateTracker service.\n\n{{{\npublic interface PageStateTracker\n{\n  void 
&lt;T&gt; addCommand(T component, ComponentCommand&lt;T&gt; 
command);\n}\n}}}\n\nThe commands are kept in the order that they are added, 
except that new commands for the same component //replace// previous commands 
for that component.\n\nAs with the Tapestry 4
  For component, some mechanism will be needed to store object ids inside the 
URLs (that is, inside the commands serialized into URL query parameters) and 
translate back to //equivalent// objects when the link is triggered.\n\nDynamic 
page state outside of a Form will overlap with some of the FormProcessing 
inside the form.</div>
@@ -5181,7 +5182,7 @@
 <div tiddler="InvisibleInstrumentation" modifier="HowardLewisShip" 
modified="200610201803" created="200610201802" tags="">A feature of Tapestry 4 
where the component id, type and parameters were &quot;hidden&quot; inside 
ordinary HTML tags.\n\nThis will show up inside Tapestry 5 pretty soon, and 
look something like:\n{{{\n&lt;span t:type=&quot;If&quot; 
t:test=&quot;prop:showWarning&quot; class=&quot;warning&quot;&gt; \n  . . 
.\n&lt;/span&gt;\n}}}</div>
 <div tiddler="LogicalPageName" modifier="HowardLewisShip" 
modified="200610081330" created="200610081330" tags="">A logical page name is 
the name of a page as it is represented in a URI.\n\nInternally, Tapestry 
operates on pages using full qualified class names. Technically, the FQCN is 
the class of the page's root element, but from an end developer point of view, 
the root element is the page.\n\nThe logical page name must be converted to a 
fully qualified class name.\n\nA set of LibraryMappings are used.  Each library 
mapping is used to express a folder name, such as &quot;core&quot;, with a Java 
package name, such as org.apache.tapestry.corelib.  For pages, the page name is 
searched for in the pages sub-package (i.e., 
org.apache.tapestry.corelib.pages).  Component libraries have unique folder 
names mapped to root packages that contain the pages (and components, and 
mixins) of that library.\n\nWhen there is no folder name, the page is expected 
to be part of the application, 
 under the pages sub-package of the application's root package.\n\nIf not found 
there, as a special case, the name is treated as if it were prefixed with 
&quot;core/&quot;.  This allows access to the core pages (and more importantly, 
components -- the search algorithm is the same).\n\nFinally, pages may be 
organized into folders.  These folders become further sub-packages. Thus as 
page name of &quot;admin/EditUsers&quot; may be resolved to class 
org.example.myapp.pages.admin.EditUsers.\n\n</div>
 <div tiddler="MainMenu" modifier="HowardLewisShip" modified="200609210701" 
created="200609210643" tags="">MasterIndex\n[[RSS 
feed|tap5devwiki.xml]]\n\n[[Tapestry 5 
Home|http://tapestry.apache.org/tapestry5/]]\n[[Howard's 
Blog|http://howardlewisship.com/blog/]]\n\n[[Formatting 
Help|http://www.blogjones.com/TiddlyWikiTutorial.html#EasyToEdit%20Welcome%20NewFeatures%20WhereToFindHelp]]</div>
-<div tiddler="MasterIndex" modifier="HowardLewisShip" modified="200611241944" 
created="200609202214" tags="">Top level concepts within Tapestry 5.\n\nA 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is\nnot a perfect 
match for the notes. That's OK ... as long as the official Maven documentation 
does a good job. It's not reasonable to expect developers to jump back in here 
and dot every i and cross every t if they're already expected to generate good 
Maven documentation.\n\n* PropBinding -- Notes on the workhorse 
&quot;prop:&quot; binding prefix\n* TypeCoercion -- How Tapestry 5 extensibly 
addresses type conversion\n* FormProcessing\n* DynamicPageState -- tracking 
changes to page state during the render\n* EnvironmentalServices -- how 
components cooperate during page render\n* ComponentMixins -- A new fundamental 
way to build web functionality\n* RequestTypes -- Requests, request processing
 , URL formats\n* ComponentTemplates -- Issues about Component Templates\n* 
DeveloperProcedures -- Your a Tapestry committer ... how do you makes 
changes?\n* SmartDefaults -- do even more with event less\n* RandomIdeas -- 
stuff that doesn't fit elsewhere\n* ProblemsNeedingSolutions\n* 
ComponentDocumentation -- Generating Documentation about Components\n* 
TapestryLookAndFeel -- Default CSS\n* [[Assets]]\n\n</div>
+<div tiddler="MasterIndex" modifier="HowardLewisShip" modified="200701051919" 
created="200609202214" tags="">Top level concepts within Tapestry 5.\n\nA 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is\nnot a perfect 
match for the notes. That's OK ... as long as the official Maven documentation 
does a good job. It's not reasonable to expect developers to jump back in here 
and dot every i and cross every t if they're already expected to generate good 
Maven documentation.\n\n* PropBinding -- Notes on the workhorse 
&quot;prop:&quot; binding prefix\n* TypeCoercion -- How Tapestry 5 extensibly 
addresses type conversion\n* FormProcessing\n* DynamicPageState -- tracking 
changes to page state during the render\n* EnvironmentalServices -- how 
components cooperate during page render\n* ComponentMixins -- A new fundamental 
way to build web functionality\n* RequestTypes -- Requests, request processing
 , URL formats\n* ComponentTemplates -- Issues about Component Templates\n* 
DeveloperProcedures -- Your a Tapestry committer ... how do you makes 
changes?\n* SmartDefaults -- do even more with event less\n* RandomIdeas -- 
stuff that doesn't fit elsewhere\n* ProblemsNeedingSolutions\n* 
ComponentDocumentation -- Generating Documentation about Components\n* 
TapestryLookAndFeel -- Default CSS\n* [[Assets]]\n* CaseInsensitivity -- case 
in URLs should not matter\n\n</div>
 <div tiddler="OGNL" modifier="HowardLewisShip" modified="200610071249" 
created="200609202254" tags="">The [[Object Graph Navigation 
Library|http://ognl.org]] was an essential part of Tapestry 4.\n\nOGNL is both 
exceptionally powerful (especially the higher order things it can do, such as 
list selections and projections). However, for the highest\nend sites, it is 
also a performance problem, both because of its heavy use of reflection, and 
because it uses a lot of code inside synchronized blocks.\n\nIt will be 
optional in Tapestry 5. I believe it will not be part of the tapestry-core, but 
may be packaged as tapestry-ognl.\n\nThe &quot;prop:&quot; binding prefix is an 
effective replacement for OGNL in Tapestry 5.   See PropBinding.\n</div>
 <div tiddler="PageRenderRequest" modifier="HowardLewisShip" 
modified="200610081333" created="200610071313" tags="">Page render requests are 
requests used to render a specific page.  //render// is the term meaning to 
compose the HTML response to be sent to the client. Note: HTML is used here 
only as the most common case, other markups are entirely possible.\n\nIn many 
cases, pages are stand-alone.  No extra information in the URL is necesarry to 
render them.  PersistentProperties of the page will factor in to the rendering 
of the page.\n\nIn specific cases, a page needs to render within a particular 
context. The most common example of this is a page that is used to present a 
specific instance of a database persistent entity. In such a case, the page 
must be combined with additional data, in the URL, to identify the specific 
entity to access and render.\n\n! URI 
Format\n\n{{{\n/page-name.html/id\n}}}\n\nHere &quot;page-name&quot; is the 
LogicalPageName for the page. \n\nThe &q
 uot;.html&quot; file extension is used as a delimiter between the page name 
portion of the URI, and the context portion of the URI. This is necessary 
because it is not possible (given the plethora of libraries and folders) to 
determine how many slashes will appear in the URI.\n\nThe context consists of 
one ore more ids (though a single id is the normal case). The id is used to 
identify the specific data to be displayed. Further, a page may require 
multiple ids, which will separated with slashes. Example: 
/admin/DisplayDetail.html/loginfailures/2006\n\nNote that these context values, 
the ids, are simply //strings//. Tapestry 4 had a mechanism, the DataSqueezer, 
that would encode the type of object with its value, as a single string, and 
convert it back. While seemingly desirable, this facility was easy to abuse, 
resulting in long and extremely ugly URIs.\n\nAny further information needed by 
Tapestry will be added to the URI as query parameters. This may include things 
like us
 er locale, persistent page properties, applicaition flow identifiers, or 
anything else we come up with.\n\n! Request Processing\n\nOnce the page and id 
parameters are identified, the corresponding page will be loaded.\n\nTapestry 
will fire two events before rendering the page.\n\nThe first event is of type 
&quot;setupPageRender&quot;.  This allows the page to process the context (the 
set of ids). This typically involves reading objects from an external 
persistent store (a database)\nand storing those objects into transient page 
properties, in expectaion of the render.\n\nThe @SetupPageRender annotation 
marks a method to be invoked when this event is triggered.  The method may take 
one or more strings, or an array of strings, as parameters; these will be\nthe 
context values.  The method will normally return void.  Other values are 
''TBD''. It may also take other simple types, which will be coerced from the 
string [EMAIL PROTECTED] setup(long id)\n{\n  . .
  .\n}\n}}}\n\n\n\nThe second event is of type &quot;pageValidate&quot;.  It 
allows the page to decide whether the page is valid for rendering at this time. 
This most often involves a check to see if the user is logged into the 
application, and has the necessary privileges to display the contents of the 
page.  User identity and privileges are //not// concepts built into Tapestry, 
but are fundamental to the majority of Tapestry applications.</div>
 <div tiddler="ProblemsNeedingSolutions" modifier="HowardLewisShip" 
modified="200701032351" created="200611230401" tags="">There are a few things 
that I'm concerned about.\n\n!Render Complexity\n\nAll those states in the 
render component state machine may be a little much, especially 
~PreBeginRender, ~BeginRender and ~PostBeginRender.  In addition, it doesn't 
work for a case I'm interested in ... for link components, I'd like to use the 
RenderInformals mixin, but also support a disable parameter that turns off the 
&lt;a&gt; tag (but still renders the body).  The state machine currently is set 
up so that returning false in any of the ~BeginRender states skips all the way 
to ~AfterRender, bypassing the template and/or body.\n\nStill don't have a 
perfect solution for the above (it may not be solvable via mixins, which may 
show limitations in the component/mixin model).  I have added a @MixinAfter 
annotation which simplifies the state machine somewhat.</div>

Modified: 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml?view=diff&rev=493155&r1=493154&r2=493155
==============================================================================
--- 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml 
(original)
+++ 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml 
Fri Jan  5 11:35:14 2007
@@ -6,11 +6,29 @@
 <description>The quick and dirty one-stop shopping of random ideas for 
Tapestry 5.</description>
 <language>en-us</language>
 <copyright>Copyright 2007 HowardLewisShip</copyright>
-<pubDate>Wed, 03 Jan 2007 23:55:13 GMT</pubDate>
-<lastBuildDate>Wed, 03 Jan 2007 23:55:13 GMT</lastBuildDate>
+<pubDate>Fri, 05 Jan 2007 19:35:21 GMT</pubDate>
+<lastBuildDate>Fri, 05 Jan 2007 19:35:21 GMT</lastBuildDate>
 <docs>http://blogs.law.harvard.edu/tech/rss</docs>
 <generator>TiddlyWiki 2.0.11</generator>
 <item>
+<title>CaseInsensitivity</title>
+<description>One aspect of &quot;pretty&quot; URLs for Tapestry pages is that 
case should not matter.  The user should be able to manually type a URL without 
respect to case, and have it //just work//.  Turns out that's hard on a number 
of fronts.&lt;br /&gt;&lt;br /&gt;! Page Names&lt;br /&gt;&lt;br /&gt;In 
Tapestry 4 and in the current Tapestry 5 code base, that is a problem.  
Tapestry starts with a page name, and uses that to hunt around and locate the 
page class and from there, the page template, etc.&lt;br /&gt;&lt;br /&gt;That 
hunting around tends to be problematic, because ClassLoader.getResource() is 
case //specific//.  In addition, ClassLoader doesn't directly provide any way 
to introspect the available classes.&lt;br /&gt;&lt;br /&gt;You'd think that 
you could, as a page is first accesssed, record its name in a case insensitve 
cache somewhere.  However, that doesn't work.  First, in a cluster, the server 
handling the request may simply never have handled a request 
 for that page before, so it won't have an up-to date cache.  Likewise, after a 
server restart, existing requests (possibly cached in a browser's bookmarks) 
&lt;br /&gt;&lt;br /&gt;However, I've been doing some research.  
ClassLoader.getResources() , passed a folder name (such as 
&quot;org/example/myapp/pages/&quot;) will yield one or more URLs for the 
folders.  Some of these will be URLs for file systems, some will be URLs for 
JARs.  You can differentiate by the value returned from 
URL.openConnection().&lt;br /&gt;&lt;br /&gt;For file system URLs, opening the 
stream provides a list of the files and folders for that package.  Using this, 
we can identify the protential classes, and identify sub-folders/sub-packages 
to recursively scan.&lt;br /&gt;&lt;br /&gt;For JAR URLs, we can cast to 
JARURLConnection and obtain the JarFile instance for the entire JAR.  From 
there we can obtain a list of entries.&lt;br /&gt;&lt;br /&gt;Combining these 
two approaches should allow us, at appli
 cation startup, to locate all page instances.  We'll be able to build a 
case-insensitive mapping from logical page name to Java class name.&lt;br 
/&gt;&lt;br /&gt;! Component Ids&lt;br /&gt;&lt;br /&gt;Component ids and id 
paths show up in some URLs (primarily action URLs, but even so). As currently 
implemented, ids are case sensitive. With some work, it should be possible to 
make accessing a component by its id, or id path, case insensitive.  This 
should include errors if two components have the same case-insensitive 
id.&lt;br /&gt;&lt;br /&gt;! Query Parameters&lt;br /&gt;&lt;br /&gt;Not sure 
this is as relevant, because the types of URLs that matter will usually not 
include any query parameters.  In terms of form submissions ... well, the 
entire client side is wired case sensitivly, so making form submissions case 
inensitive seems like a useless exercise.</description>
+<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#CaseInsensitivity</link>
+<pubDate>Fri, 05 Jan 2007 19:34:38 GMT</pubDate>
+</item>
+<item>
+<title>MasterIndex</title>
+<description>Top level concepts within Tapestry 5.&lt;br /&gt;&lt;br /&gt;A 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is&lt;br /&gt;not a 
perfect match for the notes. That's OK ... as long as the official Maven 
documentation does a good job. It's not reasonable to expect developers to jump 
back in here and dot every i and cross every t if they're already expected to 
generate good Maven documentation.&lt;br /&gt;&lt;br /&gt;* PropBinding -- 
Notes on the workhorse &quot;prop:&quot; binding prefix&lt;br /&gt;* 
TypeCoercion -- How Tapestry 5 extensibly addresses type conversion&lt;br 
/&gt;* FormProcessing&lt;br /&gt;* DynamicPageState -- tracking changes to page 
state during the render&lt;br /&gt;* EnvironmentalServices -- how components 
cooperate during page render&lt;br /&gt;* ComponentMixins -- A new fundamental 
way to build web functionality&lt;br /&gt;* RequestTypes -- Requests, requ
 est processing, URL formats&lt;br /&gt;* ComponentTemplates -- Issues about 
Component Templates&lt;br /&gt;* DeveloperProcedures -- Your a Tapestry 
committer ... how do you makes changes?&lt;br /&gt;* SmartDefaults -- do even 
more with event less&lt;br /&gt;* RandomIdeas -- stuff that doesn't fit 
elsewhere&lt;br /&gt;* ProblemsNeedingSolutions&lt;br /&gt;* 
ComponentDocumentation -- Generating Documentation about Components&lt;br 
/&gt;* TapestryLookAndFeel -- Default CSS&lt;br /&gt;* [[Assets]]&lt;br /&gt;* 
CaseInsensitivity -- case in URLs should not matter&lt;br /&gt;&lt;br 
/&gt;</description>
+<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#MasterIndex</link>
+<pubDate>Fri, 05 Jan 2007 19:19:59 GMT</pubDate>
+</item>
+<item>
+<title>ComponentTemplates</title>
+<description>There are some issues related to component templates.&lt;br 
/&gt;&lt;br /&gt;Firstly, people are really interested in seeing the return of 
InvisibleInstrumentation.  =That is coming.= That is now available.&lt;br 
/&gt;&lt;br /&gt;Secondly, the idea that templates are well-formed XML 
documents is causing some issues.&lt;br /&gt;&lt;br /&gt;The problem is related 
to entities and doctypes.&lt;br /&gt;&lt;br /&gt;Unless you provide a doctype 
for the template, 
[[entities|http://www.htmlhelp.com/reference/html40/entities/]] don't work; 
they result in template parse errors.&lt;br /&gt;&lt;br /&gt;If you provide a 
standard doctype, say&lt;br /&gt;{{{&lt;br /&gt; &lt;!DOCTYPE HTML PUBLIC 
&quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;&lt;br /&gt;            
&quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;&lt;br /&gt;}}}&lt;br 
/&gt;&lt;br /&gt;You also get parse errors, because the DTD does some odd 
things with comments that the Java SAX parser doesn't seem to 
 understand.&lt;br /&gt;&lt;br /&gt;I've had better luck with the XHTML 
doctype:&lt;br /&gt;{{{&lt;br /&gt;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD 
XHTML 1.0 Transitional//EN&quot;&lt;br 
/&gt;&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;&lt;br
 /&gt;}}}&lt;br /&gt;&lt;br /&gt;But this doesn't render quite the way I want 
it to.&lt;br /&gt;&lt;br /&gt;Further, entities in the text are converted to 
unicode by the parser, then converted to //numeric// entities on output.  Not 
quite WYSIWYG and potentially confusing.&lt;br /&gt;&lt;br /&gt;It may be 
necessary to discard SAX and build a limited XML parser that allows entities to 
be passed through unchanged (they would become a special type of document 
token).&lt;br /&gt;&lt;br /&gt;Lastly, the question is how to get the correct 
DOCTYPE into the rendered output, espcially in the common case that a Border 
component provides the outer tags, as is common in Tapestry 4.  This may have 
to be configured as a ann
 otation on page classes.&lt;br /&gt;&lt;br /&gt;! Template Location&lt;br 
/&gt;&lt;br /&gt;Concensus is building that templates should //not//  have a  
{{{.html}}} extension, but something specific to Tapestry, perhaps {{{.tap}}} 
or {{{.tsp}}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Further, there are invalid, 
but present, security concerns that the templates should live on the classpath 
or in WEB-INF, but not in the root folder.  Both of these issues would simplify 
things for Tapestry.&lt;br /&gt;</description>
+<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentTemplates</link>
+<pubDate>Fri, 05 Jan 2007 19:19:01 GMT</pubDate>
+</item>
+<item>
 <title>SmartDefaults</title>
 <description>As great as the annotations are, allowing things to work without 
the annotations could be even better.&lt;br /&gt;&lt;br /&gt;!Event handler 
methods&lt;br /&gt;&lt;br /&gt;Methods with the prefix &quot;on&quot; could 
automatically be considered event handler methods.  The string after the 
prefix, converted to lower case, would be the event type.  We could even add 
&quot;from//~ComponentId//&quot; to the end.  Examples (with annotation 
equivalents):&lt;br /&gt;&lt;br /&gt;* onSubmit  --&gt; 
@~OnEvent(&quot;submit&quot;)&lt;br /&gt;* onSubmitFromForm --&gt; 
@~OnEvent(value=&quot;submit&quot;, component=&quot;form&quot;)&lt;br /&gt;* 
onUpdateFromSelect  --&gt; @~OnEvent(value=&quot;update&quot;, 
component=&quot;select&quot;)&lt;br /&gt;* onEventFromSelect --&gt; 
@~OnEvent(component=&quot;select&quot;)&lt;br /&gt;&lt;br /&gt;This is now 
implemented.&lt;br /&gt;&lt;br /&gt;!Render phase methods&lt;br /&gt;&lt;br 
/&gt;Naming a method the same as the render phase (with
  the first character lower case).  Again, Tapestry could deduce the phase from 
the method name, as if the annotation were present:&lt;br /&gt;&lt;br /&gt;* 
beforeRender() --&gt; @~BeforeRender&lt;br /&gt;* beforeRenderBody() --&gt; 
@~BeforeRenderBody&lt;br /&gt;&lt;br /&gt;etc.  Again, the methods don't have 
to be public, they just have to have the correct name. In every other way they 
are the same as annotated render phase methods except that they don't have the 
annotation.&lt;br /&gt;&lt;br /&gt;There may be some minor implications w.r.t. 
render phase method ordering.&lt;br /&gt;&lt;br /&gt;etc.&lt;br /&gt;&lt;br 
/&gt;This is now implemented.&lt;br /&gt;&lt;br /&gt;!Other Ideas&lt;br 
/&gt;&lt;br /&gt;This gets more component specific. I had the idea that a 
~TextField whose id was &quot;userId&quot; might want to edit a property named 
&quot;userId&quot; as the default for when its value parameter is unbound. I 
think to accomplish this, we need the concept of computed bindin
 gs for unbound parameters ... perhaps in the form of methods that return a 
Binding with a name and/or annotation, for example:&lt;br /&gt;&lt;br 
/&gt;{{{&lt;br /&gt;&lt;br /&gt;  @Inject&lt;br /&gt;  private 
ComponentResources _resources;&lt;br /&gt;&lt;br /&gt;  
@Inject(&quot;infrastructure:bindingSource&quot;)&lt;br /&gt;  private 
BindingSource _source;&lt;br /&gt;&lt;br /&gt;  @Parameter&lt;br /&gt;  private 
Object _value;&lt;br /&gt;&lt;br /&gt;  Binding defaultValue()&lt;br /&gt;  
{&lt;br /&gt;    ComponentResources containerResources = 
_resources.getContainer().getComponentResources();&lt;br /&gt;    return 
_source.newBinding(&quot;default value&quot;, containerResources,  
_resources.getId());  &lt;br /&gt;  }&lt;br /&gt;}}}&lt;br /&gt;&lt;br 
/&gt;This is now implemented; very handy for a few things such as 
TextField.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So valueDefault() is invoked if 
the value parameter is not bound.  The component uses its own immediate id 
(&quot;user
 Id&quot;) as the name of a property of its container (typically, the page).  
~ComponentResources does not yet implement getContainer(), but the rest would 
work.&lt;br /&gt;&lt;br /&gt;If this was widespread, there could be even better 
optimizations for it.  Perhaps container resources could just be passed into 
the method as a parameter, to save the code to find it.  Ditto with 
BindingSource.  Once again, rather than come up with complex XML-ese to come up 
with defaults, we're trying to work //with// Java code.&lt;br 
/&gt;</description>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#SmartDefaults</link>
@@ -48,12 +66,6 @@
 <pubDate>Wed, 03 Jan 2007 23:46:00 GMT</pubDate>
 </item>
 <item>
-<title>ComponentTemplates</title>
-<description>There are some issues related to component templates.&lt;br 
/&gt;&lt;br /&gt;Firstly, people are really interested in seeing the return of 
InvisibleInstrumentation.  =That is coming.= That is now available.&lt;br 
/&gt;&lt;br /&gt;Secondly, the idea that templates are well-formed XML 
documents is causing some issues.&lt;br /&gt;&lt;br /&gt;The problem is related 
to entities and doctypes.&lt;br /&gt;&lt;br /&gt;Unless you provide a doctype 
for the template, 
[[entities|http://www.htmlhelp.com/reference/html40/entities/]] don't work; 
they result in template parse errors.&lt;br /&gt;&lt;br /&gt;If you provide a 
standard doctype, say&lt;br /&gt;{{{&lt;br /&gt; &lt;!DOCTYPE HTML PUBLIC 
&quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;&lt;br /&gt;            
&quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;&lt;br /&gt;}}}&lt;br 
/&gt;&lt;br /&gt;You also get parse errors, because the DTD does some odd 
things with comments that the Java SAX parser doesn't seem to 
 understand.&lt;br /&gt;&lt;br /&gt;I've had better luck with the XHTML 
doctype:&lt;br /&gt;{{{&lt;br /&gt;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD 
XHTML 1.0 Transitional//EN&quot;&lt;br 
/&gt;&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;&lt;br
 /&gt;}}}&lt;br /&gt;&lt;br /&gt;But this doesn't render quite the way I want 
it to.&lt;br /&gt;&lt;br /&gt;Further, entities in the text are converted to 
unicode by the parser, then converted to &lt;numeric&gt; entities on output.  
Not quite WYSIWYG and potentially confusing.&lt;br /&gt;&lt;br /&gt;It may be 
necessary to discard SAX and build a limited XML parser that allows entities to 
be passed through unchanged (they would become a special type of document 
token).&lt;br /&gt;&lt;br /&gt;Lastly, the question is how to get the correct 
DOCTYPE into the rendered output, espcially in the common case that a Border 
component provides the outer tags, as is common in Tapestry 4.  This may have 
to be configured as a
  annotation on page classes.</description>
-<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentTemplates</link>
-<pubDate>Wed, 03 Jan 2007 23:44:00 GMT</pubDate>
-</item>
-<item>
 <title>WatchCodeCoverage</title>
 <description>The code coverage tools built into ''mvn site'' are quite useful. 
Right now, overall coverage is at 93%. Keep an eye on code coverage, including 
branch coverage (do you test both outcomes of an if statement?).  Use 
unexecuted code to target your efforts.&lt;br /&gt;&lt;br /&gt;I often do a 
cursory unit test for &quot;normal behavior&quot;, plus more exaustive unit 
tests for error conditions.  I then &quot;back the test up&quot; using an 
integration test (build with [[Selenium]]) to prove that the normal behavior 
case really works.</description>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#WatchCodeCoverage</link>
@@ -72,12 +84,6 @@
 <pubDate>Fri, 24 Nov 2006 19:53:00 GMT</pubDate>
 </item>
 <item>
-<title>MasterIndex</title>
-<description>Top level concepts within Tapestry 5.&lt;br /&gt;&lt;br /&gt;A 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is&lt;br /&gt;not a 
perfect match for the notes. That's OK ... as long as the official Maven 
documentation does a good job. It's not reasonable to expect developers to jump 
back in here and dot every i and cross every t if they're already expected to 
generate good Maven documentation.&lt;br /&gt;&lt;br /&gt;* PropBinding -- 
Notes on the workhorse &quot;prop:&quot; binding prefix&lt;br /&gt;* 
TypeCoercion -- How Tapestry 5 extensibly addresses type conversion&lt;br 
/&gt;* FormProcessing&lt;br /&gt;* DynamicPageState -- tracking changes to page 
state during the render&lt;br /&gt;* EnvironmentalServices -- how components 
cooperate during page render&lt;br /&gt;* ComponentMixins -- A new fundamental 
way to build web functionality&lt;br /&gt;* RequestTypes -- Requests, requ
 est processing, URL formats&lt;br /&gt;* ComponentTemplates -- Issues about 
Component Templates&lt;br /&gt;* DeveloperProcedures -- Your a Tapestry 
committer ... how do you makes changes?&lt;br /&gt;* SmartDefaults -- do even 
more with event less&lt;br /&gt;* RandomIdeas -- stuff that doesn't fit 
elsewhere&lt;br /&gt;* ProblemsNeedingSolutions&lt;br /&gt;* 
ComponentDocumentation -- Generating Documentation about Components&lt;br 
/&gt;* TapestryLookAndFeel -- Default CSS&lt;br /&gt;* [[Assets]]&lt;br 
/&gt;&lt;br /&gt;</description>
-<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#MasterIndex</link>
-<pubDate>Fri, 24 Nov 2006 19:44:00 GMT</pubDate>
-</item>
-<item>
 <title>DynamicPageState</title>
 <description>Tapestry 4 has left tracking of dynamic page state as an exercise 
to the developer.  Mostly, this is done using the ''parameters'' parameter of 
the ~DirectLink component.&lt;br /&gt;&lt;br /&gt;''Update: As I've thought 
this one through, I don't think it is viable outside of Forms. It will end up 
with long URLs and a constant ambiguity about whether each link should include 
or exclude the page state.  So this one is unlikely to get implemented.''&lt;br 
/&gt;&lt;br /&gt;Dynamic page state is anything that isn't inside a persistent 
page property. For the most part, this includes page properties updated by a 
For component&lt;br /&gt;&lt;br /&gt;It seems likely that this information 
could be automatically encoded into ~URLs.  &lt;br /&gt;&lt;br /&gt;I'm 
envisioning a service that accumulates a series of //commands//. Each command 
is used to store a bit of page state. The commands are serializable.  The 
commands are ultimately serialized into a MIME string and attach
 ed as a query parameter to each URL.&lt;br /&gt;&lt;br /&gt;When such a link 
is triggered, the commands are de-serialized and each executed in turn. Only 
when that is finished is any further event processing executed, including 
calling into to user code.&lt;br /&gt;&lt;br /&gt;My outline for this is to 
store a series of tuples; each tuple is a component id plus the command to 
execute.&lt;br /&gt;&lt;br /&gt;{{{&lt;br /&gt;public interface 
ComponentCommand&lt;T&gt;&lt;br /&gt;{&lt;br /&gt;  void execute(T 
component);&lt;br /&gt;}&lt;br /&gt;}}}&lt;br /&gt;&lt;br /&gt;These commands 
should be immutable.&lt;br /&gt;&lt;br /&gt;So a component, such as a For loop 
component, could provide itself and a ComponentCommand instance (probably a 
static inner class) to some kind of PageStateTracker service.&lt;br /&gt;&lt;br 
/&gt;{{{&lt;br /&gt;public interface PageStateTracker&lt;br /&gt;{&lt;br /&gt;  
void &lt;T&gt; addCommand(T component, ComponentCommand&lt;T&gt; 
command);&lt;br /&gt;
 }&lt;br /&gt;}}}&lt;br /&gt;&lt;br /&gt;The commands are kept in the order 
that they are added, except that new commands for the same component 
//replace// previous commands for that component.&lt;br /&gt;&lt;br /&gt;As 
with the Tapestry 4 For component, some mechanism will be needed to store 
object ids inside the URLs (that is, inside the commands serialized into URL 
query parameters) and translate back to //equivalent// objects when the link is 
triggered.&lt;br /&gt;&lt;br /&gt;Dynamic page state outside of a Form will 
overlap with some of the FormProcessing inside the form.</description>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#DynamicPageState</link>
@@ -128,13 +134,6 @@
 <description>Component actions are actions that reflect user interaction with 
a component within a page. Again, this falls into several broad 
categories:&lt;br /&gt;&lt;br /&gt;* Links that perform a server-side action, 
and result in a page refresh, or a new page being displayed.&lt;br /&gt;* Ajax 
style links, which perform a server-side action, and refresh only part of the 
page.&lt;br /&gt;* Forms which perform a server-side action, followed by a page 
refresh (or new page being displayed).&lt;br /&gt;* Ajax style forms, which 
trigger an action, followed by a refresh of part of the page.&lt;br /&gt;* 
Other user interactions, which result in a server side action, and a partial 
page refresh.&lt;br /&gt;&lt;br /&gt;In all of these cases, one or more 
ComponentEvents is fired. The result of ComponentEvent determines whether a 
partial page render or a full page render occurs.&lt;br /&gt;&lt;br /&gt;In the 
later case, a client side redirect is sent, to force the browser to initial 
 a new PageRenderRequest.  This addresses an issue in Tapestry 4, in that 
following a link or form submission, the URL would indicate details about the 
previous page, not the newly displayed page, and clicking the browser refresh 
button could cause a server side operation to occur again (which would often be 
quite undersirable).&lt;br /&gt;&lt;br /&gt;!URI Format&lt;br /&gt;&lt;br 
/&gt;{{{&lt;br /&gt;/page-name.event-type/component-id-path/id&lt;br 
/&gt;}}}&lt;br /&gt;&lt;br /&gt;Here page-name is the LogicalPageName.  The 
event-type is a string that identifies the type of event (and will ultimately 
be used to select an event handler method).  &lt;br /&gt;&lt;br /&gt;The 
component-id-path is a dot-separated series of component ids, used to identify 
a specific component within the overall page.&lt;br /&gt;&lt;br /&gt;The id is 
optional, and may be repeated. The id value or values will be provided to the 
event handler method.&lt;br /&gt;&lt;br /&gt;Example: /Login.submit/form  
 (the URI for a form component on page Login).&lt;br /&gt;&lt;br /&gt;Example: 
/admin/UserProfile/action/menu.delete/37  (component menu.delete of the 
UserProfile page, with an id of 37).&lt;br /&gt;</description>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentActionRequest</link>
 <pubDate>Sun, 08 Oct 2006 13:35:00 GMT</pubDate>
-</item>
-<item>
-<title>RequestTypes</title>
-<description>There are three broad categories of user requests (requests from 
the client web browser):&lt;br /&gt;&lt;br /&gt;* PageRenderRequest -- requests 
to render a specific page, possibly with some configuration&lt;br /&gt;* 
ComponentActionRequest -- requests that trigger behaivor within a specific 
component&lt;br /&gt;* ResourceRequest -- requests that access a resource file 
within the classpath&lt;br /&gt;&lt;br /&gt;Each of these requests has a 
specific URI format.</description>
-<category>request</category>
-<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#RequestTypes</link>
-<pubDate>Sun, 08 Oct 2006 13:34:00 GMT</pubDate>
 </item>
 </channel>
 </rss>


Reply via email to