On Wed, May 26, 2021 at 7:00 AM Numa Schmeder <n...@dfacto.ch> wrote:
> Hello, > Hello! > It seems method with varargs doesn’t work with property expression. > If I put the following property expression, I get an error: Message > doesn’t have a public “format" method. > ${messages.format('priceFromPerGuest', travelMinPricePerGuest, > displayedCurrency)} > But If I write it as follow is works: > messages.format('priceFromPerGuest', [travelMinPricePerGuest, > displayedCurrency]) > > Is this a bug ? > I don't think so. Varargs, as far as I know, are implemented in Java purely as a compiler feature, and Tapestry prop binding expressions work at runtime, so it only sees method(arg, Object[] varargs) for something declared as method(arg1, Object... varargs). > Tapestry property expression is a bit limiting, particularly in conditions > where you can’t have logical expression as: test=“size > 10” > Let me be pedantic here. :) Yes, it's the prop binding, short for property. Being based on properties, it can be very fast, since Tapestry-IoC and Tapestry can create code that calls properties without using reflection. This binding was never supposed to have logical expressions. > I know the rational is to keep property expression as simple as possible, > but having some logic expressed in the template is not that bad, Having logic expressed in the template is completely against the way the prop binding was created and implemented, so I suggest you to not try or want to do something one given tool doesn't want. > because it’s in context ans sometimes makes more sense than having > everything in java code. Here comes one of the beauties of Tapestry: it's incredibly flexible and customizable. You can create your own bindings with any logic you want! If you don't know how, please let us know and we'll show you how. By the way, ChenilleKit, a third-party Tapestry add-on library, provides an OGNL binding that provides a lot of expression power (but uses reflection at runtime). > Also if you work a lot with collection of objects, you have to create a > property for each type of element in the collections, the “var” keyword is > not powerful to be used in complex property expressions. > Exemple, this won’t work, but it would be very practical: > <t:loop source=“countries” value=“var:country”> > ${var:country.getName(locale)} - ${getPopulation(var:country)} > </t:loop> > > And if you use a generic property tempValue that you could reuse in > different places, it won’t work because all conduits will be based on the > Object Type and not Country type. > > @Property > Object tempValue > > <t:loop source=“countries” value=“var: tempValue”> > ${tempValue.getName(locale)} - ${getPopulation(tempValue)} > </t:loop> > > Could we find a solution to avoir creating a lot of fields for all loops ? > The var binding only really accepts strings well because it doesn't use reflection and being able to support arbitrary types would need reflection. > > Thank you for your help, > > Best! > > > <http://www.dfacto.ch/> Numa Schmeder www.dfacto.ch < > http://www.dfacto.ch/> > n...@dfacto.ch <mailto:n...@dfacto.ch> | M +41 79 538 30 01 > > DIGITAL STRATEGY | DESIGN | DEVELOPMENT > > > > > -- Thiago