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 <[email protected]>  
> 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" <[email protected]>
> wrote:
> > On Tue, Jan 6, 2009 at 10:28 AM, Marius <[email protected]>  
> wrote:
> >
> > > On Jan 6, 7:15 pm, "David Pollak" <[email protected]>
> > > 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  
> <[email protected]> wrote:
> >
> > > > > Very cool Dave !
> >
> > > > > thx,
> > > > > Marius
> >
> > > > > On Jan 6, 4:36 pm, "David Pollak"  
> <[email protected]>
> > > > > 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
> > > > > > <[email protected] <marc%[email protected]> <
> > > marc%[email protected] <marc%[email protected]>><
> > > > > marc%[email protected] <marc%[email protected]> <
> > > marc%[email protected] <marc%[email protected]>>>
> >
> > > > > > > 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 
> [email protected]<marc%[email protected]>
> > > <marc%[email protected] <marc%[email protected]>>
> > > > > <marc%[email protected] <marc%[email protected]> <
> > > marc%[email protected] <marc%[email protected]>>>>
> > > > > > > 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  
> <[email protected]> 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
>
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to