Ok, I just committed the updates. Now both BindHelpers.attr and S.attr implement AttrHelpers trait where we have a bunch of overloaded apply,
I would have liked to use Option[NodeSeq] for S.attr as well but this would be a breaking change and breaking changes are frozen now. So S.attr("someparam") still returns a Box[String]. However I added 2 helper function ~ that would return Option[NodeSeq], so you can call S.attr ~("someparam") and get back an Option[NodeSeq]. I know we could have used implicits to convert from Box[String] to Option[NodeSeq] but I feel that this would be an abuse of implicits as the use of implicits IMHO should be motivated byt strong design rationales and I think this is the case. Thoughts? Br's, Marius On Jan 7, 7:40 pm, Marius <marius.dan...@gmail.com> wrote: > I'll look into it. > > On Jan 7, 7:38 pm, "David Pollak" <feeder.of.the.be...@gmail.com> > wrote: > > > Marc, > > > Good suggestion. Marius -- do you want to do this... maybe even turn the > > pattern into a trait that we can apply over and over? > > > Thanks, > > > David > > > On Tue, Jan 6, 2009 at 9:57 PM, Marc Boschma > > <marc+lift...@boschma.cx<marc%2blift...@boschma.cx> > > > > wrote: > > > Cool code! Works nicely... > > > Would it make sense to also add something similar to this from S.attr ? > > > > def apply[T](what: String, f: String => T, default: => T): T > > > = apply(what).map(f) openOr default > > > > ie maybe: > > > > def apply[T](prefix: String, key: String, f: String => T): Option[T] > > > = apply(prefix, key).map(f) > > > def apply[T](key: String, f: String => T): Option[T] = apply(key).map(f) > > > > to BindHelpers.attr ? > > > > Thinking about it should the applys of the two attr objects be aligned > > > (Option verses Box, etc) ? It would make the crafting of snippets and bind > > > functions in terms of access to attributes the same, dropping a potential > > > barrier to learning lift... > > > > ie Maybe BindHelpers.attr should have applys with the following > > > signatures... > > > > def apply(key: String): Box[String] > > > def apply(prefix: String, key: String): Box[String] > > > > def apply(key: String, default: => String): String > > > def apply(prefix: String, key: String, default: => String): String > > > > def apply[T](key: String, f: String => T, default: => T): T > > > def apply[T](prefix: String, key: String, f: String => T, default: => > > > T): T > > > > Lastly, and maybe I am missing something here, but I take it for a snippet > > > a prefixed attribute isn't accessible via S.attr ??? > > > > Regards, > > > > Marc > > > > On 07/01/2009, at 6:54 AM, David Pollak wrote: > > > > On Tue, Jan 6, 2009 at 11:16 AM, Marius <marius.dan...@gmail.com> wrote: > > > >> Ok ... i just committed some changes: > > > >> 1. Renamed curAttr to attr > > >> 2. The BindHelpers vals are now private but we expose two functions > > >> currentNode and bindNodes > > > > Cool beans! > > > >> Br's, > > >> Marius > > > >> On Jan 6, 8:37 pm, "David Pollak" <feeder.of.the.be...@gmail.com> > > >> wrote: > > >> > On Tue, Jan 6, 2009 at 10:28 AM, Marius <marius.dan...@gmail.com> > > >> wrote: > > > >> > > On Jan 6, 7:15 pm, "David Pollak" <feeder.of.the.be...@gmail.com> > > >> > > wrote: > > >> > > > I also added > > >> > > > BindHelpers.attr("tag"): Option[NodeSeq] > > >> > > > so you can do something like: > > > >> > > > <span class={BindHelpers.attr("class")>...</span> > > > >> > > > and: > > >> > > > BindHelpers.attr("prefix", "tag") > > > >> > > I think it is committed to curAttr which personally I'm not a fan ... > > >> > > Doyou mind if I change it to attr or nodeAttr ? > > > >> > Go for it. > > > >> > > > Thanks, > > > >> > > > David > > > >> > > > On Tue, Jan 6, 2009 at 9:13 AM, Marius <marius.dan...@gmail.com> > > >> wrote: > > > >> > > > > Very cool Dave ! > > > >> > > > > thx, > > >> > > > > Marius > > > >> > > > > On Jan 6, 4:36 pm, "David Pollak" <feeder.of.the.be...@gmail.com> > > >> > > > > wrote: > > >> > > > > > Folks, > > > >> > > > > > I'm about to commit up a non-breaking solution. > > > >> > > > > > In bind, you can call: > > >> > > > > > BindHelpers.bindNodes.value: List[NodeSeq] > > >> > > > > > BindHelpers.currentNode.value: Elem > > > >> > > > > > bindNodes is a list of the nodes that were passed into bind > > >> > > > > > with > > >> the > > >> > > more > > >> > > > > > current node at the head of the list. If you're doing > > >> hierarchical > > >> > > > > binding, > > >> > > > > > you can see all the nodes that were passed into bind this was. > > > >> > > > > > currentNode is available to the BindParam and it contains the > > >> parent > > >> > > Elem > > >> > > > > to > > >> > > > > > the NodeSeq that was passed into your BindParam. You can > > >> inspect > > >> > > > > attributes > > >> > > > > > to your heart's content. > > > >> > > > > > Give it an hour or two for these changes to make their way > > >> through > > >> > > > > Hudson. > > > >> > > > > > Thanks, > > > >> > > > > > David > > > >> > > > > > On Tue, Jan 6, 2009 at 4:50 AM, Marc Boschma > > >> > > > > > <marc+lift...@boschma.cx <marc%2blift...@boschma.cx> < > > >> marc%2blift...@boschma.cx <marc%252blift...@boschma.cx>> < > > >> > > marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> < > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>>>< > > >> > > > > marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> < > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> < > > >> > > marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> < > > >> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>>> > > > >> > > > > > > wrote: > > > >> > > > > > > I've just had a thought as to how to make it not a breaking > > >> change. > > > >> > > > > > > Leave your change "calcValue(s.child) I just call > > >> calcValue(s)" > > > >> > > > > > > change: > > >> > > > > > > case class FuncBindParam(name: String, value: NodeSeq => > > >> NodeSeq) > > >> > > > > > > extends Tuple2(name, value) with BindParam { > > >> > > > > > > def calcValue(in: NodeSeq): NodeSeq = value(in) > > >> > > > > > > } > > > >> > > > > > > to: > > >> > > > > > > case class FuncBindParam(name: String, value: NodeSeq => > > >> NodeSeq) > > >> > > > > > > extends Tuple2(name, value) with BindParam { > > >> > > > > > > def calcValue(in: NodeSeq): NodeSeq = value(in.child) > > >> > > > > > > } > > > >> > > > > > > That should prevent old code breaking... which would be a > > >> > > > > > > good > > >> > > > > > > thing(tm) given the amount of code that uses bind(...) > > > >> > > > > > > then create something like: > > > >> > > > > > > case class FuncMetaDataBindParam(name: String, value: > > >> (MetaData, > > >> > > > > > > NodeSeq) => NodeSeq) extends Tuple2(name, value) with > > >> BindParam { > > >> > > > > > > def calcValue(in: NodeSeq): NodeSeq = > > >> > > > > > > value(in.attributes, > > >> > > > > > > in.child) > > >> > > > > > > } > > > >> > > > > > > along with adding to class SuperArrowAssoc... > > >> > > > > > > def ->(in: (MetaData, NodeSeq) => NodeSeq) = > > >> > > > > > > FuncMetaDataBindParam(name, in) > > > >> > > > > > > That would be fairly clean... > > > >> > > > > > > ----- > > > >> > > > > > > Maybe for those that actually want the full node add: > > > >> > > > > > > case class FuncBoxBindParam(name: String, value: > > >> Box(NodeSeq) => > > >> > > > > > > NodeSeq) extends Tuple2(name, value) with BindParam { > > >> > > > > > > def calcValue(in: NodeSeq): NodeSeq = value(Full(in)) > > >> > > > > > > } > > > >> > > > > > > and you could go nuts and: > > > >> > > > > > > case class FuncPrefixAndLabelBindParam(name: String, value: > > >> > > > > > > (String, String, NodeSeq) => NodeSeq) extends Tuple2(name, > > >> value) > > >> > > with > > >> > > > > > > BindParam { > > >> > > > > > > def calcValue(in: NodeSeq): NodeSeq = value(in.prefix, > > >> > > in.label, > > >> > > > > > > in.child) > > >> > > > > > > } > > > >> > > > > > > etc... > > > >> > > > > > > On 06/01/2009, at 10:51 PM, Marc Boschma wrote: > > > >> > > > > > > > (you can tel I'm sleeping well :/ - too hot) > > > >> > > > > > > > The toList function is one of David's (todo example app). I > > >> do > > >> > > love > > >> > > > > > > > the ability to curry :) > > > >> > > > > > > > Marc > > >> > > > > > > > On 06/01/2009, at 9:51 PM, Marius wrote: > > > >> > > > > > > >> On Jan 6, 12:47 pm, Marc Boschma > > >> > > > > > > >> <marc+lift...@boschma.cx<marc%2blift...@boschma.cx> > > >> <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx>> > > >> > > <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> < > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>>> > > >> > > > > <marc%2blift...@boschma.cx <marc%252blift...@boschma.cx> < > > >> marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx>> < > > >> > > marc%252blift...@boschma.cx <marc%25252blift...@boschma.cx> < > > >> marc%25252blift...@boschma.cx <marc%2525252blift...@boschma.cx>>>>> > > >> > > > > > > wrote: > > >> > > > > > > >>> A quick just before going to bed reaction is that your > > >> change > > >> > > would > > >> > > > > > > >>> solve the issue. > > > >> > > > > > > >> Yeah it would ... (I mean it worked fine in my tests) > > > >> > > > > > > >>> It is interesting you focused on the "exclude" and not > > >> > > > > > > >>> the > > >> > > > > > > >>> "list" (which is what I have been playing with). I > > >> actually > > >> > > missed > > >> > > > > > > >>> it > > >> > > > > > > >>> was a similar case... > > > >> > > > > > > >> I just picked it randomly :) ... I've seen that you're > > >> using a > > >> > > > > > > >> partially applied function doList ... (which I assume it > > >> > > > > > > >> is > > >> a > > >> > > > > curried > > >> > > > > > > >> function):) > > > >> > > > > > > >>> Regards, > > > >> > > > > > > >>> Marc > > > >> > > > > > > >>> On 06/01/2009, at 9:24 PM, Marius wrote: > > > >> > > > > > > >>>> I just did a minor modification to the lift code so the > > >> actual > > >> > > > > > > >>>> node it > > >> > > > > > > >>>> is passed to the BindParam and not its child. Now > > >> > > > > > > >>>> having: > > > >> > > > > > > >>>> bind("todo", html, > > >> > > > > > > >>>> "exclude" -> {node:NodeSeq > > >> =>ajaxCheckbox > > >> > > > > > > >>>> (QueryNotDone, v => {QueryNotDone(v); reDraw})} > > >> > > > > > > >>>> ... ) > > > >> > > > > > > >>>> and the markup <todo:exclude param="Dumb"/> > > > >> > > > > > > >>>> The node parameter to the anonymous function will be the > > >> > > > > > > >>>> <todo:exclude> node and not its children. So now you can > > >> > > access > > >> > > > > the > > >> > > > > > > >>>> "param" attribute from node. The change was in in_bind > > >> > > function so > > >> > > > > > > >>>> instead of calling calcValue(s.child) I just call > > >> calcValue(s) > > > >> > > > > > > >>>> Looking at the existent BindParams this change does not > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~----------~----~----~----~------~----~------~--~---