Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by FilipSAdamsen:
http://wiki.apache.org/tapestry/Tapestry5HowToAddBindingPrefix

The comment on the change is:
Updated text, examples, and code.

------------------------------------------------------------------------------
- In this example we will create our own binding prefix to support array/list 
values directly in template without needing to write a getter method.[[BR]]
+ In this example we will create a list binding prefix to support array/list 
values directly in templates without needing to write getter methods.[[BR]]
- This is tested on (5.0.5), it will most likely be a part of the framework in 
some way, but currently it isn't, and to show how easy it is to extend 
tapestry....[[BR]]
+ This is tested on Tapestry 5.0.14, it will most likely be a part of the 
framework in some way, but currently it isn't.[[BR]]
  
- For example if you want to link your product page, you will write this in 
tempalte :
+ Example: You have a product page, product/view, and you want to be able to 
compare the current product to a list of related products. So you write this in 
your template:
  {{{
- <T:ActionLink page="Product" context="producViewLink">View</T:ActionLink>
- <T:ActionLink page="Product" context="producEditLink">Edit</T:ActionLink>
+ <t:loop t:source="relatedproducts" t:value="relatedproduct">
+   <t:pagelink page="product/compare" context="productcomparecontext">Compare 
with ${relatedproduct.name}</t:pagelink>
+ </t:loop>
  }}}
- and this in your java class
+ And this in your Java class:
  {{{
- public Object[] getProductViewLink(){
+ public Object[] getProductCompareContext(){
-     return new Object[]{product.getId(),"view"};
- }
- public Object[] getProductEditLink(){
-     return new Object[]{product.getId(),"edit"};
+     return new Object[]{ product.getId(), relatedProduct.getId() };
  }
  }}}
  
- After following this example, the java part will not be needed and template 
will look something like this:
+ The list binding prefix simplifies this to:
  {{{
- <T:ActionLink page="Product" 
context="list:product.id,'view'">View</T:ActionLink>
- <T:ActionLink page="Product" 
context="list:product.id,'edit'">Edit</T:ActionLink>
+ <t:loop t:source="relatedproducts" t:value="relatedproduct">
+   <t:pagelink page="product/compare" 
context="list:product.id,relatedproduct.id">Compare with 
${relatedproduct.name}</t:pagelink>
+ </t:loop>
  }}}
  
  
+ Let's implement the list binding prefix.
  
- '''Now the example.'''
- 
- Add this to your !AppModule.java
+ Add this to your !AppModule.java:
  {{{
      public static void contributeBindingSource(
              MappedConfiguration<String, BindingFactory> configuration,
              BindingSource bindingSource)
      {
-         configuration.add("list",new ListBindingFactory(bindingSource));
+         configuration.add("list", new ListBindingFactory(bindingSource));
      }
  }}}
  
- The !ListBindingFactory
+ The !ListBindingFactory:
  {{{
  /**
+  * Factory for list bindings. List bindings parse comma-delimited lists of 
binding expressions into [EMAIL PROTECTED] List lists}
+  * of values. The default binding prefix for each binding expression is prop.
-  * Implementation of the list: binding prefix -- we parse list of bindings
-  * and generate delegate bindings for each element<br>
-  * default binding is prop, except when surrounded with '' or is a numeric 
value ([0-9.]*)
   */
  public class ListBindingFactory implements BindingFactory {
-     private final BindingSource _bindingSource;
  
+   private final BindingSource bindingSource;
+ 
-     public ListBindingFactory(BindingSource source){
+   public ListBindingFactory(BindingSource source) {
-         this._bindingSource = source;
+     this.bindingSource = source;
+   }
+ 
+   public Binding newBinding(String description, ComponentResources container, 
ComponentResources component,
+                             String expression, Location location) {
+     List<Binding> delegates = new ArrayList<Binding>();
+     String[] items = expression.split(",");
+     boolean invariant = true;
+ 
+     for (String item : items) {
+       Binding binding = bindingSource.newBinding(description, container, 
component,
+                                                  BindingConstants.PROP, item, 
location);
+       invariant = invariant && binding.isInvariant();
+       delegates.add(binding);
      }
-     
-     public Binding newBinding(String description, ComponentResources 
container, ComponentResources component,
-             String expression, Location location)
-     {
-         List<Binding> delegates = new ArrayList<Binding>();
-         String[] bindingNames = expression.split(",");
-         boolean isInvariant=true;
-         
-         for (String bindingName : bindingNames){
-             String defaultBinding = TapestryConstants.LITERAL_BINDING_PREFIX;
-             
-             if(bindingName.charAt(0) == '\''){
-                 //translate "'something'" to "literal:something"
-                 bindingName = bindingName.substring(1,bindingName.length()-1);
  
-             }else{
-                 //if value is numeric, we leave literal binding prefix as 
default
-                 for (int i = 0; i < bindingName.length(); i++) {
-                     char ch = bindingName.charAt(i);
-                     if(ch != '.' && !Character.isDigit(ch)){
-                         defaultBinding = 
TapestryConstants.PROP_BINDING_PREFIX; 
-                         break;
-                     }
-                 }
-             }
- 
-             Binding binding = _bindingSource.newBinding(description, 
container, component, defaultBinding, bindingName, location);
-             isInvariant = isInvariant && binding.isInvariant();
-             delegates.add(binding);
-         }
- 
-         return new ListBinding(delegates, isInvariant);
+     return new ListBinding(delegates, invariant);
-     }
+   }
  }
  }}}
  
- The !ListBinding 
+ The !ListBinding :
  {{{
- public class ListBinding extends AbstractBinding{
+ public class ListBinding extends AbstractBinding {
-     private final List<Binding> delegates;
-     private final boolean _invariant;
  
+   private final List<Binding> delegates;
+   private final boolean invariant;
+ 
-     public ListBinding(List<Binding> delegates, boolean invariant) {
+   public ListBinding(List<Binding> delegates, boolean invariant) {
-         this.delegates = delegates;
+     this.delegates = delegates;
-         _invariant = invariant;
+     this.invariant = invariant;
+   }
+ 
+   public Object get() {
+     List<Object> values = new ArrayList<Object>(delegates.size());
+ 
+     for (Binding binding : delegates) {
+       values.add(binding.get());
      }
  
-     public Object get() {
-         Object[] valuesFromDelegates = new Object[delegates.size()];
+     return values;
+   }
  
-         for (int i = 0; i < delegates.size(); i++) {
-             valuesFromDelegates[i] = delegates.get(i).get();
-         }
-         
-         return valuesFromDelegates;
-     }
-     
-     @Override
-     public boolean isInvariant() {
+   public boolean isInvariant() {
-         return _invariant;
+     return invariant;
-     }
+   }
+ 
-     
-     @Override
-     public Class<Object[]> getBindingType() {
+   public Class<List> getBindingType() {
-         return Object[].class;
+     return List.class;
-     }
+   }
  }
  }}}
- !Notice: although we named this binding "list" the value returned is an 
Object array, but tapestry will easily convert between the two. If you like, 
you can easily change this to return "List"[[BR]]
- !Notice#2: you must override isInvariant and "return false" to avoid value 
being cached (in this example we return true if all sub expressions are 
invariant)
+ Notice: You must override isInvariant and return false to avoid the value 
being cached. In this example we return true if all binding expressions are 
invariant.
  
- And that's it, you now have your own binding prefix. It splits the expression 
on "," and each subexpression will be evaluated as it was single binding 
expression (with exception for numeric values and values surrounded with ' ', 
which are prefixed literal).
+ And that's it. You now have a list binding prefix. It splits the expression 
on "," and each subexpression will be evaluated as it was a single binding 
expression.
  
- for example a chart link (similar to chart example on this wiki)
+ For example a chart link - similar to the chart example 
(["Tapestry5HowToCreateASimpleGraphComponent"]) on this wiki - can be used like 
this with the list binding prefix:
  {{{
  <t:chart width="200" height="150" context="list:'aa',22,'bb',5" 
popup="popupSize"/>
  <t:chart width="200" height="150" context="list:'aa',29,'bb',30,'cc',10" 
popup="popupSize"/>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to