[CONF] Apache Tapestry Page And Component Classes FAQ

2014-03-02 Thread Bob Harner (Confluence)






 {footnote}Tapestry would also create an alias . (Tapestry would also create an alias account/view,   by   stripping   off   the   redundant   account   suffix.   Either   name   is   equally   valid   in   your   code,   and   Tapestry   will   use   the   shorter   name,   account/view   in   URLs.{footnote})In addition, it is possible to define additional root packages for the application:







  


Bob Harner edited the page:
 


Page And Component Classes FAQ   




 Comment: Fixed footnote problem by doing away with it. 


...
You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have root-package.pages.account.ViewAccount, which would have the page name account/viewaccount







 Wiki Markup






 Code Block








controls
true


linenumbers
true


 




 

public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping(, com.example.app.tasks));
   configuration.add(new LibraryMapping(, com.example.app.chat));
}
 


 ...



 Code Block








controls
true


linenumbers
true


 




 

@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {

[CONF] Apache Tapestry Page And Component Classes FAQ

2012-06-29 Thread confluence







Page And Component Classes FAQ
Page edited by Howard M. Lewis Ship


 Changes (1)
 




...
Tapestry tranforms your class at runtime. It tends to build a large constructor for the class instance. Further, an instance of the class is useless by itself, it must be wired together with its template and its sub-components.   
On top of that, Tapestry keeps just once instance of each page in memory (since 5.2). It reworks the bytecode of the components so that a single instance can be shared across multiple request handling threads.  
{scrollbar}  
...


Full Content

Templating and Markup FAQFrequently Asked QuestionsForms and Form Components FAQ

Page And Component Classes

Main article: Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages classes must be in the root-package.pages package; components must be in the root-package.components.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.

Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code).

The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they can't be accessed from the client however; a specific rule prevents access to files with the .tml extension).

It is possible that this feature may be removed in a later release. It is preferred that page templates be stored on the classpath, like component templates.

How do I store my page classes in a different package?

Tapestry is very rigid here; you can't. Page classes must go in root-package.pages, component classes in root-package.components, etc.

You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have root-package.pages.account.ViewAccount, which would have the page name "account/viewaccount"




1




In addition, it is possible to define additional root packages for the application:



public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping("", "com.example.app.tasks"));
   configuration.add(new LibraryMapping("", "com.example.app.chat"));
}



LibraryMappings are used to resolve a library prefix to one or more package names.  The empty string represents the application itself; the above example adds two additional root packages; you might see additional pages under com.example.app.tasks.pages, for example.

Tapestry doesn't check for name collisions, and the order the packages are searched for pages and components is not defined. In general, if you can get by with a single root package for your application, that is better.

Why do my instance variables have to be private?

In Tapestry 5.3.1 and earlier all instance variables must be private. Starting in version 5.3.2 instance variables can also be protected or package private (that is, not public), or they can even be public if final or annotated with the deprecated @Retain.

Tapestry does a large amount of transformation to your simple POJO classes as it loads them into memory. In many cases, it must locate every read or write of an instance variable and change its behavior; for example, reading a field that is a component parameter will cause a property of the containing page or component to be read.

Restricting the scope of fields allows Tapestry to do the necessary processing one class at a time, as needed, at runtime. More complex Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but they require a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up in the rendered markup?

Getting informal parameters to work is in two steps.  First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support informal parameters, using the SupportsInformalParameters annotation. Here's a hypothetical component that displays an image based on the value of a Image object (presumably, a database entity):



@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {
writer.element("img", "src", image.toClientURL(), "class", "db-image");

resources.renderInformalParameters(writer);


[CONF] Apache Tapestry Page And Component Classes FAQ

2011-02-21 Thread confluence







Page And Component Classes FAQ
Page edited by Howard M. Lewis Ship


 Changes (5)
 




h2. Page And Component Classes 
{scrollbar} 
 
h2. Page And Component Classes  
Main article: [Component Classes]  
...
Theres very little difference between the two. Pages classes must be in the _root-package_.{{pages}} package; components must be in the _root-package_.{{components}}.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.  
Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code). 
 The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they cant be accessed from the client however; a specific rule prevents access to files with the {{.tml}} extension). 
...
Tapestry tranforms your class at runtime. It tends to build a large constructor for the class instance. Further, an instance of the class is useless by itself, it must be wired together with its template and its sub-components.   
{scrollbar}  
  
...


Full Content

Templating and Markup FAQFrequently Asked QuestionsForms and Form Components

Page And Component Classes

Main article: Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages classes must be in the root-package.pages package; components must be in the root-package.components.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.

Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code).

The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they can't be accessed from the client however; a specific rule prevents access to files with the .tml extension).

It is possible that this feature may be removed in a later release. It is preferred that page templates be stored on the classpath, like component templates.

How do I store my page classes in a different package?

Tapestry is very rigid here; you can't. Page classes must go in root-package.pages, component classes in root-package.components, etc.

You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have _root-package.pages.account.ViewAccount, which would have the page name "account/viewaccount"




1




In addition, it is possible to define additional root packages for the application:



public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping("", "com.example.app.tasks"));
   configuration.add(new LibraryMapping("", "com.example.app.chat"));
}



LibraryMappings are used to resolve a library prefix to one or more package names.  The empty string represents the application itself; the above example adds two additional root packages; you might see additional pages under com.example.app.tasks.pages, for example.

Tapestry doesn't check for name collisions, and the order the packages are searched for pages and components is not defined. In general, if you can get by with a single root package for your application, that is better.

Why do my instance variables have to be private?

Tapestry does a large amount of transformation to your simple POJO classes as it loads them into memory. In many cases, it must locate every read or write of an instance variable and change its behavior; for example, reading a field that is a component parameter will cause a property of the containing page or component to be read.

Limiting fields to private means that Tapestry can do the necessary processing one class at a time, as needed, at runtime. More complex Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but requires a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up in the rendered markup?

Getting informal parameters to work is in two steps.  First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support informal 

[CONF] Apache Tapestry Page And Component Classes FAQ

2011-02-21 Thread confluence







Page And Component Classes FAQ
Page edited by Howard M. Lewis Ship


 Changes (1)
 




...
Theres very little difference between the two. Pages classes must be in the _root-package_.{{pages}} package; components must be in the _root-package_.{{components}}.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.  
Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code). 
 The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they cant be accessed from the client however; a specific rule prevents access to files with the {{.tml}} extension). 
...


Full Content

Templating and Markup FAQFrequently Asked QuestionsForms and Form Components

Page And Component Classes

Main article: Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages classes must be in the root-package.pages package; components must be in the root-package.components.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.

Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code).

The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they can't be accessed from the client however; a specific rule prevents access to files with the .tml extension).

It is possible that this feature may be removed in a later release. It is preferred that page templates be stored on the classpath, like component templates.

How do I store my page classes in a different package?

Tapestry is very rigid here; you can't. Page classes must go in root-package.pages, component classes in root-package.components, etc.

You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have _root-package.pages.account.ViewAccount, which would have the page name "account/viewaccount"




1




In addition, it is possible to define additional root packages for the application:



public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping("", "com.example.app.tasks"));
   configuration.add(new LibraryMapping("", "com.example.app.chat"));
}



LibraryMappings are used to resolve a library prefix to one or more package names.  The empty string represents the application itself; the above example adds two additional root packages; you might see additional pages under com.example.app.tasks.pages, for example.

Tapestry doesn't check for name collisions, and the order the packages are searched for pages and components is not defined. In general, if you can get by with a single root package for your application, that is better.

Why do my instance variables have to be private?

Tapestry does a large amount of transformation to your simple POJO classes as it loads them into memory. In many cases, it must locate every read or write of an instance variable and change its behavior; for example, reading a field that is a component parameter will cause a property of the containing page or component to be read.

Limiting fields to private means that Tapestry can do the necessary processing one class at a time, as needed, at runtime. More complex Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but requires a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up in the rendered markup?

Getting informal parameters to work is in two steps.  First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support informal parameters, using the SupportsInformalParameters annotation. Here's a hypothetical component that displays an image based on the value of a Image object (presumably, a database entity):



@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {
writer.element("img", "src", image.toClientURL(), "class", "db-image");


[CONF] Apache Tapestry Page And Component Classes FAQ

2011-02-21 Thread confluence







Page And Component Classes FAQ
Page edited by Howard M. Lewis Ship


 Changes (1)
 




{scrollbar}  
h2. Page And Component Classes 
 Main article: [Component Classes] 
...


Full Content

Templating and Markup FAQFrequently Asked QuestionsForms and Form Components

Page And Component Classes

Main article: Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages classes must be in the root-package.pages package; components must be in the root-package.components.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.

Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code).

The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they can't be accessed from the client however; a specific rule prevents access to files with the .tml extension).

It is possible that this feature may be removed in a later release. It is preferred that page templates be stored on the classpath, like component templates.

How do I store my page classes in a different package?

Tapestry is very rigid here; you can't. Page classes must go in root-package.pages, component classes in root-package.components, etc.

You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have _root-package.pages.account.ViewAccount, which would have the page name "account/viewaccount"




1




In addition, it is possible to define additional root packages for the application:



public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping("", "com.example.app.tasks"));
   configuration.add(new LibraryMapping("", "com.example.app.chat"));
}



LibraryMappings are used to resolve a library prefix to one or more package names.  The empty string represents the application itself; the above example adds two additional root packages; you might see additional pages under com.example.app.tasks.pages, for example.

Tapestry doesn't check for name collisions, and the order the packages are searched for pages and components is not defined. In general, if you can get by with a single root package for your application, that is better.

Why do my instance variables have to be private?

Tapestry does a large amount of transformation to your simple POJO classes as it loads them into memory. In many cases, it must locate every read or write of an instance variable and change its behavior; for example, reading a field that is a component parameter will cause a property of the containing page or component to be read.

Limiting fields to private means that Tapestry can do the necessary processing one class at a time, as needed, at runtime. More complex Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but requires a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up in the rendered markup?

Getting informal parameters to work is in two steps.  First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support informal parameters, using the SupportsInformalParameters annotation. Here's a hypothetical component that displays an image based on the value of a Image object (presumably, a database entity):



@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {
writer.element("img", "src", image.toClientURL(), "class", "db-image");

resources.renderInformalParameters(writer);

writer.end();

return false;
  }
}




Why do I get java.lang.LinkageError when I invoke public methods of my page classes?

In Tapestry, there are always two versions of page (or component) classes.  The first version is the version loaded by standard class loader: the simple POJO version that you wrote.

The second version is much more complicated; it's the transformed version of your code, with lots of extra hooks and changes to allow the class to operate inside Tapestry. This includes implementing new interfaces and methods, adding new constructors, and changing access to existing fields and methods.

Although these two classes have the same fully 

[CONF] Apache Tapestry Page And Component Classes FAQ

2011-01-17 Thread confluence







Page And Component Classes FAQ
Page edited by Bob Harner


Comment:
Renamed so it's name makes sense as a stand-alone page, e.g. when appearing in "Related Articles" boxes


 Changes (0)
 




...


Full Content

Page And Component Classes

Main article: Component Classes

What's the difference between a page and a component?

There's very little difference between the two. Pages classes must be in the root-package.pages package; components must be in the root-package.components.  Pages may provide event handlers for certain page-specific events (such as activate and passivate).  Components may have parameters.

Other than that, they are more equal than they are different. They may have templates or may render themselves in code (pages usually have a template, components are more likely to render only in code).

The major difference is that Tapestry page templates may be stored in the web context directory, as if they were static files (they can't be accessed from the client however; a specific rule prevents access to files with the .tml extension).

It is possible that this feature may be removed in a later release. It is preferred that page templates be stored on the classpath, like component templates.

How do I store my page classes in a different package?

Tapestry is very rigid here; you can't. Page classes must go in root-package.pages, component classes in root-package.components, etc.

You are allowed to create sub-packages, to help organize your code better and more logically. For example, you might have _root-package.pages.account.ViewAccount, which would have the page name "account/viewaccount"




1




In addition, it is possible to define additional root packages for the application:



public static void contributeComponentClassResolver(ConfigurationLibraryMapping configuration) {
   configuration.add(new LibraryMapping("", "com.example.app.tasks"));
   configuration.add(new LibraryMapping("", "com.example.app.chat"));
}



LibraryMappings are used to resolve a library prefix to one or more package names.  The empty string represents the application itself; the above example adds two additional root packages; you might see additional pages under com.example.app.tasks.pages, for example.

Tapestry doesn't check for name collisions, and the order the packages are searched for pages and components is not defined. In general, if you can get by with a single root package for your application, that is better.

Why do my instance variables have to be private?

Tapestry does a large amount of transformation to your simple POJO classes as it loads them into memory. In many cases, it must locate every read or write of an instance variable and change its behavior; for example, reading a field that is a component parameter will cause a property of the containing page or component to be read.

Limiting fields to private means that Tapestry can do the necessary processing one class at a time, as needed, at runtime. More complex Aspect Orient Programming systems such as AspectJ can perform similar transformations (and much more complex ones), but requires a dedicated build step (or the introduction of a JVM agent).

Why don't my informal parameters show up in the rendered markup?

Getting informal parameters to work is in two steps.  First, you must make a call to the ComponentResources.renderInformalParameters() method, but just as importantly, you must tell Tapestry that you want the component to support informal parameters, using the SupportsInformalParameters annotation. Here's a hypothetical component that displays an image based on the value of a Image object (presumably, a database entity):



@SupportsInformalParameters
public class DBImage
{
  @Parameter(required=true)
  private Image image;

  @Inject
  private ComponentResources resources;

  boolean beginRender(MarkupWriter writer)
  {
writer.element("img", "src", image.toClientURL(), "class", "db-image");

resources.renderInformalParameters(writer);

writer.end();

return false;
  }
}




Why do I get java.lang.LinkageError when I invoke public methods of my page classes?

In Tapestry, there are always two versions of page (or component) classes.  The first version is the version loaded by standard class loader: the simple POJO version that you wrote.

The second version is much more complicated; it's the transformed version of your code, with lots of extra hooks and changes to allow the class to operate inside Tapestry. This includes implementing new interfaces and methods, adding new constructors, and changing access to existing fields and methods.

Although these two classes have the same fully qualified class name, they are distinct classes because they are