Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
{float:right|background=#eee}
{contentbylabel:title=Related Articles|showLabels=false|showSpace=false|space=@self|labels=expressions,component-classes,component-templates,parameters}
{float}

Component Parameters

Table of Contents

Component parameters are the primary means for a component instance and its container to communicate with each other. Parameters are used to configure component instances.

...

A special prefix, "inherit:", is used to support Inherited Parameter Bindings.

Render

...

Variables: Bindings

Components can have any number of render variables. Render variables are named values with no specific type (they are ultimately stored in a Map). Render variables are useful for holding simple values, such as loop indices, that need to be passed from one component to another.

...

Tapestry will adjust the URL of the image so that it is processed by Tapestry, not the servlet container. It will gain a URL that includes the application's version number, it will have a far-future expires header, and (if the client supports it) its content will be compressed before being sent to the client.

Don't use the ${...} syntax!

Main Article: Component Templates#Expansions

You generally should not use the Template Expansion syntax, ${...}, within component parameter bindings. Doing so results in the property inside the braces being converted to an (immutable) string, and will therefore result in a runtime exception if your component needs to update the value (whenever the default or explicit binding prefix is prop: or var:, since such component parameters are two-way bindings).

...


<t:textfield t:id="color" value="color"/>

...


<t:textfield t:id="color" value="${color}"/>

The general rule is, only use the ${...} syntax in non-Tapestry-controlled locations in your template, such as in attributes of ordinary HTML elements and in plain-text areas of your template.

...

@Parameter annotation

Required Parameters

Parameters that are required must be bound. A runtime exception occurs if a component has unbound required parameters.

Code Block
public class Component{

  @Parameter(required = true)
  private String parameter;

}
Tip

Sometimes a parameter is marked as required, but may still be omitted if the underlying value is provided by some other means. This is the case, for example, with the Select component's value parameter, which may have its underlying value set by contributing a ValueEncoderSource. Be sure to read the component's parameter documentation carefully. Required simply enables checks that the parameter is bound, it does not mean that you must supply the binding in the template (or @Component annotation).

Optional Parameters

Parameters are optional unless they are marked as required.

You may set a default value for optional parameters using the value element of the @Parameter annotation. In the Count component above, the start parameter has a default value of 1. That value is used unless the start parameter is bound, in which case, the bound value supersedes the default.

Anchor
Inherited_Parameter_Bindings
Inherited_Parameter_Bindings

Parameter Binding Defaults

The @Parameter annotation's value element can be used to specify a binding expression that will be the default binding for the parameter if otherwise left unbound. Typically, this is the name of a property that that will compute the value on the fly.

Code Block
java
java

@Parameter(value="defaultMessage") // or, equivalently, @Parameter("defaultMessage")
private String message;

@Parameter(required=true)
private int maxLength;

public String getDefaultMessage(){ 
	return String.format("Maximum field length is %d.", maxLength);
}

As elsewhere, you may use a prefix on the value. A common prefix to use is the "message:" prefix, to access a localized message.

Parameter Caching

Reading a parameter value can be marginally expensive (because of type coercion). Therefore, it makes sense to cache the parameter value, at least while the component is actively rendering itself.

In rare cases, it is desirable to defeat the caching; this can be done by setting the cache() attribute of the @Parameter annotation to false.

Don't use the ${...} syntax!

Main Article: Component Templates#Expansions

You generally should not use the Template Expansion syntax, ${...}, within component parameter bindings. Doing so results in the property inside the braces being converted to an (immutable) string, and will therefore result in a runtime exception if your component needs to update the value (whenever the default or explicit binding prefix is prop: or var:, since such component parameters are two-way bindings).

Section
Column
Code Block
xml
xml
titleThis is right

<t:textfield t:id="color" value="color"/>
Column
Code Block
xml
xml
titleThis is wrong

<t:textfield t:id="color" value="${color}"/>

The general rule is, only use the ${...} syntax in non-Tapestry-controlled locations in your template, such as in attributes of ordinary HTML elements and in plain-text areas of your template.

Section
Column
Code Block
xml
xml
titleThis is right

<img src="${context:images/banner.png}"/>
Column
Code Block
xml
xml
titleThis is wrong

<img src="context:images/banner.png"/>

Informal Parameters

Some components support informal parameters, additional parameters beyond the formally defined parameters. Informal parameters will be rendered into the output as additional attributes on the tag rendered by the component. Generally speaking, components that have a 1:1 relationship with a particular HTML tag (such as <TextField> and <input> will support informal parameters.

Only components whose class is annotated with @SupportsInformalParameters will support informal parameters. Tapestry silently drops informal parameters that are specified for components that do not have this annotation.

Informal parameters are often used to set the CSS class of an element, or to specify client-side event handlers.

The default binding prefix for informal parameters depends on where the parameter binding is specified. If the parameter is bound inside a Java class, within the @Component annotation, then the default binding prefix is "prop:". If the parameter is bound inside the component template, then the default binding prefix is "literal:". This reflects the fact that a parameter specified in the Java class, using the annotation, is most likely a computed value, whereas a value in the template should simply be copied, as is, into the result HTML stream.

If your component should render informal parameters, just inject the ComponentResources for your component and invoke the renderInformalParameters() method. See Supporting Informal Parameters for an example of how to do this.

Parameters Are Bi-Directional

Parameters are not simply variables; each parameter represents a connection, or binding, between a component and a property of its container. When using the prop: binding prefix, the component can force changes into a property of its container, just by assigning a value to its own instance variable.

Code Block
xml
xml

<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
    <p> Countdown:
        <t:count start="5" end="1" result="index">
          ${index} ...
        </t:count>
    </p>
</t:layout>

Because the Count component updates its result parameter (the result field), the index property of the containing component is updated. Inside the Count's body, we output the current value of the index property, using the expansion ${index}. The resulting output will look something like:

Code Block
xml
xml

  <p> Countdown: 5 ... 4 ... 3 ... 2 ... 1 ... </p>

(Though the whitespace will be quite different.)

The relevant part is that components can read fixed values, or live properties of their container, and can change properties of their container as well.

...


<img src="${context:images/banner.png}"/>

...


<img src="context:images/banner.png"/>

Informal Parameters

Some components support informal parameters, additional parameters beyond the formally defined parameters. Informal parameters will be rendered into the output as additional attributes on the tag rendered by the component. Generally speaking, components that have a 1:1 relationship with a particular HTML tag (such as <TextField> and <input> will support informal parameters.

Only components whose class is annotated with @SupportsInformalParameters will support informal parameters. Tapestry silently drops informal parameters that are specified for components that do not have this annotation.

Informal parameters are often used to set the CSS class of an element, or to specify client-side event handlers.

The default binding prefix for informal parameters depends on where the parameter binding is specified. If the parameter is bound inside a Java class, within the @Component annotation, then the default binding prefix is "prop:". If the parameter is bound inside the component template, then the default binding prefix is "literal:". This reflects the fact that a parameter specified in the Java class, using the annotation, is most likely a computed value, whereas a value in the template should simply be copied, as is, into the result HTML stream.

If your component should render informal parameters, just inject the ComponentResources for your component and invoke the renderInformalParameters() method. See Supporting Informal Parameters for an example of how to do this.

Parameters Are Bi-Directional

Parameters are not simply variables; each parameter represents a connection, or binding, between a component and a property of its container. When using the prop: binding prefix, the component can force changes into a property of its container, just by assigning a value to its own instance variable.

...


<t:layout xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
    <p> Countdown:
        <t:count start="5" end="1" result="index">
          ${index} ...
        </t:count>
    </p>
</t:layout>

Because the Count component updates its result parameter (the result field), the index property of the containing component is updated. Inside the Count's body, we output the current value of the index property, using the expansion ${index}. The resulting output will look something like:

...


  <p> Countdown: 5 ... 4 ... 3 ... 2 ... 1 ... </p>

(Though the whitespace will be quite different.)

The relevant part is that components can read fixed values, or live properties of their container, and can change properties of their container as well.

Required Parameters

Parameters that are required must be bound. A runtime exception occurs if a component has unbound required parameters.

Tip

Sometimes a parameter is marked as required, but may still be omitted if the underlying value is provided by some other means. This is the case, for example, with the Select component's value parameter, which may have its underlying value set by contributing a ValueEncoderSource. Be sure to read the component's parameter documentation carefully. Required simply enables checks that the parameter is bound, it does not mean that you must supply the binding in the template (or @Component annotation).

Optional Parameters

Parameters are optional unless they are marked as required.

You may set a default value for optional parameters using the value element of the @Parameter annotation. In the Count component above, the start parameter has a default value of 1. That value is used unless the start parameter is bound, in which case, the bound value supersedes the default.

AnchorInherited_Parameter_BindingsInherited_Parameter_Bindings

Inherited Parameter Bindings

...

Code Block
xml
xml
titleLayout.tml
<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">

	<div t:type="title" t:title="inherit:menuTitle"></div>

	<t:body />

</t:container>
Code Block
javajava
titleTitle.java

package org.example.app.components;

import org.apache.tapestry5.annotations.Parameter;

public class Title {

	@Parameter
	private String title;

}

Parameter Binding Defaults

The @Parameter annotation's value element can be used to specify a binding expression that will be the default binding for the parameter if otherwise left unbound. Typically, this is the name of a property that that will compute the value on the fly.

Example:

...


  @Parameter(value="defaultMessage")      // or, equivalently, @Parameter("defaultMessage")
  private String message;

  @Parameter(required=true)
  private int maxLength;

  public String getDefaultMessage()
  {
    return String.format("Maximum field length is %d.", _maxLength);
  }
	<t:body />

</t:container>
Code Block
java
java
titleTitle.java

package org.example.app.components;

import org.apache.tapestry5.annotations.Parameter;

public class Title {

	@Parameter
	private String title;

}

...

Computed Parameter Binding Defaults

...

TODO: This seems contradictory. What does it mean to update an unbound component parameter when the component is not rendering?

Parameter Caching

Reading a parameter value can be marginally expensive (because of type coercion). Therefore, it makes sense to cache the parameter value, at least while the component is actively rendering itself.

In rare cases, it is desirable to defeat the caching; this can be done by setting the cache() attribute of the @Parameter annotation to false.

Parameter Type Coercion

Tapestry includes a mechanism for coercing types automatically. Most often, this is used to convert literal strings into appropriate values, but in many cases, more complex conversions will occur.

...