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
-~----------~----~----~----~------~----~------~--~---

Reply via email to