[Lift] Automatic compiilation fails with lift-archetype-basic 2.0-M1 in Eclipse
I just started a new Lift project in Eclipse using the latest basic archetype and I keep getting a slew of validation errors whenever I add or edit a Scala source file. The only way to rid the project of these errors is to do a Project/Clean..., which is really annoying and greatly slows development. Is anyone else experiencing same? By the way, I'm using Eclipse 3.5.1, Eclipse maven ide (Maven Integration for Eclipse) and the Scala Eclipse plugin from http://www.scala-lang.org/scala-eclipse-plugin. I tested that the Maven integration and the scala plugin are working OK independently, so they are not the problem. Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Error saving Mapper object
I started a new 1.1-Snapshot and am now getting the following error when trying to save a mapper object: Message: net.liftweb.mapper.MapperException: Cannot test the MetaMapper singleton for saved status net.liftweb.mapper.MetaMapper$class.saved_$qmark(MetaMapper.scala: 550) net.liftweb.coreguard.model.test.saved_$qmark(test.scala:28) ... My mapper is simple. It's just a test object: object test extends test with LongKeyedMetaMapper[test]{ } class test extends LongKeyedMapper[test] with IdPK with LongKeyedMetaMapper[test] with CRUDify[Long,test] { def getSingleton = test object name extends MappedString(this, 100){ override def displayName = test name } } Thanks in advance for any help to resolve this. Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] 1.1-M7 basic archetype errors
The 1.1-M7 basic archetype in http://scala-tools.org/repo-snapshots doesn't have a dependency on lift-json and so compilation fails. Adding this dependency in the pom solves this. Also, shouldn't the pom use the SNAPSHOT repo rather than, or at least in addition to, releases? Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: Error saving Mapper object
Stupid me!! I mistakenly put the CRUDify trait on the class, not the object. Thanks a bunch for getting me out of this mess. Glenn On Dec 14, 10:13 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Mon, Dec 14, 2009 at 9:11 AM, glenn gl...@exmbly.com wrote: I started a new 1.1-Snapshot and am now getting the following error when trying to save a mapper object: You're not saving a Mapper instance, you're calling save on the MetaMapper instance. That can cause significant problems, thus it now generates an error. Message: net.liftweb.mapper.MapperException: Cannot test the MetaMapper singleton for saved status net.liftweb.mapper.MetaMapper$class.saved_$qmark(MetaMapper.scala: 550) net.liftweb.coreguard.model.test.saved_$qmark(test.scala:28) ... My mapper is simple. It's just a test object: object test extends test with LongKeyedMetaMapper[test]{ } class test extends LongKeyedMapper[test] with IdPK with LongKeyedMetaMapper[test] with CRUDify[Long,test] { def getSingleton = test object name extends MappedString(this, 100){ override def displayName = test name } } Thanks in advance for any help to resolve this. Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com . For more options, visit this group at http://groups.google.com/group/liftweb?hl=en. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: Mapper - JObject bridge
David, I couldn't find encodeAsJSON_! on MetaMapper in the Lift source on github. Where is this code checked in? Glenn On Dec 2, 1:15 pm, David Pollak feeder.of.the.be...@gmail.com wrote: Folks (HarryH -- this means you), I've just checked in code on the dpp_issue_213 that does Mapper - JObject bridging using the awesome lift-json library. The methods on MetaMapper: protected def encodeAsJSON_! (toEncode: A): JsonAST.JObject protected def decodeFromJSON_!(json: JsonAST.JObject): A Implement the bridge. They are protected and have a _! in their name because they are *dangerous* in that data can be exposed on the JSON object that you might not want exposed and these methods should be used with extreme caution. An example of usage can be found in the MapperSpecs: object SampleModel extends SampleModel with KeyedMetaMapper[Long, SampleModel] { def encodeAsJson(in: SampleModel): JsonAST.JObject = encodeAsJSON_!(in) def buildFromJson(json: JsonAST.JObject): SampleModel = decodeFromJSON_!(json) } class SampleModel extends KeyedMapper[Long, SampleModel] { def getSingleton = SampleModel // what's the meta server def primaryKeyField = id object id extends MappedLongIndex(this) object firstName extends MappedString(this, 32) object moose extends MappedNullableLong(this) object notNull extends MappedString(this, 32) { override def dbNotNull_? = true } def encodeAsJson(): JsonAST.JObject = SampleModel.encodeAsJson(this) } So, you can use this mechanism to serialize a Mapper object to JSON, shovel the object into memcached and then pull it out, mutate a field and save the object back to the database (although connection identifier is lost, so if you are sharding your database, this will not work). Please give it a try, give me feedback. I'll put it on review board tomorrow after any feedback and get it into Lift. Thanks, David -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: XSLT?
Jim, I've used a lot of XSLT in the past but have recently taken to Scala's use of XML literals and extraction methods coupled with case matching in place of XSL templates - no need to call into Xerces, Xalan or any other third-party libraries to do this. Glenn On Dec 4, 9:19 am, Jim Wise jw...@draga.com wrote: Had asked this earlier on the scala-users list. It's not (quite) a Lift question, but maybe someone has done something similar? I'm in the process of moving an application currently implemented in Java using Apache Cocoon to Scala and Liftweb. I've had a relatively easy time moving the `plumbing' of the app over -- sessions, users, dynamic content and so on -- but a lot of the app's presentation is, in true cocoon style, implemented as XSLT pipelines on static or generated XML content. In the long term, I see the benefits of moving these to Lift templates, but in a 0.9 version (as it were), it makes a fair amount of sense to use the existing templates, with a lift snippet or view (or even a wrapper function or hook) performing a final XSLT transform on the generated XML. I can see how to hook such a step into Lift's processing, but I also see that Lift has no native support for this (no surprise, as Lift has a full templating system of its own). Before I set about doing this by calling into Xerces and Xalan from Scala (should be easy enough), is there any sample code or Scala API for XSLT transformations already out there? Thanks, -- Jim Wise jw...@draga.com application_pgp-signature_part 1KViewDownload -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: A sensible AJAX approach
David, Thanks a bunch. Your solution is one I was trying to implement but wasn't quite sure how until you showed me that I can create an AnonFunc using Shtml.ajaxCall. It certainly does simplify things. One of the issues that stymied me - and still does, frankly - is how the ajaxCall wraps the edit function with the correct parameter for the callback to work. I updated the code in http://github.com/glennSilverman/treeview and refactored it into a MetaMegaTreeItem trait to easily add these features to any Mapper object. Maybe some Lift committer might find the ideas involved here usefull enough to include something similar in a future release of Lift. Glenn . On Nov 24, 5:53 pm, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, The issue is that you were creating call-back functions during an API call (rather than as part of Lift's HTML/Ajax/Comet pipeline). In general, I think this is very bad design. I'd strongly recommend using the Ajax/Json call facilities built into Lift. You get a pile of things for free including securing calls (you don't need to keep a lot of state client-side). So, your code looks like: def buildTree(in:NodeSeq):NodeSeq = { val func = AnonFunc( SHtml.ajaxCall(JsRaw(this.id), (id: String) = SetHtml(role_edit, Role.find(id).map(edit) openOr NodeSeq.Empty))._2 ) TreeView(tree, JsObj((persist, location), (toggle, func)), loadTree, loadNode) } Also, you might want to look at S.hostAndPort for calculating the current server. Also, think about using the map() call rather than pattern matching on Full/_. Also, there's no need to register API calls in SiteMap I'll update your app and push code tohttp://github.com/dpp/treeview Thanks, David On Tue, Nov 24, 2009 at 8:02 AM, glenn gl...@exmbly.com wrote: David, The statement that all functions are bound to the current state in the scope that the function was created may be true for functions submitted via SHtml, but doesn't seem to hold true for those from LiftResponse, otherwise, the edit function in my example would work for editing, just as it does for creating. In any case, I'm still at a loss on how to fix this. Glenn On Nov 20, 5:40 pm, glenn gl...@exmbly.com wrote: David, I was able to put together a simplified application to demo the problem. It's just a basic lift archetype with a Role.scala added to the mapper package that contains all the relevant code. Here is the link to the application: http://github.com/glennSilverman/treeview If you run it as-is, you can add new roles to the db but you can't edit them. Glenn On Nov 20, 10:28 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Fri, Nov 20, 2009 at 10:14 AM, glenn gl...@exmbly.com wrote: David, That's what I thought. All I needed to do was create the Mapper.toForm like so: item.toForm(Full(Save), { _.save }) and the item would be saved on submit. But it doesn't work in my case. Please put together a complete runnable example of it not working for you and we'll debug it. Glenn On Nov 20, 10:05 am, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, All functions are bound to the current state in the scope that the function was created. There's no need to do weird RequestVar things with Hidden fields or anything else. If you've got a function passed to SHtml.text, submit, etc. that function closes over its local scope: it captures all the variables it refers to. So: def mySnippet = { val myInstance = MyTable.find(whatever) SHtml.ajaxCheckbox(..., bool = {myInstance.boolField(bool).save; Noop}) } In the above code, you've captured the instance in the val myInstance... that's kept around for the lifespan of the function that you passed to ajaxCheckbox. Thanks, David On Fri, Nov 20, 2009 at 9:45 AM, glenn gl...@exmbly.com wrote: I've been following this thread as lately I'm having difficulty with an ajax-submitted request in my app. Here's the scenario (There's no simple way to describe this, so bear with me): I create a JQuery tree of my data (Mapper object with just an item name and a parent Mapper object as it's fields) as follows: def buildTree(in:NodeSeq):NodeSeq = { object MyJqLoad { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = JqId(json_result).toJsCmd + .load( + content.toJsCmd + JsRaw(+this.id) + ) } } val host = http://; + S.hostName val link = host + :8080 + S.contextPath + /api/json/ + dbTableName.toLowerCase + / val func = AnonFunc( MyJqLoad(link)) TreeView(tree, JsObj((persist, location), (toggle, func
[Lift] Re: A sensible AJAX approach
David, The statement that all functions are bound to the current state in the scope that the function was created may be true for functions submitted via SHtml, but doesn't seem to hold true for those from LiftResponse, otherwise, the edit function in my example would work for editing, just as it does for creating. In any case, I'm still at a loss on how to fix this. Glenn On Nov 20, 5:40 pm, glenn gl...@exmbly.com wrote: David, I was able to put together a simplified application to demo the problem. It's just a basic lift archetype with a Role.scala added to the mapper package that contains all the relevant code. Here is the link to the application: http://github.com/glennSilverman/treeview If you run it as-is, you can add new roles to the db but you can't edit them. Glenn On Nov 20, 10:28 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Fri, Nov 20, 2009 at 10:14 AM, glenn gl...@exmbly.com wrote: David, That's what I thought. All I needed to do was create the Mapper.toForm like so: item.toForm(Full(Save), { _.save }) and the item would be saved on submit. But it doesn't work in my case. Please put together a complete runnable example of it not working for you and we'll debug it. Glenn On Nov 20, 10:05 am, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, All functions are bound to the current state in the scope that the function was created. There's no need to do weird RequestVar things with Hidden fields or anything else. If you've got a function passed to SHtml.text, submit, etc. that function closes over its local scope: it captures all the variables it refers to. So: def mySnippet = { val myInstance = MyTable.find(whatever) SHtml.ajaxCheckbox(..., bool = {myInstance.boolField(bool).save; Noop}) } In the above code, you've captured the instance in the val myInstance... that's kept around for the lifespan of the function that you passed to ajaxCheckbox. Thanks, David On Fri, Nov 20, 2009 at 9:45 AM, glenn gl...@exmbly.com wrote: I've been following this thread as lately I'm having difficulty with an ajax-submitted request in my app. Here's the scenario (There's no simple way to describe this, so bear with me): I create a JQuery tree of my data (Mapper object with just an item name and a parent Mapper object as it's fields) as follows: def buildTree(in:NodeSeq):NodeSeq = { object MyJqLoad { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = JqId(json_result).toJsCmd + .load( + content.toJsCmd + JsRaw(+this.id) + ) } } val host = http://; + S.hostName val link = host + :8080 + S.contextPath + /api/json/ + dbTableName.toLowerCase + / val func = AnonFunc( MyJqLoad(link)) TreeView(tree, JsObj((persist, location), (toggle, func)), loadTree, loadNode) } The functions, loadTree and loadNode, are used to asynchronously build the tree of item names from the Mapper instances. The link val creates a URL, for example, http://localhost:8080/api/json/ dbTableName/, where dbTableName is just the Mapper object name. On the client, the user clicks on a tree item, which, as you can see from the above code, submits the Mapper id selected to the server, which then pulls the Mapper.toForm html from the Mapper instance and returns it to the client at div id=json_result/, which is in my template. This all works great. Where this all breaks down, is in submitting the returned Mapper.toForm back to the server when I click on the Save button, because no Mapper instance exists at that point in the request or session for the save button to act on. Somewhere, I'm thinking I have to modify the Mapper.toForm html so the submit button runs another JavaScript function on the client to return the Mapper id to the server for processing. But I haven't yet been able to do this. One of the problems is that I don't even have an id on the client (none is returned with Mapper.toForm html) to work with. And, it seems to me that to make this scenario work, I'm forced to become a JavaScript guru and work outside of Lift. In other words, if there isn't a mechanism in Lift to handle this situation directly, there should be. One of the things I've tried is to add a hidden form field to the Mapper.toForm html, SHtml.hidden(() = itemIdVar(id.toString)), where itemIdVar extends RequestVar[String]. But I couldn't make that work either. The hidden form field is suppose to run the ()=Any function, and it may do that, but not in the correct sequence to do any good when the form is submitted. Glenn On Nov 19, 11:35 pm
[Lift] Re: Change to support dynamic top level menu items
There is a poor man's approach to creating top-level menus dynamically. Simply create a number of hidden menus - guessing at the max number your app will likely need - whose text representation, paths and hidden attributes can be adjusted programatically as needed by the application. Not a very satisfactory solution, but in a pinch... Glenn On Nov 24, 2:46 pm, Ross Mellgren dri...@gmail.com wrote: I considered this but my problem was that you could not place them into the middle of a static flow, without rummaging around in the CompleteMenu looking for known MenuItems. For example, I was thinking in the CMS case that you probably want a static Home Menu and then some dynamic menus and then maybe some more static menus after that, such as logout etc. Of course, I'm just trying to help out, it's not my use case, so the existing solution of overriding SiteMap.buildMenu may work for philip. -Ross On Nov 24, 2009, at 5:42 PM, David Pollak wrote: Ross, You can dynamically add child elements right now: new SiteMap(menuItems) { override def buildMenu(current: Box[Loc[_]]): CompleteMenu = { val tmp = super.buildMenu(current) CompleteMenu(tmp.lines.toList ::: List(additional menus)) } } On Mon, Nov 23, 2009 at 5:16 PM, Ross Mellgren dri...@gmail.com wrote: Understood. Thanks. -Ross On Nov 23, 2009, at 8:15 PM, David Pollak wrote: On Mon, Nov 23, 2009 at 4:55 PM, Ross Mellgren dri...@gmail.com wrote: As much as I subscribe to the a lack of dissent is implicit assent policy, I'm hoping somebody deeply familiar with SiteMap can comment on whether this change seems like a bad idea? I guess if I don't hear anything I'll create an issue and submit the patch for review, but I'd feel better with a bit more discussion. Give me a few days to respond please. -Ross On Nov 22, 2009, at 9:28 PM, philip wrote: Essential for the CMS I am programming as the user needs to be able to define the menu structure. On 11月22日, 上午4時46分, Ross Mellgren dri...@gmail.com wrote: In the recent thread, a couple people asked for the ability to create dynamic menu items per request from the database. David suggested Loc.supplimentalKidMenuItems which works fine for dynamic children of a static menu, but doesn't support the ability to make the top level menu dynamic. Menu has a method called makeMenuItem which gives a Box of MenuItem. What about a new method makeMenuItems that gives a possible plurality of MenuItems whose default implementation deferred to the existing makeMenuItem in the case where it's not overridden? I made this change to my local copy of lift and it seems to work alright. Example Menu: case class DynMenu() extends Menu(Loc(dynmenu, Link(List (dynmenu), true, /dynmenu), Dynamic Menu)) { override def makeMenuItems(path: List[Loc[_]]): Iterable [MenuItem] = DynMenuItem.findAll.map(dmi = { MenuItem(Text(dmi.label.is), Text(dmi.link.is), Nil, false, false, Nil) }) } That is, a Menu can generate 0 or more MenuItems when the menu is being generated. The disadvantage I see is similar to the one with supplimentalKidMenuItems -- that is, you have to manually compute the attributes of MenuItem such as current. However, it does give you the full power to make whatever kind of menu items you want. I looked briefly at seeing if it would be feasible to use a function Box[Req] = SiteMap on LiftRules, but I think the RewritePF auto detection thing in LiftRules.setSiteMap prevents this from being the right thing. The change to lift-webkit: diff --git a/lift-base/lift-webkit/src/main/scala/net/liftweb/ sitemap/Menu.scala b/lift-base/lift-webkit/src/main/scala/net/ liftweb/sitemap/Menu.scala index d33d1dc..79194f5 100644 --- a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/ Menu.scala +++ b/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap/ Menu.scala @@ -61,8 +61,10 @@ case class Menu(loc: Loc[_], kids: Menu*) extends HasKids { } // def buildChildLine: List[MenuItem] = kids.toList.flatMap(m = m.loc.buildItem(Nil, false, false)) + def makeMenuItems(path: List[Loc[_]]): Iterable[MenuItem] = makeMenuItem(path) + def makeMenuItem(path: List[Loc[_]]): Box[MenuItem] = - loc.buildItem(loc.buildKidMenuItems(kids), _lastInPath(path), _inPath(path)) + loc.buildItem(loc.buildKidMenuItems(kids), _lastInPath (path), _inPath(path)) private def _inPath(in: List[Loc[_]]): Boolean = in match { case Nil = false diff --git a/lift-base/lift-webkit/src/main/scala/net/liftweb/ sitemap/SiteMap.scala b/lift-base/lift-webkit/src/main/scala/net/ liftweb/sitemap/SiteMap.scala index 7939938..f8fa307 100644 --- a/lift-base/lift-webkit/src/main/scala/net/liftweb/sitemap
[Lift] Re: A sensible AJAX approach
I've been following this thread as lately I'm having difficulty with an ajax-submitted request in my app. Here's the scenario (There's no simple way to describe this, so bear with me): I create a JQuery tree of my data (Mapper object with just an item name and a parent Mapper object as it's fields) as follows: def buildTree(in:NodeSeq):NodeSeq = { object MyJqLoad { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = JqId(json_result).toJsCmd + .load( + content.toJsCmd + JsRaw(+this.id) + ) } } val host = http://; + S.hostName val link = host + :8080 + S.contextPath + /api/json/ + dbTableName.toLowerCase + / val func = AnonFunc( MyJqLoad(link)) TreeView(tree, JsObj((persist, location), (toggle, func)), loadTree, loadNode) } The functions, loadTree and loadNode, are used to asynchronously build the tree of item names from the Mapper instances. The link val creates a URL, for example, http://localhost:8080/api/json/dbTableName/, where dbTableName is just the Mapper object name. On the client, the user clicks on a tree item, which, as you can see from the above code, submits the Mapper id selected to the server, which then pulls the Mapper.toForm html from the Mapper instance and returns it to the client at div id=json_result/, which is in my template. This all works great. Where this all breaks down, is in submitting the returned Mapper.toForm back to the server when I click on the Save button, because no Mapper instance exists at that point in the request or session for the save button to act on. Somewhere, I'm thinking I have to modify the Mapper.toForm html so the submit button runs another JavaScript function on the client to return the Mapper id to the server for processing. But I haven't yet been able to do this. One of the problems is that I don't even have an id on the client (none is returned with Mapper.toForm html) to work with. And, it seems to me that to make this scenario work, I'm forced to become a JavaScript guru and work outside of Lift. In other words, if there isn't a mechanism in Lift to handle this situation directly, there should be. One of the things I've tried is to add a hidden form field to the Mapper.toForm html, SHtml.hidden(() = itemIdVar(id.toString)), where itemIdVar extends RequestVar[String]. But I couldn't make that work either. The hidden form field is suppose to run the ()=Any function, and it may do that, but not in the correct sequence to do any good when the form is submitted. Glenn On Nov 19, 11:35 pm, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Chris Lewis burningodzi...@gmail.com writes: Thanks for the feedback Jeppe. I can't completely infer the context of your example, Seems to happen a lot to me lately. :-) This was just a quick paste from our codebase but I get the idea (and I hadn't known about TemplateFinder). Here's what I've hacked together so far. /Jeppe -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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=.
[Lift] Re: A sensible AJAX approach
David, That's what I thought. All I needed to do was create the Mapper.toForm like so: item.toForm(Full(Save), { _.save }) and the item would be saved on submit. But it doesn't work in my case. Glenn On Nov 20, 10:05 am, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, All functions are bound to the current state in the scope that the function was created. There's no need to do weird RequestVar things with Hidden fields or anything else. If you've got a function passed to SHtml.text, submit, etc. that function closes over its local scope: it captures all the variables it refers to. So: def mySnippet = { val myInstance = MyTable.find(whatever) SHtml.ajaxCheckbox(..., bool = {myInstance.boolField(bool).save; Noop}) } In the above code, you've captured the instance in the val myInstance... that's kept around for the lifespan of the function that you passed to ajaxCheckbox. Thanks, David On Fri, Nov 20, 2009 at 9:45 AM, glenn gl...@exmbly.com wrote: I've been following this thread as lately I'm having difficulty with an ajax-submitted request in my app. Here's the scenario (There's no simple way to describe this, so bear with me): I create a JQuery tree of my data (Mapper object with just an item name and a parent Mapper object as it's fields) as follows: def buildTree(in:NodeSeq):NodeSeq = { object MyJqLoad { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = JqId(json_result).toJsCmd + .load( + content.toJsCmd + JsRaw(+this.id) + ) } } val host = http://; + S.hostName val link = host + :8080 + S.contextPath + /api/json/ + dbTableName.toLowerCase + / val func = AnonFunc( MyJqLoad(link)) TreeView(tree, JsObj((persist, location), (toggle, func)), loadTree, loadNode) } The functions, loadTree and loadNode, are used to asynchronously build the tree of item names from the Mapper instances. The link val creates a URL, for example,http://localhost:8080/api/json/ dbTableName/, where dbTableName is just the Mapper object name. On the client, the user clicks on a tree item, which, as you can see from the above code, submits the Mapper id selected to the server, which then pulls the Mapper.toForm html from the Mapper instance and returns it to the client at div id=json_result/, which is in my template. This all works great. Where this all breaks down, is in submitting the returned Mapper.toForm back to the server when I click on the Save button, because no Mapper instance exists at that point in the request or session for the save button to act on. Somewhere, I'm thinking I have to modify the Mapper.toForm html so the submit button runs another JavaScript function on the client to return the Mapper id to the server for processing. But I haven't yet been able to do this. One of the problems is that I don't even have an id on the client (none is returned with Mapper.toForm html) to work with. And, it seems to me that to make this scenario work, I'm forced to become a JavaScript guru and work outside of Lift. In other words, if there isn't a mechanism in Lift to handle this situation directly, there should be. One of the things I've tried is to add a hidden form field to the Mapper.toForm html, SHtml.hidden(() = itemIdVar(id.toString)), where itemIdVar extends RequestVar[String]. But I couldn't make that work either. The hidden form field is suppose to run the ()=Any function, and it may do that, but not in the correct sequence to do any good when the form is submitted. Glenn On Nov 19, 11:35 pm, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Chris Lewis burningodzi...@gmail.com writes: Thanks for the feedback Jeppe. I can't completely infer the context of your example, Seems to happen a lot to me lately. :-) This was just a quick paste from our codebase but I get the idea (and I hadn't known about TemplateFinder). Here's what I've hacked together so far. /Jeppe -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.comliftweb%2bunsubscr...@googlegroups.com . For more options, visit this group at http://groups.google.com/group/liftweb?hl=. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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=.
[Lift] Missing source files in 1.1-SNAPSHOT
Where are all the java source files in http://scala-tools.org/repo-snapshots/net/liftweb/lift-webkit/1.1-SNAPSHOT/lift-webkit-1.1-SNAPSHOT-sources.jar? It's kind of hard to debug without them. Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Firefox error in returning a CreatedResponse
I'm returning Full(CreatedResponse(form, text/xhtml )) in LiftRules.DispatchPF, where form is just a MetaMapper.toForm node, which works fine in IE but fails in Firefox with the following error. XML or text declaration not at start of entity [Break on this error] div xmlns=http://www.w3.org/1999/xhtml;?xml version=1.0 encoding=UTF-8? (line 1) uncaught exception: [Exception... Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMNSHTMLElement.innerHTML] nsresult: 0x80004003 (NS_ERROR_INVALID_POINTER) location: JS frame :: http://localhost:8080/classpath/jquery.js :: anonymous :: line 251 data: no] Anyone have an idea why this happening? Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: Missing source files in 1.1-SNAPSHOT
Kris, Don't want to clone the GitHub repo, as I need a Maven repo. Glenn On Nov 18, 11:19 am, Indrajit Raychaudhuri indraj...@gmail.com wrote: Still, something looks wrong: http://scala-tools.org/repo-releases/net/liftweb/lift-webkit/1.1-M7/l... has the .scala sources buthttp://scala-tools.org/repo-snapshots/net/liftweb/lift-webkit/1.1-SNA... doesn't. - Indrajit On 19/11/09 12:32 AM, Kris Nuttycombe wrote: I recommend cloning dpp's github repository:http://github.com/dpp/liftweb Kris On Wed, Nov 18, 2009 at 11:41 AM, glenngl...@exmbly.com wrote: Where are all the java source files in http://scala-tools.org/repo-snapshots/net/liftweb/lift-webkit/1.1-SNA... It's kind of hard to debug without them. Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en. -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en. -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: Firefox error in returning a CreatedResponse
Ross, Yep, that fixes it. Thanks, although I'm not sure if the solution is worse than the problem. I mean, what possible side affects could turning off the use of Xhtml mime type have? Glenn On Nov 18, 11:23 am, Ross Mellgren dri...@gmail.com wrote: Try turning off the XHTML mime type by putting LiftRules.useXhtmlMimeType = false into your Boot and see if it goes away? -Ross On Nov 18, 2009, at 2:21 PM, glenn wrote: I'm returning Full(CreatedResponse(form, text/xhtml )) in LiftRules.DispatchPF, where form is just a MetaMapper.toForm node, which works fine in IE but fails in Firefox with the following error. XML or text declaration not at start of entity [Break on this error] div xmlns=http://www.w3.org/1999/xhtml;?xml version=1.0 encoding=UTF-8? (line 1) uncaught exception: [Exception... Component returned failure code: 0x80004003 (NS_ERROR_INVALID_POINTER) [nsIDOMNSHTMLElement.innerHTML] nsresult: 0x80004003 (NS_ERROR_INVALID_POINTER) location: JS frame ::http://localhost:8080/classpath/jquery.js:: anonymous :: line 251 data: no] Anyone have an idea why this happening? Glenn -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com . For more options, visit this group athttp://groups.google.com/group/liftweb?hl=en . -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: Missing source files in 1.1-SNAPSHOT
You can either use debugging facilities in Eclipse or, as I mostly do, sprinkle a lot of println or Log.info statements around. But coding it right in the first place requires access to Lift source code, and for that I use maven's facility for downloading source jars from the pom. If the source jar isn't complete, or isn't in the maven repository, I'm out of luck. Glenn On Nov 18, 1:19 pm, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Kris Nuttycombe kris.nuttyco...@gmail.com writes: On Wed, Nov 18, 2009 at 1:51 PM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Kris Nuttycombe kris.nuttyco...@gmail.com writes: On Wed, Nov 18, 2009 at 12:31 PM, glenn gl...@exmbly.com wrote: Kris, Don't want to clone the GitHub repo, as I need a Maven repo. Glenn Out of curiosity, is this because you have a Maven tool that helps automate interaction with a debugger? If so I'd be interested in learning about it - I've got a Lift bug I'm looking at now that would probably benefit from using an actual debugger on. If you use Eclipse, it can automatically get the sourc files from the sources jar. Open Type - Select e.g. Box - You get the Box.scala file. It is readonly though, so you can't easily try a quick hack /Jeppe Eclipse required? println debugging it is then! Yeah, 2.7.x is not that great. I'm really looking forward to 2.8, keep hearing lots of good stuff. But first we need Lift to work on 2.8 :-) /Jeppe -- You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to lift...@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.
[Lift] Re: ManyToMany decision
There is a related issue that if implemented, would certainly make the Mapper framework more robust - that of marking table rows for deletion, rather than deleting them directly. Some RDBMS's have a built-in marking function, and another function that actually removes rows that have been so marked. Glenn On Nov 12, 8:35 am, glenn gl...@exmbly.com wrote: Naftoli, Isn't this really a cascading delete issue and not one isolated to ManyToMany situations? Most ORM solutions allow for cascading deletes. Such a feature could be added to the Mapper class, itself, and hold a list of foreign key assignments that the delete function could iterate over, if turned on. Glenn On Nov 11, 9:31 am, Naftoli Gugenheim naftoli...@gmail.com wrote: To clarify: The fundamental purpose of ManyToMany, like OneToMany, is that rather than dealing with children of an entity as they are in the database at a given moment, instead, they should have similar semantics to a MappedField: You load it from the database, modify it to your hearts content, and then decide whether you want to save it or not. For example, calling set() on a MappedField does not write immediately to the database, and it's a good thing too--imagine a multi-page form where you can go back and forth to different screens, or a single page form that uses submit buttons that perform some action but you stay on the same page. You don't want the user's changes to go the database unless he clicks Save. So too, one often wants to edit a list on one screen. There should be submit buttons to add records, etc., but if you don't click save it shouldn't go to the database. So MappedOneToMany and MappedManyToMany act as collections, internally keeping track of which records were inserted or removed, but not performing a create or delete until the field is saved. So in other words they act as multi-valued fields. There are two ways MappedManyToMany can do this. It can hold a list of join table records, or child table records. Either way it will have to look up the other at times. Now in order for saves and deletes on the ManyToMany Mapper to be propagated to the MappedManyToMany fields, it has to have a list of them. The list only gets populated when code references the field, causing it to be initialized and add itself to the list of m-n fields. So we make all of these proposed changes? - Jim Barrowsjim.barr...@gmail.com wrote: On Tue, Nov 10, 2009 at 2:16 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: Hello. When I wrote ManyToMany a couple of months ago, I designed it to internally hold a collection of join table records, and to act as a collection of elements of the child table. For example, given Volunteer and VolunteerGroup where volunteers can be in multiple groups, Volunteer.volunteerGroups implements a collection of VolunteerGroups, but internally it's actually managing a collection of VolunteerVolunteerGroups (the join table). I don't think you really need to maintain the pivot table list (VolunteerVolunteerGroups) at all. If you maintain the Many-to-Many as part of the object, and use a standard naming convention then you don't really need this extra list running around. You can still build the SQL correctly knowing only the objects involved. The current implementation throws an error (Predef.error) when it tries to get the child element via the join record and it doesn't exist. Thus any page accessing corrupted data will not display if the error is not caught. I plan, G-d willing, to change the implementation to silently skip such records. But the occurrence that reminded me of the defect also brought another point to my attention. To my knowledge Lift's schemifier does not correctly generate foreign key constraints for all databases (at least not at the point in time it schemified my H2 database... :) ) so we need a way for ManyToMany to keep things in sync. ManyToMany helps, to an extent, because when its MappedManyToMany members are initialized, it puts them in a list, and it propagates saves and deletes. So if you have a ManyToMany Mapper instance that contains a MappedManyToMany that has been initialized, and you call delete_! on the Mapper, it will delete all the associated join table entries. But it's not enough. 1. That can only happen if both sides of the relationship use MappedManyToMany. Is there some way to enforce this? I was thinking of using a combination of (a) requiring the foreign MetaMapper to extends ManyToMany, and (b) when a MappedManyToMany is initialized, it should check that the foreign MetaMapper/ManyToMany actually contains a MappedManyToMany referring to the current MappedManyToMany. (a) is not sufficient without (b), and (b) has the same
[Lift] Re: ManyToMany decision
Naftoli, Isn't this really a cascading delete issue and not one isolated to ManyToMany situations? Most ORM solutions allow for cascading deletes. Such a feature could be added to the Mapper class, itself, and hold a list of foreign key assignments that the delete function could iterate over, if turned on. Glenn On Nov 11, 9:31 am, Naftoli Gugenheim naftoli...@gmail.com wrote: To clarify: The fundamental purpose of ManyToMany, like OneToMany, is that rather than dealing with children of an entity as they are in the database at a given moment, instead, they should have similar semantics to a MappedField: You load it from the database, modify it to your hearts content, and then decide whether you want to save it or not. For example, calling set() on a MappedField does not write immediately to the database, and it's a good thing too--imagine a multi-page form where you can go back and forth to different screens, or a single page form that uses submit buttons that perform some action but you stay on the same page. You don't want the user's changes to go the database unless he clicks Save. So too, one often wants to edit a list on one screen. There should be submit buttons to add records, etc., but if you don't click save it shouldn't go to the database. So MappedOneToMany and MappedManyToMany act as collections, internally keeping track of which records were inserted or removed, but not performing a create or delete until the field is saved. So in other words they act as multi-valued fields. There are two ways MappedManyToMany can do this. It can hold a list of join table records, or child table records. Either way it will have to look up the other at times. Now in order for saves and deletes on the ManyToMany Mapper to be propagated to the MappedManyToMany fields, it has to have a list of them. The list only gets populated when code references the field, causing it to be initialized and add itself to the list of m-n fields. So we make all of these proposed changes? - Jim Barrowsjim.barr...@gmail.com wrote: On Tue, Nov 10, 2009 at 2:16 PM, Naftoli Gugenheim naftoli...@gmail.comwrote: Hello. When I wrote ManyToMany a couple of months ago, I designed it to internally hold a collection of join table records, and to act as a collection of elements of the child table. For example, given Volunteer and VolunteerGroup where volunteers can be in multiple groups, Volunteer.volunteerGroups implements a collection of VolunteerGroups, but internally it's actually managing a collection of VolunteerVolunteerGroups (the join table). I don't think you really need to maintain the pivot table list (VolunteerVolunteerGroups) at all. If you maintain the Many-to-Many as part of the object, and use a standard naming convention then you don't really need this extra list running around. You can still build the SQL correctly knowing only the objects involved. The current implementation throws an error (Predef.error) when it tries to get the child element via the join record and it doesn't exist. Thus any page accessing corrupted data will not display if the error is not caught. I plan, G-d willing, to change the implementation to silently skip such records. But the occurrence that reminded me of the defect also brought another point to my attention. To my knowledge Lift's schemifier does not correctly generate foreign key constraints for all databases (at least not at the point in time it schemified my H2 database... :) ) so we need a way for ManyToMany to keep things in sync. ManyToMany helps, to an extent, because when its MappedManyToMany members are initialized, it puts them in a list, and it propagates saves and deletes. So if you have a ManyToMany Mapper instance that contains a MappedManyToMany that has been initialized, and you call delete_! on the Mapper, it will delete all the associated join table entries. But it's not enough. 1. That can only happen if both sides of the relationship use MappedManyToMany. Is there some way to enforce this? I was thinking of using a combination of (a) requiring the foreign MetaMapper to extends ManyToMany, and (b) when a MappedManyToMany is initialized, it should check that the foreign MetaMapper/ManyToMany actually contains a MappedManyToMany referring to the current MappedManyToMany. (a) is not sufficient without (b), and (b) has the same problem as #2 below, that objects are lazy. I think you're right here. Both sides have to have the mapping.. however I don't think there is a good clean way to detect this without a compiler plugin of some kind. 1. There is a basic problem, which is that since objects are lazy, if you haven't referenced the MappedManyToMany field, delete_! will not be able to propagate to the join entries. As you traverse the deleteing side, doesn't
[Lift] Re: How do you consume a JsonResponse in a Mapper.toForm snippet
I found that I can send the Mapper.toForm xml directly in an XmlResponse, rather than try to output JSON. However, that brought up another problem - bug, maybe - in that when I send Full(XmlResponse(item.toForm(Full(Save), { _.save }))) I get the following error: undefined entity [Break on this error] tdnbsp;/td This line is inserted before the Save button in the Mapper-generated form. Glenn On Nov 10, 2:40 pm, glenn gl...@exmbly.com wrote: I'm using XMLApiHelper to dispatch a JsonResponse to the client. My problem is I don't see how to consume the JSON object in my template, which calls a snippet myform(xhtml:NodeSeq):NodeSeq = toForm(Empty,) that outputs an empty Mapper form on the client. The JSON object is just the Mapper converted to JSON. I want the fields to be filled in with the data from the JsonResponse. Any help would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Problem with BlazeDS and LiftFilter 1.0+
David, (This is a copy of an earlier reply to your Migration Guide post. I didn't get any response there, so I'm listing it on this thread since it seems somewhat related to the current discussion) I attempted to follow your blog piece and rewrite the code in Integrating Flex, BlazeDS, and Scala/Lift, at http://flexonrails.net/?p=103. Maybe I'm being a bit ambitious to redo this, but when I run just the Lift portion (without Flex/BazeDS) and make a call to my LiftActor implementation, nothing happens. Shouldn't the messageHandler be called automatically (There is nothing to start, is there?). It doesn't when I trace through the code. What am I doing wrong? Here's my rewrite of Notifier using LiftActor: class Notifier extends LiftActor{ val msgBroker = MessageBroker.getMessageBroker(null) val clientID = UUIDUtils.createUUID() val msg = new AsyncMessage() var notificationsSent = 0; val currentTime = new Date().getTime(); protected def messageHandler = { case Notify ={ msg.setDestination(notifications) msg.setClientId(clientID) msg.setTimestamp(currentTime) msg.setBody(new Notification(notificationsSent, Hello from Scala/Lift, new Date())) msgBroker.routeMessageToService(msg,null) notificationsSent = 1 } LAPinger.schedule(this, Notify, 500L) } } case object Notify class Notification(var id: Int, var message: String, var timesent: Date){ def getId = id def setId(id: Int) = this.id = id def getMessage = message def setMessage(m: String) = message = m def getTimesent = timesent def setTimesent(t: Date) = timesent = t } I also have an XMLApiHelper with: def dispatch: LiftRules.DispatchPF = { case Req(webservices :: c :: Nil, , GetRequest)= () = start_feed(c:String) and start_feed simply calls new Notifiier(). Given this code, the URL: http://localhost:8080/webservices/Notify successfully calls into start_feed and creates Notifier but the messageHandler isn't called. Any help is appreciated? Thanks, Glenn On Nov 10, 3:58 pm, David Pollak feeder.of.the.be...@gmail.com wrote: Can you code up a full working example of what you want to do and post it on GitHub? On Sat, Nov 7, 2009 at 10:15 AM, oshyshko oshys...@gmail.com wrote: Removing BlazeDS servlet from LiftFilter coverage is a bad idea: If it is done so, lift-mapper creates separate transactions for all operations. http://groups.google.com/group/liftweb/browse_thread/thread/e2c0dd2c5... This means LiftFilter and BlazeDS servlet should become friends. LiftRules.passNotFoundToChain = true is in my Boot.scala. The response is: HTTP/1.1 200 OK Expires: Thu, 01 Jan 1970 00:00:00 GMT Set-Cookie: JSESSIONID=1a8mg0498vrwd;Path=/ Content-Length: 0 Server: Jetty(6.1.21) Note: if I remove LiftFilter, the servlet works fine. Any ideas how to make LiftFilter not to intrude into BlazeDS deeds? On Oct 31, 2:19 pm, Timothy Perrett timo...@getintheloop.eu wrote: You needed to specify the passNotFoundToChain var, thats why you were getting the 404 originally - as you detail, its not needed to explicitly set the /messagebroker URL in your web.xml. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Compiler errors switching to M6
I get the following compiler error when switching from M5 to M6 versions of Lift: ..\snippet\ManageUsers.scala:24: error: ManageUsers.this.ModelView does not take type parameters val view: ModelView[User] = new UserView(new User, this) Here's my code to this point: class UserView(entity:User, snippet:ManageUsers) extends ModelView [User](entity, snippet){ override val editAction = TheBindParam(edit, snippet.link(edit, ()=load, Text(S?(Edit Roles } class ManageUsers extends ModelSnippet[User]{ val view: ModelView[Userr] = new UserView(new User, this) ... } My question is two-fold: 1) What is the fix for this error? 2) What ever happened to backwards compatibility? I stopped using Snaptshots because changes kept breaking my code. I thought I was somewhat insulated from this problem going to released versions. Now, with M7 due to be released, what other problems am I going to face? Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Compiler errors switching to M6
David, I understand how to fix the compiler error in my code. Are you suggesting I'm better going back to the Snapshots, and taking my chances with the many code changes that requires? Glenn On Nov 3, 9:06 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Nov 3, 2009 at 8:56 AM, glenn gl...@exmbly.com wrote: I get the following compiler error when switching from M5 to M6 versions of Lift: ..\snippet\ManageUsers.scala:24: error: ManageUsers.this.ModelView does not take type parameters val view: ModelView[User] = new UserView(new User, this) Here's my code to this point: class UserView(entity:User, snippet:ManageUsers) extends ModelView [User](entity, snippet){ override val editAction = TheBindParam(edit, snippet.link(edit, ()=load, Text(S?(Edit Roles } class ManageUsers extends ModelSnippet[User]{ val view: ModelView[Userr] = new UserView(new User, this) ... } My question is two-fold: 1) What is the fix for this error? 2) What ever happened to backwards compatibility? Lift is evolving. The ModelView code is new in the 1.1 branch and is getting updated based on user feedback. I stopped using Snaptshots because changes kept breaking my code. Snapshots are the best way to keep up to date with code changes. You'll see more incremental changes to the APIs if you're on Snapshot than if you move multiple milestone releases. I thought I was somewhat insulated from this problem going to released versions. Milestones are not releases. They are milestones leading up to the 1.1 release which should happen in a few months. Now, with M7 due to be released, what other problems am I going to face? There are material breaking changes to Actor-related code as well as moving Box/Full/Empty from the lift-util to lift-common package. We document material breaking changes on this list with subjects: **BREAKING CHANGES** as well as on the new lift-announce list. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Compiler errors switching to M6
David, To follow up. I'd much rather use Snapshots than Milestones. Interim is interim, and I prefer to be in lockstep with the most current code base. But warnings on this forum notwithstanding, I have found myself in the past spending a lot of time fixing unexpected compiler errors, and I fear that sticking with milestones will just delay the inevitable. I know this is a common issue in any development scenario, Lift or otherwise...and I don't know of a satsifactory solution. Glenn On Nov 3, 9:11 am, glenn gl...@exmbly.com wrote: David, I understand how to fix the compiler error in my code. Are you suggesting I'm better going back to the Snapshots, and taking my chances with the many code changes that requires? Glenn On Nov 3, 9:06 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Nov 3, 2009 at 8:56 AM, glenn gl...@exmbly.com wrote: I get the following compiler error when switching from M5 to M6 versions of Lift: ..\snippet\ManageUsers.scala:24: error: ManageUsers.this.ModelView does not take type parameters val view: ModelView[User] = new UserView(new User, this) Here's my code to this point: class UserView(entity:User, snippet:ManageUsers) extends ModelView [User](entity, snippet){ override val editAction = TheBindParam(edit, snippet.link(edit, ()=load, Text(S?(Edit Roles } class ManageUsers extends ModelSnippet[User]{ val view: ModelView[Userr] = new UserView(new User, this) ... } My question is two-fold: 1) What is the fix for this error? 2) What ever happened to backwards compatibility? Lift is evolving. The ModelView code is new in the 1.1 branch and is getting updated based on user feedback. I stopped using Snaptshots because changes kept breaking my code. Snapshots are the best way to keep up to date with code changes. You'll see more incremental changes to the APIs if you're on Snapshot than if you move multiple milestone releases. I thought I was somewhat insulated from this problem going to released versions. Milestones are not releases. They are milestones leading up to the 1.1 release which should happen in a few months. Now, with M7 due to be released, what other problems am I going to face? There are material breaking changes to Actor-related code as well as moving Box/Full/Empty from the lift-util to lift-common package. We document material breaking changes on this list with subjects: **BREAKING CHANGES** as well as on the new lift-announce list. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: **Important** Migration guide Scala Actors - Lift Actors
David, I attempted to follow your blog piece and rewrite the code in Integrating Flex, BlazeDS, and Scala/Lift, at http://flexonrails.net/?p=103. Maybe I'm being a bit ambitious to redo this, but when I run just the Lift portion (without Flex/BazeDS) and make a call to my LiftActor implementation, nothing happens. Shouldn't the messageHandler be called automatically (There is nothing to start, is there?). It doesn't when I trace through the code. What am I doing wrong? Here's my rewrite of Notifier using LiftActor: class Notifier extends LiftActor{ val msgBroker = MessageBroker.getMessageBroker(null) val clientID = UUIDUtils.createUUID() val msg = new AsyncMessage() var notificationsSent = 0; val currentTime = new Date().getTime(); protected def messageHandler = { case Notify ={ msg.setDestination(notifications) msg.setClientId(clientID) msg.setTimestamp(currentTime) msg.setBody(new Notification(notificationsSent, Hello from Scala/Lift, new Date())) msgBroker.routeMessageToService(msg,null) notificationsSent = 1 } LAPinger.schedule(this, Notify, 500L) } } case object Notify class Notification(var id: Int, var message: String, var timesent: Date){ def getId = id def setId(id: Int) = this.id = id def getMessage = message def setMessage(m: String) = message = m def getTimesent = timesent def setTimesent(t: Date) = timesent = t } I also have an XMLApiHelper with: def dispatch: LiftRules.DispatchPF = { case Req(webservices :: c :: Nil, , GetRequest)= () = start_feed(c:String) and start_feed simply calls new Notifiier(). Given this code, the URL: http://localhost:8080/webservices/Notify successfully calls into start_feed and creates Notifier but the messageHandler isn't called. Any help is appreciated? Thanks, Glenn On Oct 22, 10:57 am, David Pollak feeder.of.the.be...@gmail.com wrote: Folks, I wrote a quick blog piece about migrating from Scala Actors to Lift Actors athttp://blog.lostlake.org/index.php?/archives/96-Migrating-from-Scala-... I hope this addresses questions that folks on the list have about the affirmative steps they need to take to make the migration. Thanks, David -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: How to create an rss?
I don't know if this will help, but I use a simple createTag to just enclose the full xml so it has a root element: def createTag(in: NodeSeq) = { apbul_apii{in}/apbul_api } and then showArticles would call into a feed wrapper, passing in the result of yield, like this for an Atom feed: //Reacts to Get all reguest def showArticles():AtomResponse = { val eList = for(e - Content.findAll) yield { e.toAtom } AtomResponse(feedWrapper(eList)) } Glenn On Oct 23, 6:24 am, wibblecp wibbl...@gmail.com wrote: hi guys, I'm looking for a way to generate an rss feed with lift, I'm working on something like this (from lift-book): object OwnRssFeed extends XMLApiHelper { def dispatch: LiftRules.DispatchPF = { case Req(rss :: Nil, , GetRequest) = () = showArticles() case Req(rss :: _ :: Nil, , _) = failure _ } def failure() : LiftResponse = { val ret: Box[NodeSeq] = Full(op id=FAILURE/op) NotFoundResponse() } def createTag(in: NodeSeq) = { println([CreateTag] + in) rss version=2.0 channel titletitle/title linkhttp://example.org/link descriptionExample.org/description languageen-us/language generatorLift WebFramework/generator {in} /channel /rss } def showArticles(): LiftResponse = { val a: Box[NodeSeq] = for(a - Article.find(By (Article.published, true))) yield { a.toXML } a } } obviously the yield into the definition of showArticles method break the cycle to the first one. Could you suggest me what I can do? I am evaluating lift and scala just in a while. Thanks for your attention. w. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Having trouble with form submission when using JavaScript to fetch the template
My JavaScript/JQuery programming is weak and I'm not sure how to explain the issue I'm having, but here goes... I have a simple template for editing and saving changes to a Mapper object: def edit(item: ModelType) = form {item.toForm(Full(Save), { _.save })} /form When I use a snippet to display the template on my page, the Save submit button works fine. However, when I grap the template from JavaScript on the client, using a function like: $('#show-form').load('/http:localhost:8080/getform'); the Save button doesn't work. Changes made on the form don't get saved. Here, the URL in load is intercepted in a dispatch rule that simply calls a function that gets the Mapper object from the DB and returns the template in a LiftResponse, like so: Full(CreatedResponse(edit(foundItem), text/xml)) Is the problem with JavaScript in this case or is there something in the dispatch rule that I'm failing to do? Any thoughts would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Having trouble with form submission when using JavaScript to fetch the template
If it helps, the HTML produced is identical, regardless of how the template is fetched. So this might suggest there is a problem with Request state regarding the Mapper object, but I don't understand why that should be so. Glenn On Oct 7, 9:12 am, glenn gl...@exmbly.com wrote: My JavaScript/JQuery programming is weak and I'm not sure how to explain the issue I'm having, but here goes... I have a simple template for editing and saving changes to a Mapper object: def edit(item: ModelType) = form {item.toForm(Full(Save), { _.save })} /form When I use a snippet to display the template on my page, the Save submit button works fine. However, when I grap the template from JavaScript on the client, using a function like: $('#show-form').load('/http:localhost:8080/getform'); the Save button doesn't work. Changes made on the form don't get saved. Here, the URL in load is intercepted in a dispatch rule that simply calls a function that gets the Mapper object from the DB and returns the template in a LiftResponse, like so: Full(CreatedResponse(edit(foundItem), text/xml)) Is the problem with JavaScript in this case or is there something in the dispatch rule that I'm failing to do? Any thoughts would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] How can I pass the result of Xml.toJson to JsonResponse
I want to pass the result of Xml.toJson to JsonResponse. How can I do that, when JsonResponse takes a JsExp as a parameter, not a JValue. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: How can I pass the result of Xml.toJson to JsonResponse
Sounds like it might work for me. What package and class is render found in. Glenn On Oct 6, 8:47 am, harryh har...@gmail.com wrote: For now I am doing this. It's not so bad. def xmlToJson(xml: Elem): JsExp = { val json = Xml.toJson(xml) map { // some mappings specific to my json needs } JsRaw(Printer.compact(render(json)) } JsonResponse(xmlToJson(xml)) On Oct 6, 11:17 am, David Pollak feeder.of.the.be...@gmail.com wrote: Please open a ticket for this. We need to get the rest of Lift playing well with Joni's excellent JSON library. On Tue, Oct 6, 2009 at 7:43 AM, glenn gl...@exmbly.com wrote: I want to pass the result of Xml.toJson to JsonResponse. How can I do that, when JsonResponse takes a JsExp as a parameter, not a JValue. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: How can I pass the result of Xml.toJson to JsonResponse
Never mind, I found it. Glenn On Oct 6, 9:02 am, glenn gl...@exmbly.com wrote: Sounds like it might work for me. What package and class is render found in. Glenn On Oct 6, 8:47 am, harryh har...@gmail.com wrote: For now I am doing this. It's not so bad. def xmlToJson(xml: Elem): JsExp = { val json = Xml.toJson(xml) map { // some mappings specific to my json needs } JsRaw(Printer.compact(render(json)) } JsonResponse(xmlToJson(xml)) On Oct 6, 11:17 am, David Pollak feeder.of.the.be...@gmail.com wrote: Please open a ticket for this. We need to get the rest of Lift playing well with Joni's excellent JSON library. On Tue, Oct 6, 2009 at 7:43 AM, glenn gl...@exmbly.com wrote: I want to pass the result of Xml.toJson to JsonResponse. How can I do that, when JsonResponse takes a JsExp as a parameter, not a JValue. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Help with using JSExp and JsCmd traits
David, Excellent. This is exactly what I was looking for. Thanks. Glenn On Sep 30, 4:54 pm, David Pollak feeder.of.the.be...@gmail.com wrote: JqHtml and JqEmptyAfter eagerly evaluate the NodeSeq on the server, so there's no way to get client-side JS execution in a NodeSeq. You can write something like: object MyJqText { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = text(+content.toJsCmd+) } } So: JqId(item-save) MyJqText(JsVar(this, id) + has changed) On Wed, Sep 30, 2009 at 2:05 PM, glenn gl...@exmbly.com wrote: As I mentioned, I was looking for a way to translate this JavaScript $('#item-save').html(this.id + ' was toggled') into a JsCmd so I could coded it my snipped as AnonFunc(some jsCmd). I know I can just use JsRaw, but who in their right mind wants to write JavaScript if it can be avoided. Glenn On Sep 30, 1:20 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Sep 30, 2009 at 1:08 PM, glenn gl...@exmbly.com wrote: David, The problem with writting the NodeSeq as div{this.id} was toggled/ div) is that it generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(div-1 was toggled/div); that is, Lift evaluates {this.id} in relation to the snippet, then outputs the value in the JavaScript - not the result I'm after. What are you after? What is this in the context? Glenn... On Sep 30, 11:41 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Sep 30, 2009 at 11:36 AM, glenn gl...@exmbly.com wrote: David, I can't do this, AnonFunc(JqId(item-save) JqEmptyAfter (divthis.id was toggled/div)) , if that's what you mean. That's not what I wrote. Please look again at the curly braces around the this.id: AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) This generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(divthis.idwas toggled/div); and that won't do. What's needed is something more akin to: function() {jQuery('#'+item-save).empty().after(div + this.id + was toggled/div); So, I guess my question is how do I define a NodeSeq to accomplish this? Glenn On Sep 30, 10:40 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Sep 29, 2009 at 1:22 PM, glenn gl...@exmbly.com wrote: I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw(this.id )} was toggled/div)) AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) No reason to promote this.id into some JavaScript thing. It's part of the XML literal. The XML literal is generated server-side as part of the JavaScript function. but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Help with using JSExp and JsCmd traits
David, This is off topic, but you always are a help. Your thoughtful assistance on this discussion group either directly resolves issues I'm having with Lift, or leads me to rethink my strategy and explore new avenues I haven't thought of. At the very least, you force me to reframe many of my questions, so they can be answered. Many times, I've thought of abandoning Lift for safer harbors, but the help from you and all on this group brings me back to the fold. I've still got lots to learn. Glenn On Oct 1, 8:29 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Oct 1, 2009 at 8:25 AM, glenn gl...@exmbly.com wrote: David, Excellent. This is exactly what I was looking for. Wow. I think this is the first time I've actually helped you. I'm sorry I'm bad at understanding what you ask for. More broadly, the JavaScript stuff in Lift is not magic. It's just a bunch of simple JavaScript that I and some of the other committers have used over time. I encourage the creation of your own JsCmd and JsExp components that suit your project... and maybe even share them with the community. Thanks. Glenn On Sep 30, 4:54 pm, David Pollak feeder.of.the.be...@gmail.com wrote: JqHtml and JqEmptyAfter eagerly evaluate the NodeSeq on the server, so there's no way to get client-side JS execution in a NodeSeq. You can write something like: object MyJqText { def apply(content: JsExp) = new JsExp with JQueryRight with JQueryLeft { def toJsCmd = text(+content.toJsCmd+) } } So: JqId(item-save) MyJqText(JsVar(this, id) + has changed) On Wed, Sep 30, 2009 at 2:05 PM, glenn gl...@exmbly.com wrote: As I mentioned, I was looking for a way to translate this JavaScript $('#item-save').html(this.id + ' was toggled') into a JsCmd so I could coded it my snipped as AnonFunc(some jsCmd). I know I can just use JsRaw, but who in their right mind wants to write JavaScript if it can be avoided. Glenn On Sep 30, 1:20 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Sep 30, 2009 at 1:08 PM, glenn gl...@exmbly.com wrote: David, The problem with writting the NodeSeq as div{this.id} was toggled/ div) is that it generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(div-1 was toggled/div); that is, Lift evaluates {this.id} in relation to the snippet, then outputs the value in the JavaScript - not the result I'm after. What are you after? What is this in the context? Glenn... On Sep 30, 11:41 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Sep 30, 2009 at 11:36 AM, glenn gl...@exmbly.com wrote: David, I can't do this, AnonFunc(JqId(item-save) JqEmptyAfter (divthis.id was toggled/div)) , if that's what you mean. That's not what I wrote. Please look again at the curly braces around the this.id: AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) This generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(divthis.idwas toggled/div); and that won't do. What's needed is something more akin to: function() {jQuery('#'+item-save).empty().after(div + this.id + was toggled/div); So, I guess my question is how do I define a NodeSeq to accomplish this? Glenn On Sep 30, 10:40 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Sep 29, 2009 at 1:22 PM, glenn gl...@exmbly.com wrote: I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw( this.id )} was toggled/div)) AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) No reason to promote this.id into some JavaScript thing. It's part of the XML literal. The XML literal is generated server-side as part of the JavaScript function. but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view
[Lift] Re: Help with using JSExp and JsCmd traits
David, The problem with writting the NodeSeq as div{this.id} was toggled/ div) is that it generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(div-1 was toggled/div); that is, Lift evaluates {this.id} in relation to the snippet, then outputs the value in the JavaScript - not the result I'm after. Glenn... On Sep 30, 11:41 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Sep 30, 2009 at 11:36 AM, glenn gl...@exmbly.com wrote: David, I can't do this, AnonFunc(JqId(item-save) JqEmptyAfter (divthis.id was toggled/div)) , if that's what you mean. That's not what I wrote. Please look again at the curly braces around the this.id: AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) This generates the following JavaScript: function() {jQuery('#'+item-save).empty().after(divthis.id was toggled/div); and that won't do. What's needed is something more akin to: function() {jQuery('#'+item-save).empty().after(div + this.id + was toggled/div); So, I guess my question is how do I define a NodeSeq to accomplish this? Glenn On Sep 30, 10:40 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Sep 29, 2009 at 1:22 PM, glenn gl...@exmbly.com wrote: I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw(this.id)} was toggled/div)) AnonFunc(JqId(item-save) JqEmptyAfter(div{this.id} was toggled/div)) No reason to promote this.id into some JavaScript thing. It's part of the XML literal. The XML literal is generated server-side as part of the JavaScript function. but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Help with using JSExp and JsCmd traits
I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw(this.id)} was toggled/div)) but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Help with using JSExp and JsCmd traits
Hi, Ross, Unfornately, all of these just result in: function() {jQuery('#'+item-save).empty().after(divthis.id was toggled/div);} They simply treat this.id as part of the passed in NodeSeq, divthis.id was toggled/div. I need it to output divthis.id + was toggled/div. Glenn On Sep 29, 1:46 pm, Ross Mellgren dri...@gmail.com wrote: Try JsVar(this, id) or JsRaw(this.id) -Ross On Sep 29, 2009, at 4:22 PM, glenn wrote: I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw(this.id)} was toggled/div)) but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Help with using JSExp and JsCmd traits
Ross, I think you and I came to same conclusion. Writing it as raw JavaScript, as I did initially, seems the only way I could find to do this. FYI, where I was using this was with the TreeView widget. There, toggle takes an anonymous function, and this is an implicit parameter, denoting the Tree selected. val func = JsRaw(function() $('#item-save').html(this.id + ' was toggled')) TreeView(tree, JsObj((persist, location),(toggle, func)), loadTree, loadNode) I was hoping for a more functional way to write func, in order to do more complex processing on the client. Glenn On Sep 29, 2:55 pm, Ross Mellgren dri...@gmail.com wrote: Oh I'm sorry, I got tunnel vision and did not read the rest of your code. You'll not be able to do quite what you want, since this.id is on the javascript side and the NodeSeq is on the server side. If you really want this.id within that div, I think you'll have to construct or modify the div on the JS side. I rummaged through the Lift jQuery docs and I couldn't find something that will append/inject to a JQueryLeft (such as JqId) but using a JsExp and not a fixed NodeSeq. This is not to say there isn't such a thing, just that I couldn't find it. Of course, you can whip this up using the lower level javascript stuff: AnonFunc(JqId(item-save) ~ JsFunc(empty) ~ JsFunc(after, Call(jQuery, div was toggled/div) ~ JsFunc(prepend, JsVar(this, id Of course, at that point I'd just say it might be a better idea to write the JavaScript directly, since this expands to $(#item-save).empty().after($(div was toggled/div).prepend (this.id)); -Ross On Sep 29, 2009, at 5:22 PM, glenn wrote: Hi, Ross, Unfornately, all of these just result in: function() {jQuery('#'+item-save).empty().after(divthis.id was toggled/div);} They simply treat this.id as part of the passed in NodeSeq, divthis.id was toggled/div. I need it to output divthis.id + was toggled/div. Glenn On Sep 29, 1:46 pm, Ross Mellgren dri...@gmail.com wrote: Try JsVar(this, id) or JsRaw(this.id) -Ross On Sep 29, 2009, at 4:22 PM, glenn wrote: I'd like to converting the following JsRaw(function() $('#item-save').html(this.id + ' was toggled')) into something more object-oriented, using JQuery support functions in Lift. I've tried various combiniations, including this AnonFunc(JqId(item-save) JqEmptyAfter(div{JsRaw(this.id)} was toggled/div)) but nothing seems to work. It just treats this.id as ordinary text, not as a Javascript variable. Any ideas would be appreciated. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: How can I replace SHtml.a with a Loc
David, Thanks for the reply. The Loc, itself, though. How do I write that to create the Ajax link. I want to be able to modify an html element when the link is clicked, as in SetHtml(item-save, edit(item)). Glenn On Sep 24, 5:05 pm, David Pollak feeder.of.the.be...@gmail.com wrote: val myLoc: Loc[_] = ... bind(item, xhtml, addNew - a href={myLoc.createDefaultLink}Hello/a) On Wed, Sep 23, 2009 at 11:25 AM, glenn gl...@exmbly.com wrote: I have a snippet that creates a Ajax link. bind(item, xhtml, addNew - {SHtml.a({ ()= SetHtml(item-save, edit(item))}, Text(MenuTitle_Add) )} ) How would I, instead, create the same or similar link using a Loc? Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: How can I replace SHtml.a with a Loc
David, In this case, I was trying to see if there was a way to use the standard Lift menu generator to create a link with a callback for ajax handling, similar to SHtml.a. I don't know about menu generation from SiteMap. Perhaps that's what I really need. What would that look like? Glenn On Sep 25, 8:22 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Fri, Sep 25, 2009 at 8:13 AM, glenn gl...@exmbly.com wrote: David, Thanks for the reply. The Loc, itself, though. How do I write that to create the Ajax link. I want to be able to modify an html element when the link is clicked, as in SetHtml(item-save, edit(item)). Sorry... didn't quite understand. Are you using your own menu generator or the standard Lift menu generator? I'm thinking that we have to uniquely identify (put a knowable id on) each a href that is generated. If you're doing your own menu generation from SiteMap, you can probably get your code to work by using the name of the Loc as the id. If you're using the standard Lift Menu snippet to create your menus, you'll have to open a ticket, I'll prioritize the ticket, then we'll wait for review board and then you'll get your change. Glenn On Sep 24, 5:05 pm, David Pollak feeder.of.the.be...@gmail.com wrote: val myLoc: Loc[_] = ... bind(item, xhtml, addNew - a href={myLoc.createDefaultLink}Hello/a) On Wed, Sep 23, 2009 at 11:25 AM, glenn gl...@exmbly.com wrote: I have a snippet that creates a Ajax link. bind(item, xhtml, addNew - {SHtml.a({ ()= SetHtml(item-save, edit(item))}, Text(MenuTitle_Add) )} ) How would I, instead, create the same or similar link using a Loc? Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Surf the harmonics --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Using Mapper to model entity hierarchies
In the interest of sharing ideas with the larger Lift community, I found myself creating many different mapper classes to model a hierarchy of entities best viewed in a tree, such as roles, tags and navigation links. To reduce code duplication, and to try to better understand Mapper classes, I went about creating a tree item mapper trait and its companion meta mapper object. I defined the item mapper as: trait MegaTreeItem[T : MegaTreeItem[T]] extends KeyedMapper[Long, T] { .. } which has a parent (owner) metamapper object of type T, an itemName MappedString and some useful, though not an exhaustive number of functions. and the meta mapper trait MetaMegaTreeItem[ModelType : MegaTreeItem[ModelType]] extends KeyedMetaMapper[Long, ModelType] {..} which contains menu Locs and template/snippet functions for list and tree table display. So, creating a tag mapper is a cinch: object Tag extends Tag with MetaMegaTreeItem[Tag] { } class Tag extends MegaTreeItem[Tag]{ def getSingleton = Tag def owner = Tag } I'm still mystified about the workings of Mappers and MetaMappers and why creating new mapper traits has to be so wordy (maybe not, if I understood better), but this does do the job. You can see the code and all of this actually functioning (Yeah!), by grabbing it on github, at http://github.com/glennSilverman/democritus Disclaimer: I could not get the tree table to work in IE 8. I think it's a problem with the JQuery javascript. It works great in Firefox, however. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] How can I replace SHtml.a with a Loc
I have a snippet that creates a Ajax link. bind(item, xhtml, addNew - {SHtml.a({ ()= SetHtml(item-save, edit(item))}, Text(MenuTitle_Add) )} ) How would I, instead, create the same or similar link using a Loc? Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] TreeView widget doesn't work with IE 8
The TreeView widget doesn't work in IE 8. I haven't tested in earlier versions. It does work in the latest FireFox. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Code Plugability in Lift
Forgive me. I'm bringing up the subject of modularization in Lift under a new heading, but the last discussion was, sadly, all over the map and only served to emphasize the problem. So let me narrow it down, a bit, here, and ask: How is it possible to create two different snippet implementations, or two different models, one JPA and one not, or one using the mapper framework and another the record, and replace one with the other without having to recompile the application? We're not talking here about interface design - you still have to deal with boot. And traits, as has been suggested by others...well, you'd better not expose them to the world outside your implementation, as any changes would require recompilation. In other words, you can't really use traits for your interface. To use Lift in the enterprise does require that teams be able to work independently, doesn't it. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Code Plugability in Lift
David, Does this mean you could write an entity class, like so: class User(val firstName: String, val lastName: String, val userName: String, val email: String, val password: String) with myTrait {...} and it would be useable in either a JPA or mapper or record implementation? That would be the ticket. Glenn On Sep 21, 12:47 pm, David Pollak feeder.of.the.be...@gmail.com wrote: This is an impedance mis-match between POJOs (what JPA expects) and the richer fields that Mapper and Record have. I'm working on an interface (http://github.com/dpp/liftweb/blob/master/lift-util/src/main/scala/ne...) that should be a base trait on everything in Lift that's gettable or gettable/settable. Then you could write a trait that looks like: trait MyThing { def name: PSettableValueHolder[String] * * * def getName(): String = name.is* * def setName(in: String) = name.set(in)* * * * * } Such a trait should be able to bridge a JPA implementation and a Lift mapper implementation. If you've got a better solution, please code it up and let's talk about it. On Mon, Sep 21, 2009 at 9:31 AM, glenn gl...@exmbly.com wrote: Forgive me. I'm bringing up the subject of modularization in Lift under a new heading, but the last discussion was, sadly, all over the map and only served to emphasize the problem. So let me narrow it down, a bit, here, and ask: How is it possible to create two different snippet implementations, or two different models, one JPA and one not, or one using the mapper framework and another the record, and replace one with the other without having to recompile the application? We're not talking here about interface design - you still have to deal with boot. And traits, as has been suggested by others...well, you'd better not expose them to the world outside your implementation, as any changes would require recompilation. In other words, you can't really use traits for your interface. To use Lift in the enterprise does require that teams be able to work independently, doesn't it. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: Code Plugability in Lift
David, What about using implicits? implicit def stringDataWrapper(s :String) = ... to apply the requisite trait. Is that doable? Glenn On Sep 21, 2:03 pm, glenn gl...@exmbly.com wrote: David, Does this mean you could write an entity class, like so: class User(val firstName: String, val lastName: String, val userName: String, val email: String, val password: String) with myTrait {...} and it would be useable in either a JPA or mapper or record implementation? That would be the ticket. Glenn On Sep 21, 12:47 pm, David Pollak feeder.of.the.be...@gmail.com wrote: This is an impedance mis-match between POJOs (what JPA expects) and the richer fields that Mapper and Record have. I'm working on an interface (http://github.com/dpp/liftweb/blob/master/lift-util/src/main/scala/ne...) that should be a base trait on everything in Lift that's gettable or gettable/settable. Then you could write a trait that looks like: trait MyThing { def name: PSettableValueHolder[String] * * * def getName(): String = name.is* * def setName(in: String) = name.set(in)* * * * * } Such a trait should be able to bridge a JPA implementation and a Lift mapper implementation. If you've got a better solution, please code it up and let's talk about it. On Mon, Sep 21, 2009 at 9:31 AM, glenn gl...@exmbly.com wrote: Forgive me. I'm bringing up the subject of modularization in Lift under a new heading, but the last discussion was, sadly, all over the map and only served to emphasize the problem. So let me narrow it down, a bit, here, and ask: How is it possible to create two different snippet implementations, or two different models, one JPA and one not, or one using the mapper framework and another the record, and replace one with the other without having to recompile the application? We're not talking here about interface design - you still have to deal with boot. And traits, as has been suggested by others...well, you'd better not expose them to the world outside your implementation, as any changes would require recompilation. In other words, you can't really use traits for your interface. To use Lift in the enterprise does require that teams be able to work independently, doesn't it. Glenn -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: JSON forms problem
Derek, Here is my complete head method: def head = headscript type=text/javascript src={/ + LiftRules.resourceServerPath + /jlift.js} / {Script(json.jsCmd)}/head Also, why do you use variable binding in your case pattern (j @ JsonCmd (processForm...). You don't refer to the variable anywhere in the function body, so this should work just as nicely without it (case case JsonCmd(processForm...) Glenn On Sep 16, 10:11 am, Derek Chen-Becker dchenbec...@gmail.com wrote: I'll fix the book right now, but could you please send your complete head method so that I make sure to include the correct code? Derek On Wed, Sep 16, 2009 at 9:30 AM, glenn gl...@exmbly.com wrote: Marius, You are right. I added script type=text/javascript src={/ + LiftRules.resourceServerPath + /jlift.js} / to my head method, and everything works great. The issue here, is that the Lift Book example doesn't mention this. Glenn On Sep 15, 9:07 pm, marius d. marius.dan...@gmail.com wrote: Right ... the head method should not have the js script but did you include the jlift.js script in your default template? I'll build an example this week (when I'll find some time for it) and see if I'm running into the same problems as you are. If you somehow manage to fix it please let me know. How urgent is this for you? Br's, Marius On Sep 15, 6:15 pm, glenn gl...@exmbly.com wrote: But, the head method does add the javascript to the page, so no src attribute is needed, right? On Sep 15, 3:59 pm, marius d. marius.dan...@gmail.com wrote: Where is the head function in your code ? Here is an example: def head = headscript type=text/javascript src=/classpath/ jlift.js / {Script(json.jsCmd)}/head Br's, Marius On Sep 15, 5:55 pm, marius d. marius.dan...@gmail.com wrote: Do you see any errors in FireBug ? ... Do see the Ajax request being send out in FireBug? On Sep 15, 5:49 pm, glenn gl...@exmbly.com wrote: Derek, Here is the template. Just as in the book. lift:surround with=default at=content lift:JSONForm.head / lift:JSONForm.show input type=text name=name / br / input type=text name=value / br / input type=radio name=vehicle value=Bike / input type=radio name=vehicle value=Car / input type=radio name=vehicle value=Airplane / br / select name=cars option value=volvoVolvo/option option value=saabSaab/option option value=opelOpel/option option value=audiAudi/option /select button type=submitSubmit/button /lift:JSONForm.show div id=json_result/div /lift:surround And here is my JSONForm class: class JSONForm { def head = head{Script(json.jsCmd)}/head def show(html: Group): NodeSeq = { json.jsCmd SHtml.jsonForm(json, html) } object json extends JsonHandler { def apply(in: Any): JsCmd = SetHtml(json_result, Text(This is a test)) } } Here, I just simplified the JsCmd returned from the handler. I understand that in the head method, the call to json.jsCmd creates the ajax handler (from the apply method), but clicking on the submit button on the form doesn't populate the json_result div. In fact, it doesn't do anything even though, on the page source, the button's onclick method is wired up. Glenn On Sep 15, 11:59 am, Derek Chen-Becker dchenbec...@gmail.com wrote: The apply method should be getting called because the SHtml.json method should register it as the handler for the form. Would you mind sending me the code you have and I'll take a look at it? I'm pretty sure this code was working at one point, but perhaps something has changed. Derek On Mon, Sep 14, 2009 at 2:03 PM, glenn gl...@exmbly.com wrote: Actually, the JsonHandler in the example gets called, but not the apply (in:Any) method, as that is never called in the book example. Also, the handler seems to be called twice with every submit. Why is that? Glenn On Sep 14, 8:08 am, glenn gl...@exmbly.com wrote: This may be a question for the Lift Book forum, but has anyone gotten the JSON forms example 8.13 in the Lift Book to work? When I tried it, the JsonHandler in class JSONForm never gets called when the submit button is clicked. Glenn --~--~-~--~~~---~--~~ 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
[Lift] Re: JSON forms problem
Marius, You are right. I added script type=text/javascript src={/ + LiftRules.resourceServerPath + /jlift.js} / to my head method, and everything works great. The issue here, is that the Lift Book example doesn't mention this. Glenn On Sep 15, 9:07 pm, marius d. marius.dan...@gmail.com wrote: Right ... the head method should not have the js script but did you include the jlift.js script in your default template? I'll build an example this week (when I'll find some time for it) and see if I'm running into the same problems as you are. If you somehow manage to fix it please let me know. How urgent is this for you? Br's, Marius On Sep 15, 6:15 pm, glenn gl...@exmbly.com wrote: But, the head method does add the javascript to the page, so no src attribute is needed, right? On Sep 15, 3:59 pm, marius d. marius.dan...@gmail.com wrote: Where is the head function in your code ? Here is an example: def head = headscript type=text/javascript src=/classpath/ jlift.js / {Script(json.jsCmd)}/head Br's, Marius On Sep 15, 5:55 pm, marius d. marius.dan...@gmail.com wrote: Do you see any errors in FireBug ? ... Do see the Ajax request being send out in FireBug? On Sep 15, 5:49 pm, glenn gl...@exmbly.com wrote: Derek, Here is the template. Just as in the book. lift:surround with=default at=content lift:JSONForm.head / lift:JSONForm.show input type=text name=name / br / input type=text name=value / br / input type=radio name=vehicle value=Bike / input type=radio name=vehicle value=Car / input type=radio name=vehicle value=Airplane / br / select name=cars option value=volvoVolvo/option option value=saabSaab/option option value=opelOpel/option option value=audiAudi/option /select button type=submitSubmit/button /lift:JSONForm.show div id=json_result/div /lift:surround And here is my JSONForm class: class JSONForm { def head = head{Script(json.jsCmd)}/head def show(html: Group): NodeSeq = { json.jsCmd SHtml.jsonForm(json, html) } object json extends JsonHandler { def apply(in: Any): JsCmd = SetHtml(json_result, Text(This is a test)) } } Here, I just simplified the JsCmd returned from the handler. I understand that in the head method, the call to json.jsCmd creates the ajax handler (from the apply method), but clicking on the submit button on the form doesn't populate the json_result div. In fact, it doesn't do anything even though, on the page source, the button's onclick method is wired up. Glenn On Sep 15, 11:59 am, Derek Chen-Becker dchenbec...@gmail.com wrote: The apply method should be getting called because the SHtml.json method should register it as the handler for the form. Would you mind sending me the code you have and I'll take a look at it? I'm pretty sure this code was working at one point, but perhaps something has changed. Derek On Mon, Sep 14, 2009 at 2:03 PM, glenn gl...@exmbly.com wrote: Actually, the JsonHandler in the example gets called, but not the apply (in:Any) method, as that is never called in the book example. Also, the handler seems to be called twice with every submit. Why is that? Glenn On Sep 14, 8:08 am, glenn gl...@exmbly.com wrote: This may be a question for the Lift Book forum, but has anyone gotten the JSON forms example 8.13 in the Lift Book to work? When I tried it, the JsonHandler in class JSONForm never gets called when the submit button is clicked. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Code broken due to hanges to ModelView
I realize the risk one takes in using the latest SNAPSHOT source, but there seems to be a recent change to ModelView in the mapper package such that now, it doesn't take type parameters. My questions is, if in my existing ModelSnippet code, I have val view: ModelView[User] = new UserView(new User, this) where UserView extends ModelView[User], what do I do to fix this error? Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Code broken due to hanges to ModelView
Further compounding my confusion, is that the mapper.view package from the maven repo, http://scala-tools.org/repo-snapshots, is not in GitHub, so are the two repositories out-of-sync, and have they always been so? Glenn On Sep 16, 8:45 am, glenn gl...@exmbly.com wrote: I realize the risk one takes in using the latest SNAPSHOT source, but there seems to be a recent change to ModelView in the mapper package such that now, it doesn't take type parameters. My questions is, if in my existing ModelSnippet code, I have val view: ModelView[User] = new UserView(new User, this) where UserView extends ModelView[User], what do I do to fix this error? Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Code broken due to hanges to ModelView
Naftoli, Pardon this new discussion. I just discovered your earlier post on this issue. However, the source for ModelView still shows it taking a type parameter. Has that not been updated yet? Glenn On Sep 16, 8:53 am, glenn gl...@exmbly.com wrote: Further compounding my confusion, is that the mapper.view package from the maven repo,http://scala-tools.org/repo-snapshots, is not in GitHub, so are the two repositories out-of-sync, and have they always been so? Glenn On Sep 16, 8:45 am, glenn gl...@exmbly.com wrote: I realize the risk one takes in using the latest SNAPSHOT source, but there seems to be a recent change to ModelView in the mapper package such that now, it doesn't take type parameters. My questions is, if in my existing ModelSnippet code, I have val view: ModelView[User] = new UserView(new User, this) where UserView extends ModelView[User], what do I do to fix this error? Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: MINOR BREAKING CHANGE IN mapper.view.ModelView
Naftoli, Since I don't seem to have the latest source to follow, how exactly does this work now?. If I currently have:this as my ModelView class UserView(entity:User, snippet:ManageUsers) extends ModelView [User](entity, snippet) and val view: ModelView[User] = new UserView(new User,this) in my ModelSnippet, leaving off the User type parameter doesn't compile and neither does removing the this parameter or the snippet parameter in the UserView type definition. Glenn On Sep 14, 3:10 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: If you useModelViewin a ModelSnippet, read the following: I added an inner class to mapper.view.ModelSnippet calledModelView, which extends mapper.view.ModelViewbut allows you to leave out the snippet parameter. However if you were using these new classes you may have to make a small change. If you useModelViewinside ModelSnippet, just leave out this from the constructor. You may also be able to change ModelView to view.ModelView. The Wiki article may not yet reflect this. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: JSON forms problem
Derek, Here is the template. Just as in the book. lift:surround with=default at=content lift:JSONForm.head / lift:JSONForm.show input type=text name=name / br / input type=text name=value / br / input type=radio name=vehicle value=Bike / input type=radio name=vehicle value=Car / input type=radio name=vehicle value=Airplane / br / select name=cars option value=volvoVolvo/option option value=saabSaab/option option value=opelOpel/option option value=audiAudi/option /select button type=submitSubmit/button /lift:JSONForm.show div id=json_result/div /lift:surround And here is my JSONForm class: class JSONForm { def head = head{Script(json.jsCmd)}/head def show(html: Group): NodeSeq = { json.jsCmd SHtml.jsonForm(json, html) } object json extends JsonHandler { def apply(in: Any): JsCmd = SetHtml(json_result, Text(This is a test)) } } Here, I just simplified the JsCmd returned from the handler. I understand that in the head method, the call to json.jsCmd creates the ajax handler (from the apply method), but clicking on the submit button on the form doesn't populate the json_result div. In fact, it doesn't do anything even though, on the page source, the button's onclick method is wired up. Glenn On Sep 15, 11:59 am, Derek Chen-Becker dchenbec...@gmail.com wrote: The apply method should be getting called because the SHtml.json method should register it as the handler for the form. Would you mind sending me the code you have and I'll take a look at it? I'm pretty sure this code was working at one point, but perhaps something has changed. Derek On Mon, Sep 14, 2009 at 2:03 PM, glenn gl...@exmbly.com wrote: Actually, the JsonHandler in the example gets called, but not the apply (in:Any) method, as that is never called in the book example. Also, the handler seems to be called twice with every submit. Why is that? Glenn On Sep 14, 8:08 am, glenn gl...@exmbly.com wrote: This may be a question for the Lift Book forum, but has anyone gotten the JSON forms example 8.13 in the Lift Book to work? When I tried it, the JsonHandler in class JSONForm never gets called when the submit button is clicked. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] JSON forms problem
This may be a question for the Lift Book forum, but has anyone gotten the JSON forms example 8.13 in the Lift Book to work? When I tried it, the JsonHandler in class JSONForm never gets called when the submit button is clicked. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: JSON forms problem
Actually, the JsonHandler in the example gets called, but not the apply (in:Any) method, as that is never called in the book example. Also, the handler seems to be called twice with every submit. Why is that? Glenn On Sep 14, 8:08 am, glenn gl...@exmbly.com wrote: This may be a question for the Lift Book forum, but has anyone gotten the JSON forms example 8.13 in the Lift Book to work? When I tried it, the JsonHandler in class JSONForm never gets called when the submit button is clicked. Glenn --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Wizard code in master
Is this wizard code available for review somewhere? I'm writing a snippet that allows users to add or edit site content - heading, summary, tags, etc. - and then depending on the content type selected - html, file, form, etc. - takes the user to a page specifically for adding/editing that content type (e.g. a file upload page, if that is required). Glenn On Sep 3, 3:38 am, Timothy Perrett timo...@getintheloop.eu wrote: Thought as much ;-) Just something else to throw into discussion, but perhaps it would be great ifwizardprocesses could be serialised into a couple of formats (XML, JSON??)... this is something that I could see myself using to load differentwizardsteps dynamically from my database or such. Cheers, Tim Right now, I think it's vomit in process, but later it will turn into work in process and later code suitable for others to make fun of. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Milestone 5 now available!
Does this milestone incorporate what's in 1.1-Snapshot? Glenn On Sep 8, 9:57 pm, Charles F. Munat c...@munat.com wrote: The Lift team proudly announces Milestone 5! Some text here that I forgot to copy and paste. Go get it! Chas. Munat --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Using Roles and LIftRules.authentication
Marius, With your help, I think I'm getting closer to understanding what is needed here. One thing though, is that I believe I do need to manually check if the user has the appropriate role (in the DB) before I can set userRoles RequestVar. See, in my application, I have no way of knowing in advance if a logged-in user is authorized to access a particular resource. I'm trying to accomplish that programatically. And, don't forget, roles can be changed at any time in the application. In other words, I can't just assume it in my authentication function and make the assignment there. Does that make sense? This is not to say that I can't work tangentially to Http basic authentication in Lift and create my own, just that I'm trying to incorporate the work already done so I don't have to. Glenn On Sep 7, 11:24 pm, marius d. marius.dan...@gmail.com wrote: On Sep 8, 1:18 am, glenn gl...@exmbly.com wrote: Marius, Please bear with me. I'm a little slow in following the logic here. Don't worry glen. I understand I can protect the resource as you suggest from all but users with admin roles, using the LocParam, HttpAuthProtected(() = Full(AuthRole(admin) . Now, when I click on the link, if no user is logged in, the system asks for a username and password to connect, but that's a user on the host. not an application user. Not necessarily. It is any type of user. In your authentication function you can go in DB and validate the receiving credentials as application user. Somewhere, I need to assign the currently logged in user the AuthRole(admin) needed to access the resource. Correct. And you dothis by setting userRoles RequestVar. Seems to me I need code like this to run someplace: def authorize(roleName:String): Box[Role] = { object userRoles extends RequestVar[Role](null) val credentials : (String,String) = User.currentUser match { case Full(u) = (u.email.is, u.password.is) case Empty = (null, null) } User.isa_?(roleName) match { case true = { LiftRules.authentication = HttpBasicAuthentication(lift) { case (credentials._1, credentials._2, req) = println(John is authenticated!) userRoles(_root_.net.liftweb.http.auth.AuthRole (roleName)) true } Full(new _root_.net.liftweb.http.auth.Role{ def name = roleName}) } case false = Empty } } Can't be in Boot, No you do not. Lift takes care of the roles matching for you. You don't need to manually test if a user is-an admin or some other role in order to access that resource. Please keep in mind that is just for accessing resources (URI-s) if you need to do more complex logic in your code and see if the user is an admin or having some other Role that you'd probably need to save the Role into a SessionVar or into your User object. All I want here is to explain how HTTP based authentication and roles based authorization works. I am definitely not claiming that this is enough for all applications as currently we don't have HTTP based authentication with forms for example ... but I think we should add that as well. Glenn On Sep 7, 1:36 pm, marius d. marius.dan...@gmail.com wrote: On Sep 7, 10:53 pm, glenn gl...@exmbly.com wrote: Marius, In practical terms, if I am already using an If LocParam, as in the following: If(() = User.isa_?(admin), S.?(not_authorized)) what does adding HttpAuthProtected(() = User.authorize(admin)) to the Loc do? It sais that this Loc is protected by the returned Role. Thus to access this after passing the authentication the Role specified in the authentication function (by setting userRoles) must be the same as or a child of the Role the is protecting the Loc. Here, I've had to define User.authorize to make things work, as: def authorize(roleName:String): Box[Role] = { val credentials : (String,String) = User.currentUser match { case Full(u) = (u.email.is, u.password.is) case Empty = (null, null) } User.isa_?(roleName) match { case true = { LiftRules.httpAuthProtectedResource.append { case (ParsePath(listContents :: _, _, _, _)) = Full (AuthRole(admin)) } Why do you need to use httpAuthProtectedResource if you' using HttpAuthProtected LocParam ? LiftRules.authentication = HttpBasicAuthentication(lift) { case (credentials._1, credentials._2, req) = AuthRole(roleName) true } Full(new _root_.net.liftweb.http.auth.Role{ def name = roleName}) } case
[Lift] Re: Using Roles and LIftRules.authentication
Tim, You are right. Protecting resources and menu items is well documented in Lift. But providing read/write permissions, and even restricting access to specific data entities based on a subject's role, if that's what you mean by more granularity, is often a required use case in an application. Dividing up read-only views and editable templates into different resources helps. And limiting data access is certainly doable. It would just be nice to centralize some of these features, and that's what I'm trying achieve in my code. Glenn . - oops, I almost lost myself there. On Sep 7, 12:53 pm, glenn gl...@exmbly.com wrote: Marius, In practical terms, if I am already using an If LocParam, as in the following: If(() = User.isa_?(admin), S.?(not_authorized)) what does adding HttpAuthProtected(() = User.authorize(admin)) to the Loc do? Here, I've had to define User.authorize to make things work, as: def authorize(roleName:String): Box[Role] = { val credentials : (String,String) = User.currentUser match { case Full(u) = (u.email.is, u.password.is) case Empty = (null, null) } User.isa_?(roleName) match { case true = { LiftRules.httpAuthProtectedResource.append { case (ParsePath(listContents :: _, _, _, _)) = Full (AuthRole(admin)) } LiftRules.authentication = HttpBasicAuthentication(lift) { case (credentials._1, credentials._2, req) = AuthRole(roleName) true } Full(new _root_.net.liftweb.http.auth.Role{ def name = roleName}) } case false = Empty } Rather verbose, don't you think. elipsisless Glenn On Sep 6, 8:27 am, Timothy Perrett timo...@getintheloop.eu wrote: Right, i know it has a sitemap aspect... just based on what chas has asked about RBAC before, I can only presume he's still looking for more granularity than sitemap offers :-) Perhaps it might work for Glenn though... Cheers, Tim On Sep 6, 3:44 pm, marius d. marius.dan...@gmail.com wrote: Glen, Tim is correct however HTTP auth support + it's Role model can be used for SiteMenu as well. Please see: case class HttpAuthProtected(role: () = Box[Role]) extends LocParam You easily can specify that a Loc is a protected resource you just need to return the Role that guards this resource. This Loc will be served only if HTTP authentication succeeds and the Role match. So this is an RBAC. Br's, Marius On Sep 5, 7:57 pm, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, its simply not designed to do what your asking - however, the most lift way of doing access control is with SiteMap, so potentially look into that as a solution. You don't detail your needs, but we've had this conversation several times on-list so just look through the archives and that might spawn some other ideas for you. Tim PS: Is there any good reason you always put an ellipsis after your name? For some reason it bothers me quite a bit! On Sep 5, 5:32 pm, glenn gl...@exmbly.com wrote: Marius, I appreciate your reply, but the question I asked regards useage of the Role trait in what Charles refers to as a Role-Based Access Control (RBAC) system. I could not find this addressed in the Lift Book and, no, there is no illuminating code in the lift- authentication example. It's established the trait is not a good mixin for a mapper class in maintaining persistent role/access data. I was asking, on a lark, if anyone had ideas on a pattern that might help. I guess I've gotten an answer - No. I certainly don't expect Lift, out-of-the-box, to provide a complete authorization package and I would have been surprised if it had. Glenn... On Sep 5, 12:38 am, marius d. marius.dan...@gmail.com wrote: I'll let Tim provide you a concrete code example but AFAIK there is a lift-authetication example in examples? A few points: 1. We support both BASIC and DIGEST HTTP authentication 2. First, to apply authentication you need to specify which resource (by URI) is a protected resource. Here we say that resource X is protected by Role A (Roles are hierarchicaly structured) 3. Secondly you set up the authentication function in Boot (for Basic or Digest) you check the credentials. If authentication succeeds that request is being processed. Here is an example from lift-authentication: LiftRules.httpAuthProtectedResource.prepend { case (ParsePath(secure-basic :: Nil, _, _, _)) = Full(AuthRole(admin)) } // This resource is protected by an AuthRole named admin. LiftRules.authentication
[Lift] Re: Using Roles and LIftRules.authentication
Marius, Please bear with me. I'm a little slow in following the logic here. I understand I can protect the resource as you suggest from all but users with admin roles, using the LocParam, HttpAuthProtected(() = Full(AuthRole(admin) . Now, when I click on the link, if no user is logged in, the system asks for a username and password to connect, but that's a user on the host. not an application user. Somewhere, I need to assign the currently logged in user the AuthRole(admin) needed to access the resource. Seems to me I need code like this to run someplace: def authorize(roleName:String): Box[Role] = { object userRoles extends RequestVar[Role](null) val credentials : (String,String) = User.currentUser match { case Full(u) = (u.email.is, u.password.is) case Empty = (null, null) } User.isa_?(roleName) match { case true = { LiftRules.authentication = HttpBasicAuthentication(lift) { case (credentials._1, credentials._2, req) = println(John is authenticated!) userRoles(_root_.net.liftweb.http.auth.AuthRole (roleName)) true } Full(new _root_.net.liftweb.http.auth.Role{ def name = roleName}) } case false = Empty } } Can't be in Boot, Glenn On Sep 7, 1:36 pm, marius d. marius.dan...@gmail.com wrote: On Sep 7, 10:53 pm, glenn gl...@exmbly.com wrote: Marius, In practical terms, if I am already using an If LocParam, as in the following: If(() = User.isa_?(admin), S.?(not_authorized)) what does adding HttpAuthProtected(() = User.authorize(admin)) to the Loc do? It sais that this Loc is protected by the returned Role. Thus to access this after passing the authentication the Role specified in the authentication function (by setting userRoles) must be the same as or a child of the Role the is protecting the Loc. Here, I've had to define User.authorize to make things work, as: def authorize(roleName:String): Box[Role] = { val credentials : (String,String) = User.currentUser match { case Full(u) = (u.email.is, u.password.is) case Empty = (null, null) } User.isa_?(roleName) match { case true = { LiftRules.httpAuthProtectedResource.append { case (ParsePath(listContents :: _, _, _, _)) = Full (AuthRole(admin)) } Why do you need to use httpAuthProtectedResource if you' using HttpAuthProtected LocParam ? LiftRules.authentication = HttpBasicAuthentication(lift) { case (credentials._1, credentials._2, req) = AuthRole(roleName) true } Full(new _root_.net.liftweb.http.auth.Role{ def name = roleName}) } case false = Empty } Rather verbose, don't you think. Your code is verbose but I don't see the justification for this verbosity: LiftRules.authentication = HttpBasicAuthentication(lift) { case (username, password, req) = { // Do you authentication in DB or whatever and you determined that this is an admin user userRoles(AuthRole(admin)) // userRoles needs to be set. It is a RquestVar. true } In Boot you have: Menu(Loc(listContents, List(listContents), listContents, HttpAuthProtected(() = Full(AuthRole(admin) When you use HttpAuthProtected LocParam Lift appends a function to LiftRules.httpAuthProtectedResource so you don't need to do it manually. This authorixation scheme is only about protecting resource by roles and you do this almost declaratively and for authentication I thing the things are pretty straight forward. One a user is authenticated (using HTTP authentication) you need to specify the Role for this user and you do this using userRoles RequestVar.Thus /listContents can only be accessed if: 1. user passed authentications 2. user's Role is an admin or a child of the Role specified in HttpAuthProtected elipsisless Glenn On Sep 6, 8:27 am, Timothy Perrett timo...@getintheloop.eu wrote: Right, i know it has a sitemap aspect... just based on what chas has asked about RBAC before, I can only presume he's still looking for more granularity than sitemap offers :-) Perhaps it might work for Glenn though... Cheers, Tim On Sep 6, 3:44 pm, marius d. marius.dan...@gmail.com wrote: Glen, Tim is correct however HTTP auth support + it's Role model can be used for SiteMenu as well. Please see: case class HttpAuthProtected(role: () = Box[Role]) extends LocParam You easily can specify that a Loc is a protected resource you just need to return the Role that guards this resource. This Loc will be served only if HTTP authentication succeeds
[Lift] Re: Using Roles and LIftRules.authentication
Marius, I appreciate your reply, but the question I asked regards useage of the Role trait in what Charles refers to as a Role-Based Access Control (RBAC) system. I could not find this addressed in the Lift Book and, no, there is no illuminating code in the lift- authentication example. It's established the trait is not a good mixin for a mapper class in maintaining persistent role/access data. I was asking, on a lark, if anyone had ideas on a pattern that might help. I guess I've gotten an answer - No. I certainly don't expect Lift, out-of-the-box, to provide a complete authorization package and I would have been surprised if it had. Glenn... On Sep 5, 12:38 am, marius d. marius.dan...@gmail.com wrote: I'll let Tim provide you a concrete code example but AFAIK there is a lift-authetication example in examples? A few points: 1. We support both BASIC and DIGEST HTTP authentication 2. First, to apply authentication you need to specify which resource (by URI) is a protected resource. Here we say that resource X is protected by Role A (Roles are hierarchicaly structured) 3. Secondly you set up the authentication function in Boot (for Basic or Digest) you check the credentials. If authentication succeeds that request is being processed. Here is an example from lift-authentication: LiftRules.httpAuthProtectedResource.prepend { case (ParsePath(secure-basic :: Nil, _, _, _)) = Full(AuthRole(admin)) } // This resource is protected by an AuthRole named admin. LiftRules.authentication = HttpBasicAuthentication(lift) { case (someuser, 1234, req) = { Log.info(You are now authenticated !) userRoles(AuthRole(admin)) true } } When we try to access /secure-basic resource HTTP basic auth. is applied. If credentials are correct we set the AuthRole as admin on the Requestvar userRoles. If we would have set another role such as userRoles (AuthRole (guest)) the resource would still not be served as guest has nothing to do with an admin. The lift-book describes the rules of Roles application. All this has nothing to do with Mapper or Record etc. it is purely about HTTP authentication and a simple authorization mechanism Br's, Marius On Sep 5, 12:53 am, glenn gl...@exmbly.com wrote: I'm looking for direction on the best pattern for implementing basic authentication and authorization in Lift. For example, if I already have a Role mapper to store roles in the database, to what do I attach the Role trait in the net.liftweb.http.auth package? 1) The mapper. You would have to make sure there were no naming conflicts ( i.e., def name in the trait and the mapped string, name, in the mapper. Not the best design pattern to link the two, in my humble opinion.) or 2) A new class, or perhaps an object, with the trait that wraps a Role mapper instance. The other piece to the puzzle is managing the list of AuthRoles, create protected resources and build the Lift.authentication cases. If you limit this to Boot, then you give up on dynamic authentication and authorization, or do you? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Using Roles and LIftRules.authentication
I'm looking for direction on the best pattern for implementing basic authentication and authorization in Lift. For example, if I already have a Role mapper to store roles in the database, to what do I attach the Role trait in the net.liftweb.http.auth package? 1) The mapper. You would have to make sure there were no naming conflicts ( i.e., def name in the trait and the mapped string, name, in the mapper. Not the best design pattern to link the two, in my humble opinion.) or 2) A new class, or perhaps an object, with the trait that wraps a Role mapper instance. The other piece to the puzzle is managing the list of AuthRoles, create protected resources and build the Lift.authentication cases. If you limit this to Boot, then you give up on dynamic authentication and authorization, or do you? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Using Roles and LIftRules.authentication
Tim, I tend to agree with you that the Role trait is not a good mixin for a role mapper, which is why I raise the question. Maybe I'm looking in the wrong place, but the http-authentication example in liftweb.sites on github doesn't have much code. The LiftBook is a more complete example. And neither deals with useage of the Role trait, nor with persisting authorization info. Is there some other example I should be looking at? On the issue of dynamic auth, the examples I've seen all run in Boot which leaves open the question of how to manage the same thing on the fly, so to speak, not that it can't be done. You guys have done too good a job on Lift to have overlooked that. Glenn... On Sep 4, 4:03 pm, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, If Marius doesn't beat ne to it, I'll reply tomorrow morning. The system we implemented for auth was not meant to be composed with matter per-say, not in the way you think however... Presumably you've looked at the http Auth example in the github repo? I'm not sure why on earth you would think it's not possible to do dynamic auth with the existing system? Of course it is! Cheers Tim Sent from my iPhone On 4 Sep 2009, at 22:53, glenn gl...@exmbly.com wrote: I'm looking for direction on the best pattern for implementing basic authentication and authorization in Lift. For example, if I already have a Role mapper to store roles in the database, to what do I attach the Role trait in the net.liftweb.http.auth package? 1) The mapper. You would have to make sure there were no naming conflicts ( i.e., def name in the trait and the mapped string, name, in the mapper. Not the best design pattern to link the two, in my humble opinion.) or 2) A new class, or perhaps an object, with the trait that wraps a Role mapper instance. The other piece to the puzzle is managing the list of AuthRoles, create protected resources and build the Lift.authentication cases. If you limit this to Boot, then you give up on dynamic authentication and authorization, or do you? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Mapper subclasses
I'm not sure of what the exact problem is. I created an Address trait that I couple with a number of mapper classes. trait Address[OwnerType : KeyedMapper[Long, OwnerType]]{ def owner = this.asInstanceOf[OwnerType] Where exactly does this construct break down? Glenn... On Sep 3, 7:55 am, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: jon suggested to me the way to avoid both explicit type parameter and asinstance of: trait Timestamp[MapperType : TimeStamp[MapperType]] extends Mapper [MapperType] { self:MapperType = object xdatetime extends MappedDateTime(this) // all sorts of utility functions for dealing with timestamps } Thanks jon I have improved model in my application with this approach. Giuseppe On 3 Set, 16:16, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: As an alternative to asInstanceOf you could use explicit type parameter in MappedField creation: self:MapperType = object xdatetime extends MappedDateTime[MapperType](this) On 3 Set, 09:19, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: Unfortunately you cannot escape from asInstanceOf . Forcing self:MapperType the type of this will be TimeStamp with MapperType violating the constraint for the type of the first parameter of MappedDateTime :T : Mapper[T]. Regards Giuseppe On 3 Set, 07:08, Naftoli Gugenheim naftoli...@gmail.com wrote: So I guess you can't escape the asInstanceOf. Can you successfully give the trait a self-type of this: MapperType =, or declare it to extend Mapper[MapperType], without running into problems elsewhere? - harryhhar...@gmail.com wrote: I've been handling this with traits, for example I have something like so: trait Timestamp[MapperType : Mapper[MapperType]] { object xdatetime extends MappedDateTime[MapperType](this.asInstanceOf [MapperType]) // all sorts of utility functions for dealing with timestamps } Then I can do class Foo extends LongKeyedMapper[Foo] with IdPK with Timestamp[Foo] { // additional fields that are Foo specific } I have quite a few traits similar to Timestamp at this point corresponding to various fields that appear in lots of different tables in my application. -harryh --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Mapper subclasses
Isn't this really a matter of type casting, and asInstanceOf is just Scala's way of doing this. It's always best if you don't have to downcast your objects, but sometimes its unavoidable. Glenn... On Sep 3, 10:29 am, glenn gl...@exmbly.com wrote: I'm not sure of what the exact problem is. I created an Address trait that I couple with a number of mapper classes. trait Address[OwnerType : KeyedMapper[Long, OwnerType]]{ def owner = this.asInstanceOf[OwnerType] Where exactly does this construct break down? Glenn... On Sep 3, 7:55 am, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: jon suggested to me the way to avoid both explicit type parameter and asinstance of: trait Timestamp[MapperType : TimeStamp[MapperType]] extends Mapper [MapperType] { self:MapperType = object xdatetime extends MappedDateTime(this) // all sorts of utility functions for dealing with timestamps } Thanks jon I have improved model in my application with this approach. Giuseppe On 3 Set, 16:16, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: As an alternative to asInstanceOf you could use explicit type parameter in MappedField creation: self:MapperType = object xdatetime extends MappedDateTime[MapperType](this) On 3 Set, 09:19, Giuseppe Fogliazza g.foglia...@mcmspa.it wrote: Unfortunately you cannot escape from asInstanceOf . Forcing self:MapperType the type of this will be TimeStamp with MapperType violating the constraint for the type of the first parameter of MappedDateTime :T : Mapper[T]. Regards Giuseppe On 3 Set, 07:08, Naftoli Gugenheim naftoli...@gmail.com wrote: So I guess you can't escape the asInstanceOf. Can you successfully give the trait a self-type of this: MapperType =, or declare it to extend Mapper[MapperType], without running into problems elsewhere? - harryhhar...@gmail.com wrote: I've been handling this with traits, for example I have something like so: trait Timestamp[MapperType : Mapper[MapperType]] { object xdatetime extends MappedDateTime[MapperType](this.asInstanceOf [MapperType]) // all sorts of utility functions for dealing with timestamps } Then I can do class Foo extends LongKeyedMapper[Foo] with IdPK with Timestamp[Foo] { // additional fields that are Foo specific } I have quite a few traits similar to Timestamp at this point corresponding to various fields that appear in lots of different tables in my application. -harryh --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Recent change in MappedField._toForm?
It seems that MappedField._toForm method changed recently in 1.1- Snapshot to return Box[scala.xml.Elem] instead of a Box[NodeSeq]. I'm getting a type mismatch error in my code when it was working before. override def _toForm = super._toForm.map(_.flatMap(addElemClass (_,style,height: 65px; width:360px))) where addElemClass is defined as: def addElemClass(in: Node, name:String, value:String): NodeSeq = in match { case e: Elem = e % new UnprefixedAttribute(name, Text(value), Null) case _ = NodeSeq.Empty } error: found : Seq[scala.xml.Node] required: scala.xml.Elem Was there a reason for the change? glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Recent change in MappedField._toForm?
Oops, looks like my error. I didn't see any change in the source. On Sep 1, 9:43 am, glenn gl...@exmbly.com wrote: It seems that MappedField._toForm method changed recently in 1.1- Snapshot to return Box[scala.xml.Elem] instead of a Box[NodeSeq]. I'm getting a type mismatch error in my code when it was working before. override def _toForm = super._toForm.map(_.flatMap(addElemClass (_,style,height: 65px; width:360px))) where addElemClass is defined as: def addElemClass(in: Node, name:String, value:String): NodeSeq = in match { case e: Elem = e % new UnprefixedAttribute(name, Text(value), Null) case _ = NodeSeq.Empty } error: found : Seq[scala.xml.Node] required: scala.xml.Elem Was there a reason for the change? glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Recent change in MappedField._toForm?
David, So, it looks like I no longer need my helper function addElemClass. Cool. Glenn... On Sep 1, 10:30 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Sep 1, 2009 at 9:43 AM, glenn gl...@exmbly.com wrote: It seems that MappedField._toForm method changed recently in 1.1- Snapshot to return Box[scala.xml.Elem] instead of a Box[NodeSeq]. I'm getting a type mismatch error in my code when it was working before. override def _toForm = super._toForm.map(_.flatMap(addElemClass (_,style,height: 65px; width:360px))) where addElemClass is defined as: def addElemClass(in: Node, name:String, value:String): NodeSeq = in match { case e: Elem = e % new UnprefixedAttribute(name, Text(value), Null) case _ = NodeSeq.Empty } error: found : Seq[scala.xml.Node] required: scala.xml.Elem Was there a reason for the change? I made the changes recently when I was working on some additional bind helpers that allow for binding id and other stuff. Seehttp://github.com/dpp/liftweb/commit/7b423faf6aa1a5d5c46f266551e5384d... Why? In your view, you can now do: bindname:textarea style=height: 65px; width: 360px/ In your bind, use: textarea -% obj.textarea.toForm Thanks, David glenn... -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: Recent change in MappedField._toForm?
Now, I'm not sure what is going on? The latest source for BaseMappedField has def _toForm: Box[NodeSeq] But MappedTextarea overrides this as: def _toForm: Box[Elem]. How can that be? On Sep 1, 10:10 am, glenn gl...@exmbly.com wrote: Oops, looks like my error. I didn't see any change in the source. On Sep 1, 9:43 am, glenn gl...@exmbly.com wrote: It seems that MappedField._toForm method changed recently in 1.1- Snapshot to return Box[scala.xml.Elem] instead of a Box[NodeSeq]. I'm getting a type mismatch error in my code when it was working before. override def _toForm = super._toForm.map(_.flatMap(addElemClass (_,style,height: 65px; width:360px))) where addElemClass is defined as: def addElemClass(in: Node, name:String, value:String): NodeSeq = in match { case e: Elem = e % new UnprefixedAttribute(name, Text(value), Null) case _ = NodeSeq.Empty } error: found : Seq[scala.xml.Node] required: scala.xml.Elem Was there a reason for the change? glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Recent change in MappedField._toForm?
David, Actually, I kind of like the ability to fix MappedField styles in the object itself for some situations, rather than add them in for each view, so I changed my util function to: def addElemClass(in: Node, name:String, value:String): Box[Elem] = in match { case e: Elem = Full(e % new UnprefixedAttribute(name, Text (value), Null)) case _ = Empty } I'm sure it's not the prettiest way to do this. But it does work. Glenn... On Sep 1, 10:30 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Sep 1, 2009 at 9:43 AM, glenn gl...@exmbly.com wrote: It seems that MappedField._toForm method changed recently in 1.1- Snapshot to return Box[scala.xml.Elem] instead of a Box[NodeSeq]. I'm getting a type mismatch error in my code when it was working before. override def _toForm = super._toForm.map(_.flatMap(addElemClass (_,style,height: 65px; width:360px))) where addElemClass is defined as: def addElemClass(in: Node, name:String, value:String): NodeSeq = in match { case e: Elem = e % new UnprefixedAttribute(name, Text(value), Null) case _ = NodeSeq.Empty } error: found : Seq[scala.xml.Node] required: scala.xml.Elem Was there a reason for the change? I made the changes recently when I was working on some additional bind helpers that allow for binding id and other stuff. Seehttp://github.com/dpp/liftweb/commit/7b423faf6aa1a5d5c46f266551e5384d... Why? In your view, you can now do: bindname:textarea style=height: 65px; width: 360px/ In your bind, use: textarea -% obj.textarea.toForm Thanks, David glenn... -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
David, For all that you've said in defense of Lift's extensibility, answer one question: Could you override def _showAllTemplate in Crudify, without having the source at your disposal? And, this is not an isolated example. Glenn... On Aug 28, 12:05 pm, AlBlue alex.blew...@gmail.com wrote: On Jul 29, 12:55 pm, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Yup, maintaining a collection is the easiest way to use dynamic updates in the future. That said, I've been discussing modularity of scala code generally recently: http://alblue.blogspot.com/2009/08/modularity-for-scala.html If anyone's interested helping out then please drop me a note on my blog. Hopefully we'll be able to extend the work that Heiko has already done and use that to modularise the core library. If successful, this could be used as an approach for both the lift code and apps that depend on lift. Alex --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
David, I'll take a look at the ESME code to see if what you've done scratches my itch on this issue. I've run the war file and it looks interesting. I assume the source is also available. Thanks for the heads-up. Glenn... On Aug 27, 7:55 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 2:00 PM, glenn gl...@exmbly.com wrote: David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. Are you talking about modularization of web apps? Are you talking about being able to plop in a JAR file and do one or two bits of configuration and have that JAR's features be part of your app? If you are, with the exception of the where do my menu items go issue, as long as you can do the configuration in Boot, Lift allows for fully modular apps. Rather than complaining the Lift doesn't offer what you need, please define what you need in very specific terms (I need to intercept a GET request to a URL, I need to intercept requests to a URL if certain conditions are met, I need to include a tag in view code that invokes code in my module, etc.) or point to another framework that allows for this plugin modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea. But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Why are traits any different than objects that you subclass? As far as I can tell, traits simply give you nearly multiple inheritance without the headaches. Why would you be any less willing to mix in a trait than to subclass a class provided by another library? Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. I think that snippets are a near perfect encapsulation mechanism. They are simply a transformation of XHTML - XHTML. What could be more straight forward? What could be more encapsulated? Further, Lift's mechanism of associating HTML elements with functions means that there's no need to have special URLs to handle forms or anything else. My snippet can generate a form that will be processed if it is submitted back to the server, no matter what URL the form is submitted to. In Rails and other MVC frameworks, the POST/GET must be done to a specific controller in order for the parameters to be correctly processed. Why does this matter? Well, in the ESME codebase, I just created an authentication plugin mechanism that allows a plugin to define a part of a form that is to be filled in as part of the signup process. The signup process doesn't know anything about the plugin or what fields the plugin needs. The snippet that handles the signup simply binds one element to the plugins part of the sign-up. The plugin manages its own portion of the form, manages its own validation, manages its own saving, all without having to register as being part of the controller. This is highly modular. And then, to make them private, which is done...that's turning a headache into a nightmare. Can you give me an example of a private snippet or a private template and how you would use one? Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. If I understood what you were trying to do, I could help you with patterns. Code works best for me. If you could put together templates and stubbed Scala and make clear what you're trying to do and what Lift is not letting you do, I could help you out. Thanks, David Glenn... On Aug 27, 12:11 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before
[Lift] Re: Modularization of Lift code
David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order, or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } With it, you can sort of standardize your call-order, requiring that the init function be called immediately before S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in Scala code (perhaps due to its power and complexity), unlike pure OOP. When I've written before on this subject in this group, I've gotten a lot of examples in the small purporting to dispute my contention, but falling short. If you know I'm wrong, fine ... let's see it. If you just think I am, well...think harder. This is not small potatoes There are plenty of languages on the dust heap precisely because of the extension problem. Glenn... On Aug 26, 2:53 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Aug 26, 2009 at 10:13 AM, glenn gl...@exmbly.com wrote: Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? I typically return my menu items from my init function. You can call schemifier from within your init function. As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea. But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. And then, to make them private, which is done...that's turning a headache into a nightmare. Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. Glenn... On Aug 27, 12:11 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before Just to be precise, init() is a method on your module. It's not a function. S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in Scala code (perhaps due to its power and complexity), unlike pure OOP. Ummm... as far as I know, Scala is a pure OO language. Everything in Scala is either the instance of a class (and object, but object is overloaded with Scala's use of it as a keyword for singleton) or a method. There is nothing else in Scala. In this way, Scala is like Smalltalk and Ruby. It's not like Java where things exist in Java that are neither an instance nor a method (static methods, primitive types, etc.) There is nothing that we can't do in Scala to encapsulate anything... the issue that I see is what do you want to encapsulate? When I've written before on this subject in this group, I've gotten a lot of examples in the small purporting to dispute my contention, but falling short. If you know I'm wrong, fine ... let's see it. If you just think I am, well...think harder. Let's separate Lift from Scala the language for a moment. I'm no expert in PLT so I'm not going to argue encapsulation in Scala. I can argue about Lift's modularization and what its limitations are. The following things in Lift I know to be non-modular: - Mapper: because one cannot subclass Mapper definitions, it's not really modular. Yes, I've built (and subclassed) ProtoUser, but it's a huge hack and anything serious (e.g., subclassing an existing mapper and *changing* the behavior of one on the fields) is not doable with Mapper. This is basically because I've never meant Mapper to be a serious OR mapping tool, but more of an ActiveRecord clone where you can create a mapping between an RDBMS and some sort of record. I use Mapper very successfully, but it's not meant for the same things OO is meant for (subclassing) or what Mixins are meant for. - SiteMap: SiteMap is frozen at boot time. This means that OSGi modules can't load and unload themselves and mutate the sitemap. Because the sitemap is fixed at boot time, it's also not possible for a module to insert menu items at an appropriate place in the menu hierarchy. - LiftRules: like SiteMap, the LiftRules are fixed at boot time. It's not possible for modules to load/unload dynamically and change the various PFs dynamically. I have a plan for fixing the LiftRules stuff so we can fully support OSGi modules. I will likely extend that to supporting more dynamic sitemaps. More broadly, every time I've had Scala code that's concrete and needed to be made more runtime dynamic, the process has been simple, quick, and painless. Breaking classes into traits and composing those traits into different runtime configurations has by and large been a few minute to few hour project. Yeah
[Lift] Re: Modularization of Lift code
Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: New features
I have a working example of ManyToMany that adds roles to users. I would be happy to share my work but I have an aversion to github. I don't like it, It's a slower-than- molasses interface. It's buggy and user-hostile in my opinion. I'm looking for an alternative to make it public. Any suggestions would be appreciated. Glenn... On Aug 25, 7:08 am, Naftoli Gugenheim naftoli...@gmail.com wrote: This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much
[Lift] Re: New features
Well, I managed to upload to github. Here is the repository: git://github.com/glennSilverman/UserMon.git Any feedback is appreciated. Glenn... On Aug 25, 10:43 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Google code? Sourceforge? ProjectLocker? There are a lot of choices... On Tue, Aug 25, 2009 at 12:37 PM, glenngl...@exmbly.com wrote: I have a working example of ManyToMany that adds roles to users. I would be happy to share my work but I have an aversion to github. I don't like it, It's a slower-than- molasses interface. It's buggy and user-hostile in my opinion. I'm looking for an alternative to make it public. Any suggestions would be appreciated. Glenn... On Aug 25, 7:08 am, Naftoli Gugenheim naftoli...@gmail.com wrote: This meaning the problem, or meaning ManyToMany? It's pretty simple to use. You're mapper should extend ManyToMany, and you should have a field: object m2m extends MappedManyToMany(.../*the two MetaMappers and foreign keys, see the docs/source*/) Then you can treat m2m as a Buffer, adding and deleting children. Call save on the mapper or m2m to propogate the adding/deleting to the database, and refresh to reset its contents to reflect the database. However, as noted currently the children must be saved before they are added. This is not the case for OneToMany, and for ManyToMany it should not be a problem because usually the children exist independently of the parent--that's why they can have 0 or 1 or more parents. - Randinnrand...@gmail.com wrote: Anyone have code showing this in action as it were? On Aug 6, 8:39 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Oh, I think I know what the problem is. I think I should classify it as a bug. Since you're adding a Role that isn't saved yet, and ManyToMany tracks the children via the join table, it can't access the child. As a workaround save the Role before adding it, although the need to do so is against the idea of ManyToMany and OneToMany. I will see what I can do, G-d willing. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote
[Lift] multiselect example in Liftbook problem
There seems to be a problem with SHtml.multiSelect following the example in the Lift book (Listing 4.10: Using multiselect). The example shows the last parameter to be a List, while the source for multiSelect shows it to be (String) = Any. When I tried to implement in my own code, I get the compiler error: type mismatch found; List[String], required: String. The book example even states that the function takes a String representing a Category’s primary key and returns the category. The example goes further to explain: We then use this helper method to update the Set that we created earlier. Note that the callback function will be executed for each selected item in the multiselect, which is why the callback takes a String argument instead of a Set[String]. But where is this callback function? Is it the same helper mentioned earlier. There's no other callback function parameter on the multiSelect constructor. This is all very confusing. Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: multiselect example in Liftbook problem
I found that the example is out-of-sync with the latest code in 1.1- Snapshot. I was able to get the example (in my application, at least) to compile and run, by defining the function as loadCategory(List[String]) = ..., and creating a separate submit function to handle the actual save chores. Glenn... On Aug 24, 3:37 pm, glenn gl...@exmbly.com wrote: There seems to be a problem with SHtml.multiSelect following the example in the Lift book (Listing 4.10: Using multiselect). The example shows the last parameter to be a List, while the source for multiSelect shows it to be (String) = Any. When I tried to implement in my own code, I get the compiler error: type mismatch found; List[String], required: String. The book example even states that the function takes a String representing a Category’s primary key and returns the category. The example goes further to explain: We then use this helper method to update the Set that we created earlier. Note that the callback function will be executed for each selected item in the multiselect, which is why the callback takes a String argument instead of a Set[String]. But where is this callback function? Is it the same helper mentioned earlier. There's no other callback function parameter on the multiSelect constructor. This is all very confusing. Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: TableEditor article
Naftoli, I must be doing something wrong. I tried the following, as you suggested, inserting the extra xml after the item:fields tag, but ManagerUsers.list does its own iteration through the table items and I get duplicate columns. ManageUsers.list just does a bind to the myuser:roles tag. table:items tr item:fields fields=firstname lastname email td style=vertical-align: topfield:form //td /item:fields lift:ManageUsers.list td style=vertical-align: topmyuser:roles //td /lift:ManageUsers.list td style=vertical-align: topitem:removeBtn //td /tr /table:items Then, I have the added problem of saving changes to the item, since roles is not a field recognized by ItemsList.save. Any suggestions?? Kevin, I implemented asmselect in my app and it works great. Thanks for the heads up. Glenn... On Aug 20, 3:44 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: It's not too hard to make your own without ajax. def addRemove(c: Child) = (_:Boolean) match { case true = if(!field.contains(c)) field+=c case false = field -= c} Then iterate (flatMap) over Child.findAll creating a checkbox initialized to field.contains(x) with addRemove(x) as its setter. - Kevin Wrightkev.lee.wri...@googlemail.com wrote: Absolutely spot-on article here about multiple selection on webpages:http://www.ryancramer.com/journal/entries/select_multiple/ I'm a big fan of asmselect, and the real beauty is that we already have jquery support in lift out-of-the-box :) http://www.ryancramer.com/journal/entries/select_multiple/ On Thu, Aug 20, 2009 at 11:27 PM, glenn gl...@exmbly.com wrote: Naftoli, I like the checkboxes style for a small selection (say 10 or less), and perhaps a multi-selectbox if the choices are more numerous. Another approach is to use two list boxes, one for the choices and another for the selections, with maybe a drag-and-drop capability or some add/remove buttons in between. I guess there is no good default solution. One enhancement to your tableeditor would be a tableviewer option, using a field:toXml instead of a field:form tag. Thanks for your help. Glenn... On Aug 20, 2:20 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The name is really a misnomer. It's not a MappedField. So it's missing the opposite half: it _is_ the validSelectValues but it doesn't have the toForm method of MappedField's to make use of its values. I'm not sure how a hypothetical toForm would work for a many-to-many field. Actually it depends on the circumstances. One option is how MS Access works---every time you select a value you get a new blank row. This is good where you can have many or duplicate children, but is more complex to implement. Similarly you can have a list of current children and a dropdown to add. Another option (where duplicates are not allowed) is a set of checkboxes. - glenngl...@exmbly.com wrote: Naftoli, Sorry for the addendum, but ideally, it would be nice to do something like: override def validSelectValues: Box[List[(Long, String)]] ... as you can with MappedLongForeignKey, and have a select box display in the table. Glenn... On Aug 20, 12:51 pm, glenn gl...@exmbly.com wrote: Naftoli, I tried using TableEditor with a MetaMapper instance of a ManyToMany class, but header:fields and item:fields tags in the template didn't pick up the MappedManyToMany object in the class. Is there some method that I need to override,or is there some way to write the template that will resolve this? Glenn... On Aug 12, 2:48 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I just wrote a brief wiki article on GitHub about using TableEditor, but not being familiar with the formatting syntax, the code snippets are truncated. Can anyone take a look at it and fix it? Thanks. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: TableEditor article
Kevin, The way I implemented asmselect for a MappedManyToMany object was to write a method in my Mapper class to extract the information from the database. object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) def validSelectValues: Box[List[(Long, String)]] = Full( Role.findAll.map( x = (x.id.is, x.name.is) )) In my snippet, I created the select list like so: var options = new Queue[Node]() e.validSelectValues match { case Full(x) = for(r - x){ if(e.roles.contains(r._1)) options+= option selected=selected{r._2}/ option options+= option{r._2}/option } case _ = } def selectRoles = select multiple=multiple name=roles[] title=Click to Select a Role {options} /select where e represents my Mapper instance. Then I just bound selectRoles to the tag in my template. It was really pretty simple. Glenn... On Aug 21, 11:06 am, glenn gl...@exmbly.com wrote: Naftoli, I must be doing something wrong. I tried the following, as you suggested, inserting the extra xml after the item:fields tag, but ManagerUsers.list does its own iteration through the table items and I get duplicate columns. ManageUsers.list just does a bind to the myuser:roles tag. table:items tr item:fields fields=firstname lastname email td style=vertical-align: topfield:form //td /item:fields lift:ManageUsers.list td style=vertical-align: topmyuser:roles //td /lift:ManageUsers.list td style=vertical-align: topitem:removeBtn //td /tr /table:items Then, I have the added problem of saving changes to the item, since roles is not a field recognized by ItemsList.save. Any suggestions?? Kevin, I implemented asmselect in my app and it works great. Thanks for the heads up. Glenn... On Aug 20, 3:44 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: It's not too hard to make your own without ajax. def addRemove(c: Child) = (_:Boolean) match { case true = if(!field.contains(c)) field+=c case false = field -= c} Then iterate (flatMap) over Child.findAll creating a checkbox initialized to field.contains(x) with addRemove(x) as its setter. - Kevin Wrightkev.lee.wri...@googlemail.com wrote: Absolutely spot-on article here about multiple selection on webpages:http://www.ryancramer.com/journal/entries/select_multiple/ I'm a big fan of asmselect, and the real beauty is that we already have jquery support in lift out-of-the-box :) http://www.ryancramer.com/journal/entries/select_multiple/ On Thu, Aug 20, 2009 at 11:27 PM, glenn gl...@exmbly.com wrote: Naftoli, I like the checkboxes style for a small selection (say 10 or less), and perhaps a multi-selectbox if the choices are more numerous. Another approach is to use two list boxes, one for the choices and another for the selections, with maybe a drag-and-drop capability or some add/remove buttons in between. I guess there is no good default solution. One enhancement to your tableeditor would be a tableviewer option, using a field:toXml instead of a field:form tag. Thanks for your help. Glenn... On Aug 20, 2:20 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The name is really a misnomer. It's not a MappedField. So it's missing the opposite half: it _is_ the validSelectValues but it doesn't have the toForm method of MappedField's to make use of its values. I'm not sure how a hypothetical toForm would work for a many-to-many field. Actually it depends on the circumstances. One option is how MS Access works---every time you select a value you get a new blank row. This is good where you can have many or duplicate children, but is more complex to implement. Similarly you can have a list of current children and a dropdown to add. Another option (where duplicates are not allowed) is a set of checkboxes. - glenngl...@exmbly.com wrote: Naftoli, Sorry for the addendum, but ideally, it would be nice to do something like: override def validSelectValues: Box[List[(Long, String)]] ... as you can with MappedLongForeignKey, and have a select box display in the table. Glenn... On Aug 20, 12:51 pm, glenn gl...@exmbly.com wrote: Naftoli, I tried using TableEditor with a MetaMapper instance of a ManyToMany class, but header:fields and item:fields tags in the template didn't pick up the MappedManyToMany object in the class. Is there some method that I need to override,or is there some way to write the template that will resolve this? Glenn... On Aug 12, 2:48 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I
[Lift] Re: TableEditor article
Naftoli, I think a configurable TableEditor is a good thing to have. I don't believe it would take much to enhance what you have started. For one thing, if TableEditorImpl were not a protected class, then one could simply override what is needed. Perhaps it should be made a trait that users could simply implement for any customization. Maybe ItemList could be broken up into FieldList, for just fields, and ItemList, for those non-field items, such as MappedManyToMany. As it is, I will need to rewrite portions of the code to handle these things. If I can do it so that it is reuseable outside my own particular situation, I will let you know. Glenn... On Aug 21, 1:05 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I should have thought of that problem. I could make TableEditor more flexible when I have time, but the truth is that I don't know if it's worth it. The whole thing is less than 80 LOC with scaladocs (not counting the utilities it uses which you can also use). The real logic that provides its semantics is ItemsList, which includes sortability, and is public. So it's probably not worth it to not write your own snippet! The value of TableEditor is that it's automatic--3 lines in the view and two in Boot, (actually that could surely be lessened when I have a chance) and it works on any table. Once your customizing it it might not be worth it. It basically does old fashioned binds, backed by an ItemsList (better name anyone?). Also it uses eachField from mapper.view.Util, but in your case you know which fields you have. What do you think? - glenngl...@exmbly.com wrote: Naftoli, I must be doing something wrong. I tried the following, as you suggested, inserting the extra xml after the item:fields tag, but ManagerUsers.list does its own iteration through the table items and I get duplicate columns. ManageUsers.list just does a bind to the myuser:roles tag. table:items tr item:fields fields=firstname lastname email td style=vertical-align: topfield:form //td /item:fields lift:ManageUsers.list td style=vertical-align: topmyuser:roles //td /lift:ManageUsers.list td style=vertical-align: topitem:removeBtn //td /tr /table:items Then, I have the added problem of saving changes to the item, since roles is not a field recognized by ItemsList.save. Any suggestions?? Kevin, I implemented asmselect in my app and it works great. Thanks for the heads up. Glenn... On Aug 20, 3:44 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: It's not too hard to make your own without ajax. def addRemove(c: Child) = (_:Boolean) match { case true = if(!field.contains(c)) field+=c case false = field -= c} Then iterate (flatMap) over Child.findAll creating a checkbox initialized to field.contains(x) with addRemove(x) as its setter. - Kevin Wrightkev.lee.wri...@googlemail.com wrote: Absolutely spot-on article here about multiple selection on webpages:http://www.ryancramer.com/journal/entries/select_multiple/ I'm a big fan of asmselect, and the real beauty is that we already have jquery support in lift out-of-the-box :) http://www.ryancramer.com/journal/entries/select_multiple/ On Thu, Aug 20, 2009 at 11:27 PM, glenn gl...@exmbly.com wrote: Naftoli, I like the checkboxes style for a small selection (say 10 or less), and perhaps a multi-selectbox if the choices are more numerous. Another approach is to use two list boxes, one for the choices and another for the selections, with maybe a drag-and-drop capability or some add/remove buttons in between. I guess there is no good default solution. One enhancement to your tableeditor would be a tableviewer option, using a field:toXml instead of a field:form tag. Thanks for your help. Glenn... On Aug 20, 2:20 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The name is really a misnomer. It's not a MappedField. So it's missing the opposite half: it _is_ the validSelectValues but it doesn't have the toForm method of MappedField's to make use of its values. I'm not sure how a hypothetical toForm would work for a many-to-many field. Actually it depends on the circumstances. One option is how MS Access works---every time you select a value you get a new blank row. This is good where you can have many or duplicate children, but is more complex to implement. Similarly you can have a list of current children and a dropdown to add. Another option (where duplicates are not allowed) is a set of checkboxes. - glenngl...@exmbly.com wrote: Naftoli, Sorry for the addendum, but ideally, it would be nice to do something like: override def validSelectValues: Box[List[(Long, String)]] ... as you can with MappedLongForeignKey, and have
[Lift] Re: TableEditor article
Naftoli, I tried using TableEditor with a MetaMapper instance of a ManyToMany class, but header:fields and item:fields tags in the template didn't pick up the MappedManyToMany object in the class. Is there some method that I need to override,or is there some way to write the template that will resolve this? Glenn... On Aug 12, 2:48 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I just wrote a brief wiki article on GitHub about using TableEditor, but not being familiar with the formatting syntax, the code snippets are truncated. Can anyone take a look at it and fix it? Thanks. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: TableEditor article
Naftoli, Sorry for the addendum, but ideally, it would be nice to do something like: override def validSelectValues: Box[List[(Long, String)]] ... as you can with MappedLongForeignKey, and have a select box display in the table. Glenn... On Aug 20, 12:51 pm, glenn gl...@exmbly.com wrote: Naftoli, I tried using TableEditor with a MetaMapper instance of a ManyToMany class, but header:fields and item:fields tags in the template didn't pick up the MappedManyToMany object in the class. Is there some method that I need to override,or is there some way to write the template that will resolve this? Glenn... On Aug 12, 2:48 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I just wrote a brief wiki article on GitHub about using TableEditor, but not being familiar with the formatting syntax, the code snippets are truncated. Can anyone take a look at it and fix it? Thanks. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: TableEditor article
Naftoli, I like the checkboxes style for a small selection (say 10 or less), and perhaps a multi-selectbox if the choices are more numerous. Another approach is to use two list boxes, one for the choices and another for the selections, with maybe a drag-and-drop capability or some add/remove buttons in between. I guess there is no good default solution. One enhancement to your tableeditor would be a tableviewer option, using a field:toXml instead of a field:form tag. Thanks for your help. Glenn... On Aug 20, 2:20 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The name is really a misnomer. It's not a MappedField. So it's missing the opposite half: it _is_ the validSelectValues but it doesn't have the toForm method of MappedField's to make use of its values. I'm not sure how a hypothetical toForm would work for a many-to-many field. Actually it depends on the circumstances. One option is how MS Access works---every time you select a value you get a new blank row. This is good where you can have many or duplicate children, but is more complex to implement. Similarly you can have a list of current children and a dropdown to add. Another option (where duplicates are not allowed) is a set of checkboxes. - glenngl...@exmbly.com wrote: Naftoli, Sorry for the addendum, but ideally, it would be nice to do something like: override def validSelectValues: Box[List[(Long, String)]] ... as you can with MappedLongForeignKey, and have a select box display in the table. Glenn... On Aug 20, 12:51 pm, glenn gl...@exmbly.com wrote: Naftoli, I tried using TableEditor with a MetaMapper instance of a ManyToMany class, but header:fields and item:fields tags in the template didn't pick up the MappedManyToMany object in the class. Is there some method that I need to override,or is there some way to write the template that will resolve this? Glenn... On Aug 12, 2:48 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I just wrote a brief wiki article on GitHub about using TableEditor, but not being familiar with the formatting syntax, the code snippets are truncated. Can anyone take a look at it and fix it? Thanks. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: CMS for Lift?
I think the trick to a really vibrant CMS is the ability to create plugins - modules in Lift that can be dynamically installed. I'm not sure how to affect this except through OSGi. On Aug 19, 8:55 am, TylerWeir tyler.w...@gmail.com wrote: Wonderful! On Aug 19, 11:03 am, David Pollak feeder.of.the.be...@gmail.com wrote: FWIW... I got roped into hosting a CMS by the PTA of my kids' school. I may knock something together in Lift or leverage off the work Glenn has done. On Tue, Aug 18, 2009 at 3:26 PM, Timothy Perrett timo...@getintheloop.euwrote: Just my two cents, but I wouldn't use the lift namespace... If you use the lift tags OOTB, you risk designers shoving lots of comet actors on a single page. You would get more granular control if you created a special set of tags: cms:something .. / Cheers, Tim On 18/08/2009 23:00, Ewan ehar...@gmail.com wrote: I've been scratching my head about that one too. I have used both Alfresco and opencms to produce both dynamic and static and in the case of dynamic they have their own servlet/filter to render the content - I've not yet spent enough time working out how and if they can be fitted together. For me, having used Hybris (J2EE ecommerce engine with some CMS built in), I'd like to be able to have page fragments in a template served from the CMS (lift snippets presumably) that would be created/ maintained with some aspect of workflow by CMS user(s) in an associated CMS lift webapp with funky (X)HTML editor support. My web guys, non-lift devs, can then sprinkle cms tags where appropriate. A tag might be lift:cms contentId=news count=5 order=ascending/ which would render the last five news items in ascending order. Just some thoughts -- Ewan On Aug 18, 10:09 pm, Terry J. Leach terry.le...@gmail.com wrote: I would like to know how the Lift/Scala can leveraged to with Alfresco or any other open source Java based CMS. Terry J. Leach On Aug 17, 2:09 pm, Stefan Scott stefanscottal...@gmail.com wrote: I'll chime in here since I've been evaluating several CMSs lately. I previously used Drupal and WordPress as my CMSs - now however I'm moving everything to MODx because of the increased flexibility and more-logical organization, and I'm also impressed with the demos of SilverStripe, TypoLight Typo3 - and LifeRay, which is written in Java instead of PHP. (LifeRay seems to be much more than a CMS - it claims to offer collaboration and social networking.) Some on-line demos here: MODx -http://trymodx.com/ SilverStripe -http://demo.silverstripe.com/ TypoLight -http://www.typolight.org/demo.html Typo3 -http://testsite.punkt.de/ LifeRay -http://demo.liferay.net/web/guest/home It would be good to take a look at these additional CMSs as they offer some capabilities beyond WordPress and Drupal. Drupal in particular is wildly popular but it may no longer be the best candidate to imitate, as it is less well-organized and less flexible/customizable (compared say to MODx, which lets you take CSS from an existing site and use it for your site, and which lets you apply a template to a single document, unlike Drupal where a theme applies to the entire site). To keep up with advanced CMSs, Drupal has evolved to use a bunch of (often redundant or competing) modules which are not always compatible with current releases. Examples of things that Drupal treats as add-ons (modules) are: custom content (the CCK/Views modules, with their confusing albeit AJAX-y interface), multi-language, and photo galleries (I gave up on Drupal after a few days of trying out various photo gallery modules, none of which I could understand). Finally, it seems odd that Drupal, as a content management system, lacks something all advanced CMSs have: a *treeview* of the overall site content. Instead, it only has a jumbled *list* of content, sorted by not by location but by last edited (!), with all translations also scattered through the list based on last- edited date, and this list is buried several levels deep in the admin navigation system, unlike the site content treeview navigator which is prominently displayed (usually on the left) in advanced CMSs. (Of course, I don't want to veer off-topic here and start a CMS flame war here in this liftweb discussion. :-) Regarding dynamic site map creation - I do know that MODx has something like this, using WayFinder to create a menu from selected branches of the site's document tree, automatically including any updated sub-branches, and I believe most other advanced CMSs have something like this too. LifeRay seems very intriguing - it claims to do a lot beyond just CMS. Since it's written in Java (not PHP), who knows if some of its code could
[Lift] Re: Sitemap and mapper dependency's effects on object reuse
David, Sounds like you know where I'm coming from on this. What got me was an attempt to write a Menu Loc for listing all registered users on the site. The Template for this contains a lift tag for a snippet in another class. I don't necessarily object to the dependency on a snippet class, but this does lead to reuse problems for my User MetaMapper. /** * The menu item for listing all users */ def listUsersMenuLoc: Box[Menu] = { Full(Menu(Loc(listUsers, listUsers :: Nil, S.??(List Users), listUsers, testLogginIn))) } def listUsers = Template({ () = lift:surround with=default at=content h3Site Users/h3 div id=entryform table tr thFirst Name/th thLast Name/th thEmail/th thRoles/th th/th th/th /tr lift:ManageUsers.list user:entry tr tduser:firstname //td tduser:lastname //td tduser:email //td tduser:roles//td tduser:actions//td /tr /user:entry /lift:ManageUsers.list /table /div hr / div id=user-edit/ /lift:surround }) On Aug 19, 3:08 pm, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, Lemme see if I can put together some abstractions that might help out. Thanks, David On Tue, Aug 18, 2009 at 4:58 PM, glenn gl...@exmbly.com wrote: I'm looking for some answers on best coding practices, particularly when it comes to object reuse. In a data-centric application, where the Sitemap is used to navigate through your mapper entities, has anyone given much thought to the object dependencies this can create. In the case of page specific rendering with SiteMap, for example, where should the Menu entries go - in their own object, or should they stay with the MetaMappers. And what about the templates, which can have dependencies on snippets, which reside elsewhere. In other words, it seems to me that good design requires managing the chain of dependencies that an ordinary Menu entry may require. A consistent approach is always best, and I admit that I don't have one at present. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: Sitemap and mapper dependency's effects on object reuse
Complicating matters a bit, I decided to use the new ModelSnippet, which extends StatefulSniippet for my snippet class, so I'm not sure the Template can be refactored to not use it. Glenn... On Aug 19, 4:42 pm, glenn gl...@exmbly.com wrote: David, Sounds like you know where I'm coming from on this. What got me was an attempt to write a Menu Loc for listing all registered users on the site. The Template for this contains a lift tag for a snippet in another class. I don't necessarily object to the dependency on a snippet class, but this does lead to reuse problems for my User MetaMapper. /** * The menu item for listing all users */ def listUsersMenuLoc: Box[Menu] = { Full(Menu(Loc(listUsers, listUsers :: Nil, S.??(List Users), listUsers, testLogginIn))) } def listUsers = Template({ () = lift:surround with=default at=content h3Site Users/h3 div id=entryform table tr thFirst Name/th thLast Name/th thEmail/th thRoles/th th/th th/th /tr lift:ManageUsers.list user:entry tr tduser:firstname //td tduser:lastname //td tduser:email //td tduser:roles//td tduser:actions//td /tr /user:entry /lift:ManageUsers.list /table /div hr / div id=user-edit/ /lift:surround }) On Aug 19, 3:08 pm, David Pollak feeder.of.the.be...@gmail.com wrote: Glenn, Lemme see if I can put together some abstractions that might help out. Thanks, David On Tue, Aug 18, 2009 at 4:58 PM, glenn gl...@exmbly.com wrote: I'm looking for some answers on best coding practices, particularly when it comes to object reuse. In a data-centric application, where the Sitemap is used to navigate through your mapper entities, has anyone given much thought to the object dependencies this can create. In the case of page specific rendering with SiteMap, for example, where should the Menu entries go - in their own object, or should they stay with the MetaMappers. And what about the templates, which can have dependencies on snippets, which reside elsewhere. In other words, it seems to me that good design requires managing the chain of dependencies that an ordinary Menu entry may require. A consistent approach is always best, and I admit that I don't have one at present. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: CMS for Lift?
I just put my fledgling stab at a Lift CMS on gitHub. I'm not a gitHub user, so it took me a while to set up and commit the files. Anyway, here's the URL: git://github.com/glennSilverman/democritus.git I'm sure others out there have more sophisticated content managers for Lift but I'm happy to throw mine out there for comment anyway. Glenn... On Aug 17, 4:43 am, Jefken De Vleesetenden Boterham cultoftheholysquir...@gmail.com wrote: thirded, I'd try to help out a bit On Sun, Aug 16, 2009 at 11:53 PM, TylerWeirtyler.w...@gmail.com wrote: @Glenn - is your project public? Seconded, toss it up on github and let the community start helping out. --http://pmonnaie.blogspot.com/ --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: makeUtf8 and HttpServletRequest broken in new build???
David, I just ran the basic from SNAPSHOTS and Boot.scala still has private def makeUtf8(req: HttpServletRequest) { req.setCharacterEncoding(UTF-8) } in Boot.scala. Glenn... On Aug 17, 10:10 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Mon, Aug 17, 2009 at 9:42 AM, glenn gl...@exmbly.com wrote: Is anyone planning on fixing the archetype snapshots to add this change, and import provider._ in Boot.scala. I'm able to create a new Basic Lift app from archetypes... and it works just fine. Can you tell us what command you typed to get an archetype that did not work? Thanks in advance, Glenn... On Aug 10, 10:36 am, marius d. marius.dan...@gmail.com wrote: Your makeUTF8 should look like this: private def makeUtf8(req: HTTPRequest): Unit = {req.setCharacterEncoding(UTF-8)} just use HTTPRequest instead of HttpServletRequest. Br's, Marius On Aug 10, 7:49 pm, glenn gl...@exmbly.com wrote: I just got a type mismatch found error in LiftRules.early.append (makeUtf8) in Boot.scala. It's now looking for an net.liftweb.http.provider.HTTPRequest instead of a javax.servlet.http.HttpServletRequest. Is this a new change, and if so, where is the net.liftweb.http.provider package? Glenn... -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: makeUtf8 and HttpServletRequest broken in new build???
Actually, I used the Maven Eclipse plugin. File/New/Other/Maven/Maven Project. Click Next twice and select the Nexus Indexer Archetype catalog. Use lift to filter and select Group Id: repository.net.liftweb Artifact Id: lift.archetype.basic Version: 1.1-SNAPSHOT Glenn... On Aug 18, 10:32 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Tue, Aug 18, 2009 at 9:15 AM, glenn gl...@exmbly.com wrote: David, I just ran the basic from SNAPSHOTS and Boot.scala still has What did you type at the command line? private def makeUtf8(req: HttpServletRequest) { req.setCharacterEncoding(UTF-8) } in Boot.scala. Glenn... On Aug 17, 10:10 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Mon, Aug 17, 2009 at 9:42 AM, glenn gl...@exmbly.com wrote: Is anyone planning on fixing the archetype snapshots to add this change, and import provider._ in Boot.scala. I'm able to create a new Basic Lift app from archetypes... and it works just fine. Can you tell us what command you typed to get an archetype that did not work? Thanks in advance, Glenn... On Aug 10, 10:36 am, marius d. marius.dan...@gmail.com wrote: Your makeUTF8 should look like this: private def makeUtf8(req: HTTPRequest): Unit = {req.setCharacterEncoding(UTF-8)} just use HTTPRequest instead of HttpServletRequest. Br's, Marius On Aug 10, 7:49 pm, glenn gl...@exmbly.com wrote: I just got a type mismatch found error in LiftRules.early.append (makeUtf8) in Boot.scala. It's now looking for an net.liftweb.http.provider.HTTPRequest instead of a javax.servlet.http.HttpServletRequest. Is this a new change, and if so, where is the net.liftweb.http.provider package? Glenn... -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Git some:http://github.com/dpp -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Sitemap and mapper dependency's effects on object reuse
I'm looking for some answers on best coding practices, particularly when it comes to object reuse. In a data-centric application, where the Sitemap is used to navigate through your mapper entities, has anyone given much thought to the object dependencies this can create. In the case of page specific rendering with SiteMap, for example, where should the Menu entries go - in their own object, or should they stay with the MetaMappers. And what about the templates, which can have dependencies on snippets, which reside elsewhere. In other words, it seems to me that good design requires managing the chain of dependencies that an ordinary Menu entry may require. A consistent approach is always best, and I admit that I don't have one at present. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: makeUtf8 and HttpServletRequest broken in new build???
Is anyone planning on fixing the archetype snapshots to add this change, and import provider._ in Boot.scala. Thanks in advance, Glenn... On Aug 10, 10:36 am, marius d. marius.dan...@gmail.com wrote: Your makeUTF8 should look like this: private def makeUtf8(req: HTTPRequest): Unit = {req.setCharacterEncoding(UTF-8)} just use HTTPRequest instead of HttpServletRequest. Br's, Marius On Aug 10, 7:49 pm, glenn gl...@exmbly.com wrote: I just got a type mismatch found error in LiftRules.early.append (makeUtf8) in Boot.scala. It's now looking for an net.liftweb.http.provider.HTTPRequest instead of a javax.servlet.http.HttpServletRequest. Is this a new change, and if so, where is the net.liftweb.http.provider package? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: CMS for Lift?
Philip, I'm working on a cms system in Lift. Right now, it allows for content creation using wymeditor, which can be tagged and displayed as an atom feed. This code is runnable, simple as it is. I'm working on adding dynamic site map creation as well. Is this kind of what you have in mind by a CMS system. I'm very interested in workiing with others on a CMS that can compete with any of the PHP varieties out there, such as Drupal and Wordpress. Most of these simply use plugins from one ore more javascript libraries out there for site creation, and Lift certainly can do javascript as well as, if not better than, these systems. Glenn... On Aug 15, 11:08 pm, philip philip14...@gmail.com wrote: Hi, Has anyone made a CMS for Liftweb? or I should say, in liftweb. Thanks, Philip --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] makeUtf8 and HttpServletRequest broken in new build???
I just got a type mismatch found error in LiftRules.early.append (makeUtf8) in Boot.scala. It's now looking for an net.liftweb.http.provider.HTTPRequest instead of a javax.servlet.http.HttpServletRequest. Is this a new change, and if so, where is the net.liftweb.http.provider package? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: makeUtf8 and HttpServletRequest broken in new build???
I realize the need to improve the code, but do you have to break existing in the process? That's bad form. Glenn... On Aug 10, 9:55 am, Tim Nelson tnell...@gmail.com wrote: There were changes made to remove the requirement for lift to run in a servlet container. See: http://groups.google.com/group/liftweb/browse_thread/thread/a3486a7b9... On Mon, Aug 10, 2009 at 11:49 AM, glenn gl...@exmbly.com wrote: I just got a type mismatch found error in LiftRules.early.append (makeUtf8) in Boot.scala. It's now looking for an net.liftweb.http.provider.HTTPRequest instead of a javax.servlet.http.HttpServletRequest. Is this a new change, and if so, where is the net.liftweb.http.provider package? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: New features
David, I'm using your new ManyToMany trait and ran across this error: Message: java.lang.ClassCastException: net.liftweb.mapper.ProtoUser$id $ cannot be cast to java.lang.Long scala.runtime.BoxesRunTime.unboxToLong(Unknown Source) net.liftweb.mapper.MappedLong.real_i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.i_set_$bang(MappedField.scala: 449) net.liftweb.mapper.MappedLong.i_set_$bang(MappedLong.scala:223) net.liftweb.mapper.MappedField$class.set(MappedField.scala:429) net.liftweb.mapper.MappedLong.set(MappedLong.scala:223) net.liftweb.mapper.ManyToMany$MappedManyToMany.own(ManyToMany.scala: 78) My code that generates the error is: entity.roles += r where entity is a User and roles is the MappedManyToMany object in User. Glenn... On Aug 8, 10:35 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Thanks, David. Glenn, as far as the issue of adding unsaved children, I was thinking about it. If the same Role can be referenced by multiple users, why are you creating Roles at the same time that you are adding them to a User? Shouldn't there be one screen to manage Roles and the User screen would only allow you to add existing Roles? - David Pollakfeeder.of.the.be...@gmail.com wrote: There are dependent types that mirror the parameterized types for Mapper, KeyedMapper, etc. I've updated ManyToMany to use the dependent types... it should eliminate the need to have the type parameters. If it breaks thing, please revert the changes. On Thu, Aug 6, 2009 at 9:55 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: In your use case it can only be Long and User. But there has to be a type parameter because other people might have a String key and a Request mapper. And the contents of ManyToMany have to be type safe to enforce their consistency with however the user of ManyToMany wants them to use it. So I think what you want is that the compiler should figure out that since you're using it with a KeyedMapper[Long, User], which is ManyToMany's T : KeyedMapper[K,T], and ManyToMany extends KeyedMapper[K,T] and it has a self type of T, and therefore it would be a compiler error to write anything besides Long and User, therefore you must want to use Long and User and they should be inferred. I could certainly hear that, although I'm not much of a type theorist. So feel free to open an enhancement ticket on Scala's Trac! :) If I understood correctly... On Thu, Aug 6, 2009 at 12:43 PM, glenn gl...@exmbly.com wrote: Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident
[Lift] Re: StatefulSnippet link and functionMap
Here's my code sample that illustrates the problem: class UserView(entity:User, snippet:ManageUsers) extends ModelView [User](entity, snippet){ override val editAction = TheBindParam(edit, snippet.link(edit, ()=load, Text(S?(Edit Roles val addRole = TheBindParam(insert, snippet.link(edit, () =insertRole , Text(S?(Add Role val saveUser = TheBindParam(submit, snippet.link(list, () =save , Text(S?(Save def insertRole = { val r = new Role r.save entity.roles += r save } } class ManageUsers extends ModelSnippet[User]{ val myView:UserView = new UserView(new User, this) val view: ModelView[User] = myView /** * The list snippet */ def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = val v = new UserView(u, this) v.load val e = v.entity bind(user, chooseTemplate(user, entry, ns), firstname - Text(e.firstName.is), lastname - Text(e.lastName.is), email - Text(e.email.is), roles - e.roles.map(_.name.toString).mkString(, ), v.editAction, v.removeAction ) }) }) openOr Text(You're not logged in) /** * The edit snippet */ def edit(ns: NodeSeq): NodeSeq = { val theUser = myView.entity bind(user, ns, name - Text(theUser.firstName.is + + theUser.lastName.is), roles - theUser.roles.flatMap({role = bind(role, chooseTemplate(role, entry, ns), name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }), myView.addRole, myView.saveUser ) } The addRole and saveUser links generate the error. I even tried using SHtml.link instead of StatefulSnippet.link and it made no difference. The links append a different function map parameter to the URL, when what I think I really need is just the link, /edit, not something like this: http://localhost:8080/edit?F54610774551004F=_. Does any of this make sense? On Aug 7, 8:41 am, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 6, 2009 at 3:09 PM, glenn gl...@exmbly.com wrote: I have a stateful snippet with multiple StatefulSnippet links in the bind helper. Clicking on each link gives me a 403 error. I noticed that the function map for each link is different. Shouldn't they be the same, since I'm trying to reload the same page as the one the link is on? Can you post an example based onhttp://github.com/dpp/lift_1_1_sample/tree/masterthat demonstrates the problem? Glenn... -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 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 -~--~~~~--~~--~--~---
[Lift] Re: New features
Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli Gugenheim naftoli...@gmail.com wrote: I'll try. By the way, as per my correction, you can implement list the regular way without ModelView, and just use ModelSnippet's load function in your edit link or button, passing it the User instance. - glenngl...@exmbly.com wrote: Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each
[Lift] Re: New features
Naftoli, As I said at the outset, this is really beyond my expertise. But I think it's too broad and maybe, even unnecessary. In my example, K can only be one type, Long, and T can only be of type User. Anything else, and the compiler can't be guaranteed to catch it, but try running the application and you get things like stack overflow errors. How you would fix this is beyond me. All you can really do, at this point, is make sure to include these kinds of restrictions in the docs. Glenn... On Aug 6, 9:33 am, Naftoli Gugenheim naftoli...@gmail.com wrote: It's too broad, or it's too restrictive/unnecessary? I'm confused, you seem to imply both.If it's too broad, tell me why. But if you want to know why it needs the type parameter, it's because it has to use the type parameter in its implentation -- just count how many times its source code uses it! And if you want to know why the compiler can't infer it or be told to infer it... that's another issue. But if passing a type that creates a conflicting inheritance causes a compiler crash, that's not something I can help. :) Regards. On Thu, Aug 6, 2009 at 12:26 PM, glenn gl...@exmbly.com wrote: Naftoli, At the risk of discussing something obviously beyond my pay grade, isn't the real issue Scala traits and the use of parameterized types. The ManyToMany trait is defined as: trait ManyToMany[K,T:KeyedMapper[K, T]] But this isn't really correct,is it, the parameter is too broad, and that leads to a lot of the confusion and results in the need for unnecessary documentation. When you think about it, why all the duplication? Why do I need to write my User entity as: class User extends MegaProtoUser[User] with ManyToMany[Long,User] when we all know that this would be much cleaner: class User extends MegaProtoUser[User] with ManyToMany. But traits aren't like interfaces. They have implementation and would need to know something about the parent class they are attached to - and how would you accomplish that (reflection, maybe). This is more a Scala issue than a Lift one, I think. Glenn... On Aug 5, 8:24 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Building causes a stack overflow? So the question is, is it the resident compiler or plain scalac also crashes? Or just the presentation compiler? What do you see in the error log view or file? I get compiler crashes very often when doing fancy mapper type related tricks. - glenngl...@exmbly.com wrote: Naftoli, Hate to do this to you, but I'm getting the following error using ManyToMany for Users to Roles: Message: java.lang.RuntimeException: Broken join scala.Predef$.error(Predef.scala:76) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children$1$ $anonfun$apply$1.apply(ManyToMany.scala:54) net.liftweb.util.EmptyBox.openOr(Box.scala:372) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany$$anonfun$children $1.apply(ManyToMany.scala:54) scala.List.map(List.scala:812) net.liftweb.mapper.ManyToMany$MappedManyToMany.children (ManyToMany.scala:54) net.liftweb.mapper.ManyToMany$MappedManyToMany.elements (ManyToMany.scala:96) scala.Seq$class.flatMap(Seq.scala:293) net.liftweb.mapper.ManyToMany$MappedManyToMany.flatMap (ManyToMany.scala:44) def edit(ns: NodeSeq): NodeSeq = { val theUser = view.entity val addRole = TheBindParam(insert, view.snippet.link(edit, () = theUser.roles += new Role, Text(S?(Add Role bind(user, ns, firstname - text(theUser.firstName.is, theUser.firstName (_), (size,20)), lastname - text(theUser.lastName.is,theUser.lastName(_), (size, 30)), roles - theUser.roles.flatMap{role = bind(role, ns, name - role.name.toForm, remove - SHtml.submit(S?(Remove), ()= theUser.roles -= role) ) }, addRole, submit - SHtml.submit(S?(Save), ()=view.save) ) } The offending code seems to be the line: roles - theUser.roles.flatMap{ in the above bind method when I click on the addRole link. Here's my User class: class User extends MegaProtoUser[User] with ManyToMany[Long,User]{ def getSingleton = User // what's the meta server object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role) } What am I doing wrong? You can see how difficult it is to slog through this code, let alone just trying to explain the problem so I can get help. On Aug 5, 9:57 am, Naftoli
[Lift] StatefulSnippet link and functionMap
I have a stateful snippet with multiple StatefulSnippet links in the bind helper. Clicking on each link gives me a 403 error. I noticed that the function map for each link is different. Shouldn't they be the same, since I'm trying to reload the same page as the one the link is on? Glenn... --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[Lift] Re: New features
Naftoli, I fixed my code per your comments and now I can edit and remove users from a list, as long as I populate the list with ModelView instances, as you said. As for the docs, this step was not clear to me at all. I just assumed that the list was just populated with User entities and the view in the ModelSnippet was instantiated with the selected User on each request. It sounds like your plate is pretty full, so I won't expect much, but sometime soon, could you provide an example, or improved docs, for using TableEditor and its related ItemsList trait. Thanks for all. Glenn... On Aug 5, 9:18 am, Naftoli Gugenheim naftoli...@gmail.com wrote: Correction: ModelSnippet.load takes the actual Mapper instance, not the ModelView wrapper. - Naftoli Gugenheimnaftoli...@gmail.com wrote: To answer your immediate question, the listing should not refer to the snippet's view but new ModelView instances for each entity. Then editAction is shorthand for the snippet's link method with a callback to call load on the ModelView. To set the snippet's view's entity, either call load on the snippet with the other ModelView, or call load on the other ModelView (or just set its entity directly). As far as documentation, please tell me what scaladocs need what clarification. Thanks. - glenngl...@exmbly.com wrote: Naftoli, Functional programming systems are notoriously difficult to document. The only way to really know what's going on is to meticulously trace through the source. But that requires time-consuming trial and error coding. So, without clear examples demonstrating exactly what you have in mind, I and others in the same boat, could spend days and still not get it right. For example, I tried this: var theUser:User = null val view = new ModelView(theUser, this) def list(ns: NodeSeq): NodeSeq = User.currentUser.map({user = User.findAll.flatMap({u = bind(user, chooseTemplate(user, entry, ns), firstname - Text(u.firstName.is), lastname - Text(u.lastName.is), email - Text(u.email.is), roles - u.roles.map(_.name.toString).mkString(, ), view.editAction, view.removeAction ) }) }) openOr Text(You're not logged in) and, I get a null value exception when I try to remove a user in the list. Simply using val view = new ModelView(new User, this), doesn't work either, although I don't get an exception. Now, where should I be calling load in all of this? Glenn... On Aug 3, 6:22 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: Your snippet should extend ModelSnippet (which extends StatefulSnippet). Then write: val view = new ModelView(new User, this) {} Calling load on another ModelView that references the snippet will load its entity into that view val. It has a number of methods of possible interest, like save which checks validity. Also see Util. Are you seeing the scaladocs? - glenngl...@exmbly.com wrote: Just to add to what I just wrote, I don't see how your ModelView can be applied to User, which already extends a class, MegaProtoUser. Maybe I'm not comprehending this correctly. Glenn... On Aug 3, 3:48 pm, glenn gl...@exmbly.com wrote: Naftoli, Liked your OneToMany article, but not sure how the new ModelView and ModelSnippet code can be applied to ManyToMany. Can you provide a sample? Glenn... On Aug 2, 1:21 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: I put an article on the wiki about OneToMany --http://wiki.github.com/dpp/liftweb/how-to-work-with-one-to-many-relat... . On Sun, Aug 2, 2009 at 11:20 AM, Naftoli Gugenheim naftoli...@gmail.comwrote: Glad to hear. Also see mapper.view.ItemsList (anyone have a better name?), which is used byTableEditor. It's a similar idea without relationships. Should MappedOne/ManyToMany be based on ItemsList? Also should I take Mapped out of those names? After all, they're not MappedFields and they don't correspond to a table column. - Magnus Alvestadmagnus.alves...@gmail.com wrote: This work that you've done in Mapper fits in very well with something I've been planning to do. In a Java project some time ago we implemented a 'change engine'. We were loading big pension agreements, manipulating them in a web interface and finally saving them back to the database. While the user was working on the agreement, we generated a list of changes, containing enough information to replay or unroll the change. We could use this to implement undo and some semi-intelligent merging when two users were trying to commit changes to the same