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
>> seem
>> > > to
>> > > > > > > >>>> cause
>> > > > > > > >>>> side effects since the calcValue 'in' parameter is used
>> only
>> > > for
>> > > > > > > >>>> FuncXXXBindParam-s. The impact is that the user's
>> function
>> > > would
>> > > > > > > >>>> now
>> > > > > > > >>>> get the actual node (from which now he can extract
>> attributes)
>> > > and
>> > > > > > > >>>> not
>> > > > > > > >>>> the child nodes. But child nodes from the actual node are
>> > > trivial
>> > > > > > > >>>> to
>> > > > > > > >>>> obtain.
>> >
>> > > > > > > >>>> I did not commit this change as I'd like to see other
>> opinions
>> > > to
>> > > > > > > >>>> see
>> > > > > > > >>>> if there is something that I missed somehow. If we get
>> general
>> > > > > > > >>>> consensus of this change I can commit it right away and
>> > > announce
>> > > > > > > >>>> it as
>> > > > > > > >>>> a "breaking change".
>> >
>> > > > > > > >>>> Thoughts?
>> >
>> > > > > > > >>>> Br's,
>> > > > > > > >>>> Marius
>> >
>> > > > > > > >>>> On Jan 6, 12:02 pm, Marius <marius.dan...@gmail.com>
>> wrote:
>> > > > > > > >>>>> A nice alternative would have been :
>> >
>> > > > > > > >>>>> bind("todo", html,
>> > > > > > > >>>>>                     "exclude" ->  {node:NodeSeq
>> > > =>ajaxCheckbox
>> > > > > > > >>>>> (QueryNotDone, v => {QueryNotDone(v); reDraw})}
>> > > > > > > >>>>>  ... )
>> >
>> > > > > > > >>>>> But here the node impersonates the childNodes not the
>> > > original
>> > > > > > > >>>>> node.
>> > > > > > > >>>>> So you still can not access the param attribute below
>> >
>> > > > > > > >>>>> <todo:exclude param="Dumb"/>
>> >
>> > > > > > > >>>>> but you can do it like:
>> >
>> > > > > > > >>>>> <todo:exclude ><meta param="dumb"/></todo:exclude>
>> >
>> > > > > > > >>>>> and you have full access to the meta node as it is a
>> child of
>> > > > > > > >>>>> todo:exclude. Hence you can pass state.
>> >
>> > > > > > > >>>>> I know, it is not ideal but should be workable until
>> snippet
>> > > > > > > >>>>> child-
>> > > > > > > >>>>> node attributes are exposed in one way or another.
>> >
>> > > > > > > >>>>> Br's,
>> > > > > > > >>>>> Marius
>> >
>> > > > > > > >>>>> Marc Boschma wrote:
>> > > > > > > >>>>>> I have been playing with the ToDo example application
>> and
>> > > having
>> > > > > > > >>>>>> fun
>> > > > > > > >>>>>> in manipulating XML.
>> >
>> > > > > > > >>>>>> With the <todo:list/> node I thought it would be good
>> if the
>> > > > > > > >>>>>> XHTML
>> > > > > > > >>>>>> designer could pass in some guidance to the doList(...)
>> > > method
>> > > > > > > >>>>>> used in
>> > > > > > > >>>>>> bind(..). ie. <todo:list
>> singular="true">...</todo:list>
>> >
>> > > > > > > >>>>>> Looking over the bind code I noticed that the
>> attributes are
>> > > not
>> > > > > > > >>>>>> accessible without ending up changing the calcValue
>> method's
>> > > > > > > >>>>>> signature. I did initially try to knock up a
>> >
>> > > > > > > >>>>>>   case class FuncWithAttrBindParam(name: String, value:
>> > > > > (NodeSeq,
>> > > > > > > >>>>>> MetaData) => NodeSeq) extends Tuple2(name, value) with
>> > > BindParam
>> >
>> > > > > > > >>>>>> and a corresponding
>> >
>> > > > > > > >>>>>>   case Some(ns : FuncWithAttrBindParam) =>
>> >
>> > > > > > > >>>>>> in in_bind(...), but it all looks like a huge kludge.
>> >
>> > > > > > > >>>>>> It strikes me as a little deficient to be able to
>> utilise
>> > > > > > > >>>>>> attributes
>> > > > > > > >>>>>> within the context of a snippet and yet not within a
>> bind. I
>> > > > > know
>> > > > > > > >>>>>> bind
>> > > > > > > >>>>>> is quite embedded in lift now, but I think that this
>> > > difference
>> > > > > > > >>>>>> might
>> > > > > > > >>>>>> prove a little frustrating. I know one solution is to
>> just
>> > > > > > > >>>>>> create a
>> > > > > > > >>>>>> bind("todo", html,
>> > > > > > > >>>>>>                                 "exclude" ->
>> > > > > > > >>>>>> ajaxCheckbox(QueryNotDone, v => {QueryNotDone(v);
>> reDraw}),
>> > > > > > > >>>>>>                                 "list" ->
>> doList(reDraw,
>> > > false)
>> > > > > > > >>>>>> _,
>> >
>> > ...
>> >
>> > read more ยป
>>
>>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
>
>
>
>
>
> >
>


-- 
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp

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