[Lift] Re: Help with the eclipse plugin
Ellis ellis.whiteh...@gmail.com writes: Hi Dan, I don't have an answer to your question, but maybe a suggestion. Eclipse does not work well with maven/scala/lift, and I really doubt it will anytime soon. I don't know about the Maven part, but Eclipse works with Scala Lift. It's not nearly as functional as with Java, but I can edit, compile and debug without too much trouble. Advanced stuff such as completion, navigation etc. doesn't seem to work that well and I sometimes need to do a clean all to get back into a working state I'm using it daily without major pain, but await the 2.8 plugin (when Lift moves to 2.8 :-) I don't like Maven, so only use it to bootstrap the project. These steps works for me (Eclipse EE 3.5, Scala 2.7.5): mvn archetype:create -U -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-basic \ -DarchetypeVersion=1.1-SNAPSHOT \ -DremoteRepositories=http://scala-tools.org/repo-snapshots \ -DgroupId=demo.helloworld -DartifactId=helloworld -Dversion=1.1-SNAPSHOT verify it works: mvn jetty:run Press Ctrl-C to stop mvn eclipse:eclipse In Eclipse: - If you haven't already: Define M2_REPO classpath var to point to your local maven repo (~/.m2/repository) - Import the project you just created above - Eclipse plugin don't like multiple output folders so modify your projects build path * Remove all existing source folders * Add the source folders src/main/scala, src/main/resources, src/test/scala src/test/resources, all with the same output folder - Clean the project - You can now launch src/test/RunWebApp as a Scala Application to have jetty run inside eclipse and you can run debug etc - Running specs with the Eclipse JUnit runner is possible but requires a workaround, see the specs site. /Jeppe --~--~-~--~~~---~--~~ 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 the eclipse plugin
Miles Sabin mi...@milessabin.com writes: On Thu, Jul 9, 2009 at 5:45 PM, David Pollakfeeder.of.the.be...@gmail.com wrote: But, until Martin's magic brain has yielded code for us, I would recommend avoiding Eclipse for Scala and Lift related development. Unsurprisingly I disagree. Bug reports and more contributions to documentation on using Eclipse with Lift and Maven would be much appreciated from the Lift community. There's a start here, http://lampsvn.epfl.ch/trac/scala/wiki/ScalaEclipseLift http://lampsvn.epfl.ch/trac/scala/wiki/ScalaEclipseMaven but clearly a great deal more is needed. A little more encouragement and a little less FUD wouldn't go amiss. A major show stopper atm is that Lift, afaik, doesn't work with Scala 2.8 which makes it difficult to actually use the trunk plugin. It is my (maybe incorrect?) impression that there's not a lot of activity happening on the 2.7.5 plugin /Jeppe --~--~-~--~~~---~--~~ 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] Typesafe JSON builder?
Hi, Has anyone made a typesafe JSON builder? Many Javascript libraries provides support for extensive customization, usually via a JSON object (eg. http://www.jqplot.com/docs/files/optionsTutorial-txt.html#Options_Tutorial It would be nice to generate this from Scala which would then give you type checking, IDE auto completion etc. Lacking concrete implementations, any ideas on the best way to approach this. I've seen http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html which looks like a viable (if a bit verbose) approach. /Jeppe --~--~-~--~~~---~--~~ 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 the eclipse plugin
Naftoli Gugenhem naftoli...@gmail.com writes: Completion works for me, when there are no basic syntax errors in the file (mismatched bracketd etc.). Also, I use lift without running maven from the command line. I create the project with m2eclipse, and I don't recall having to set M2_REPO. The M2_REPO var is used by the .classpath generated by mvn eclipse:eclipse /Jeppe --~--~-~--~~~---~--~~ 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: NPE Problem with User.current in CRUDify action
Just a normal request from a link in a CRUDify list Sendt fra min iPhone Den 07/07/2009 kl. 18.49 skrev David Pollak feeder.of.the.be...@gmail.com : Are you doing this as part of an HTTP request or at some other point in the execution of your code (e.g., a background processing thread)? On Tue, Jul 7, 2009 at 5:53 AM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Hi, I get an Empty box when using the value of User.current when trying to populate the valid select values for use in a CRUDify edit form: I have this mapped object which I'm trying to edit using CRUDify: class Vehicle extends LongKeyedMapper[Vehicle] with IdPK { [...] object customCategory extends MappedLongForeignKey(this, CustomCategory) { override def validSelectValues = Full(CustomCategory.findMap {cc : CustomCategory = Full(cc.id.is, cc.description.is)}) } [...] I then have this, that uses the current user to populate the valid values: object CustomCategory extends CustomCategory with LongKeyedMetaMapper [CustomCategory] { def findMap[T](f: CustomCategory = Box[T]) : List[T] = { Log.info(User %s, id=%s.format(User.currentUser, User.currentUserId)) findMap(By(id, User.currentUser.open_!.account.is))(f) } When navigating to the edit page for Vehicle, I get this in the log: INFO - User Empty, id=Full(2) So it seems the user id is stored ok, but the RequestVar is not set. Any clues?? /Jeppe -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://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: MappedDecimal and nulls
Derek Chen-Becker dchenbec...@gmail.com writes: Done. Hudson should build it and have it in the repo soon. Thanks! /Jeppe --~--~-~--~~~---~--~~ 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 test/TDD lift apps?
On Fri, Jul 3, 2009 at 6:43 PM, David Pollakfeeder.of.the.be...@gmail.com wrote: Jeppe, Once I check in some code (in about 20 minutes), if you run Lift in Test mode (-Drun.mode=test), forms, etc. will have stable names which makes testing easier. Thanks. I just tried this, and it seem something is not correct. Here's a form field genrated by CRUDify: input name=f01000_a0f86e3b78187b55b8628a66fb3371113ddc295c type=text maxlength=2 value=DK lift:field_name=vehicle:country / Firefox 3.5 complains about lift:field attribute. Looking at the changes (and the example above) it seems that the field name is still some psuedo random number. While this is better than names changing between each request, I'm wondering if it's stable to reordering removing fields (my guess is no). It would be nice not to change test cases just because we rearrange the form layout. Moving forward, I'm not sure what the best solution is. I seem able to specify the id attribute for forms that I create manually, but need this also on CRUDify and other generated forms (and looking at the above example, it seems it should be easy to eg. use the field_name). In general, It would be nice for Lift to handle all this automatically (as you've already started out to do), but if I have to add some additional markup to make sure ids/names stay stable, I will prefer that over test cases breaking if field ordering is changed. /Jeppe --~--~-~--~~~---~--~~ 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] Mapper: How to clone object fields?
Hi, What is the best way to copy values from one mapped object to another (of the same type). The code below seems to work but I was wondering if there's a better way? def insertOrUpdate(v:Vehicle) = Vehicle.find(By(vin, v.vin.is)) match { case Full(existing) = { existing.getSingleton.mappedFields.foreach (f = v.fieldByName(f.name) match { case Full(field) if (!field.dbPrimaryKey_?) = f.asInstanceOf[MappedField[Any, Vehicle]].setFromAny(field.asInstanceOf[MappedField[Any, Vehicle]].is); case _ = } ) existing.save existing } case _ = v.save; v /Jeppe --~--~-~--~~~---~--~~ 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 to test/TDD lift apps?
Hi, Having taken the first baby steps and gotten a Lift app running, it's time to bring back some of the old engineering practices to make sure things keep running when new features are added at a rapid pace :-) I'm interested in how people are testing their Lift apps, both at the unit test level (ie. specs/scalatest with no container) and at the integration test level (running in servlet container). Also, how are you doing TDD with Lift (if at all). Specifically, I've run into the following issues: 1) Testing model classes. Many require access to S (ie to read resources) or other static Lift constructs. How can you mock these? 2) Testing snippets. Same issue with S, but more related to the actual request, eg. S.param For in-container testing it seems the practice of generating unique names for form fields, makes it difficult to use tools like Selenium to do browser based testing? How do you handle this? Any input is appreciated /Jeppe --~--~-~--~~~---~--~~ 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: Thoughts on file streaming
Derek Chen-Becker dchenbec...@gmail.com writes: Well, as usual something that seemed simple at first glance is now looking somewhat complex. I'm thinking of reworking the fileUpload handling to allow a user to register either a (String, String, Array[Byte]) ⇒ Any or (String, String, InputStream) ⇒ Any function, which would then be executed during request processing. The issue is that form field processing (ParamHolders) takes place in Req, before LiftSession has been set up, and the act of parsing the request for form data, particularly for large upload streams (the target of these changes) precludes holding on to any data for later processing (the servlet container cannot be expected to hold the entire request in memory). On the other hand, users should reasonably expect that their form handling functions are stateful, so I'm trying to think of some way to meet in the middle on form processing. Ideas? Sounds nice. Will this in some way be able to display any progress of the upload (which, imho, is needed for large uploads). E.g. something like this http://wiki.nginx.org//NginxHttpUploadProgressModule /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
On Sat, Jun 27, 2009 at 5:46 PM, Timothy Perretttimo...@getintheloop.eu wrote: Guys, If you want changes made to the flot widgets, please let us know what exactly needs changing and we'll get it done. By all means, please don't feel you are out in the cold! Hi Tim, Personally, I don't feel left out in the cold :-) On the contrary, people in this community seem very willing to listen to (and implement) requests for new functionality. On the other hand, I realize that my issues are not necessarily top priority for others. So I'm willing to spend some time to fix my issues (since I need them fixed now) and share the changes back where possible... /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
dflemstr david.flemst...@gmail.com writes: Hello everyone involved, I am having a very annoying problem with the Flot widget: The automatically generated legend's auto-sizing feature is broken (it grows horizontally to the max allowed space while still adhering to the margin values specified, and it's not possible to create an external, custom legend) as demonstrated by this screenshot: http://bit.ly/uKE9o This bug is present in 1.1-M1 as well as 1.1-SNAPSHOT, isn't caused by me (since it is present int he demo app) and seems to originate from something on the client-side (obviously). Does anyone have a solution to this problem, or if not, can I make a fork of the widgets module, try to fix the problem, and commit it back? This little inconvenience removes much of the visual quality of plots, so a solution to it would be very much appreciated. I haven't looked in detail but: Is this a problem with the widget or the Flot library? As far as I know, the widget is just a thin wrapper on top of the Flot JS library. If it's a problem with the JS, you should probably try to fix this upstream: http://code.google.com/p/flot/ /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
On Sat, Jun 27, 2009 at 11:10 AM, dflemstrdavid.flemst...@gmail.com wrote: As can be seen here: http://bit.ly/13EEnw , the bug isn't present in the vanilla Flot library. Make sure you're trying to plot the same data with the same plot options. I am at a loss to find the bug causing all this. The whole Flot widget seems to be very messy (it consists of 30% commented-away code, for instance) and I would be happy to help improve it once and for all, since I'm in need of the Flot library for a project. I'm basically in the same boat and will probably clone the lift-widgets module on github and work from there (I'm not a Lift committer). I hope Francois will then commit the changes to Lift at some point :-) I think we should coordinate the effort to avoid wasting resources. Let me know what you think /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
On 26 Jun 2009, Peter Robinett wrote: Hi flot users, I am trying to copy the basic Flot example into my own code. I have no compile errors but the graph isn't rendered because /classpath/flot/ jquery.flot.js isn't found. Since I get no errors with the flot methods in my snippet, I assume lift-widgets is loading correctly. Am I missing something? Did you put a call to net.liftweb.widgets.flot.Flot.init in Boot? This is needed to make the javascript resources available... /Jeppe --~--~-~--~~~---~--~~ 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: Including jars into a liftweb project
On 26 Jun 2009, fbettag wrote: Hey guys, i was wondering how (and where) i have to put jars in my liftweb project to get them included. i know it's a beginners question, but i've been playing around all night and i couldn't get it to work. Normally, you would put jars in the WEB-INF/lib folder and they will be picked up by the servlet container They need to be available at compile time too... /Jeppe --~--~-~--~~~---~--~~ 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 mapper class: MappedEnumString
Oliver Lambert olambo...@gmail.com writes: [...] No this isn't what I'm suggesting, I don't think MappedEnum should be made flexible. I know this wasn't your suggestion, but any reason not to make MappedEnum flexible (if possible and backwards compatibility could be maintained) ? I was thinking perhaps your class could work with EnumWithDescription as shown below, which extends Enumeration#Values to include a description. This should be simple, but see below trait ValueWithDescription { def description: String def name: String } abstract class EnumWithDescription { type Value = enum.Value with ValueWithDescription private var _values: List[Value] = Nil def values = _values // possibly not a good idea using this directly val enum = new Enumeration { def Value(inName: String, inDescription: String): Value with ValueWithDescription = { new Val(nextId, inName) with ValueWithDescription { def description = inDescription def name = inName } } } def Value(name: String, description: String): Value = { val value = enum.Value(name, description) _values = _values ::: List(value) // build in order value } def Value(name: String): Value = Value(name, name) def valueOf(name: String) = values find (_.name == name) def nameDescriptionList = values map(x = (x.name, x.description) ) } At first I didn't understand why you don't just extend Enumeration like this: abstract class EnumWithDescription extends Enumeration { def Value(inName: String, inDescription: String): Value with ValueWithDescription = { new Val(nextId, inName) with ValueWithDescription { def description = inDescription def name = inName } } } but figure you would then have to cast all the values to ValueWithDescription. It seems Enumeration miss a type parameter to describe the types of Values in cases like this. Hmmm I see Enumerations have changed for 2.8 so maybe this is not impossible Back to the mapping. The way I see all these different solutions is: 1) We need to define Enumerations to get nice handling of predefined constants 2) The enumeration values need to be mapped to a database value (numeric or string) 3) The enumeration values need to be mapped to a display value (from code our property files) If the MappedEnum was parameterized on how to achieve 2+3 it seem all possibilities are open. If MappedEnum worked with ValueWithDescription values instead of Enumeration#Value, it might? be possible to define an implicit conversion from Enumeration#Value to ValueWithDescription I don't have much time in the days that are coming but will try to think of a solution to this. Input is welcome :-) /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
Peter Robinett pe...@bubblefoundry.com writes: Thanks, Jeppe, that's what I was missing. To continue to hijack this thread with my own questions, I'm having a problem creating the data List[(Double, Double)] that FlotSerie wants. I have: override val data = MyModel.findAll(By(MyMode.id, myId), OrderBy (MyModel.datetime, Ascending)).map(m = (m.datetime.getTime.toDouble, m.temperature.toDouble)) If m.temperature is a MappedDouble you probably need m.temperature.is The toDouble method converts an Any to a double, not the value of the current mapped object. /Jeppe --~--~-~--~~~---~--~~ 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: Anyone working on the flot widget?
On 25 Jun 2009, Francois Bertrand wrote: Hi Jeppe Great to see you are interested in the flot widget. My current to-do list for the flot widget, is: - create more Lift JsExp and JsCmd to modify a already displayed flot graph. They should be used in AJAX and Comet applications - update to a more recent version of the javascrrit widget I need this as well, especially since there are some patches that provides pie charts - create the test demo app, - make the creation of FlotOptions, FlotLinesOptions, etc, less verbose. I hope that Scala 2.8 Named and Default Arguments will help. Yeah, this would be nice :-) We probably need some working code within the next few weeks so probably can't wait for 2.8 though. - create a high level mechanism to display Lift's Record I appreciate any help. What's the best way to coordinate this? Just fork the code on github or? /Jeppe --~--~-~--~~~---~--~~ 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 mapper class: MappedEnumString
On Thu, Jun 25, 2009 at 1:12 AM, Oliver Lambert olambo...@gmail.com wrote: Looks very nice. One thing I'm wondering, what if I wanted the displayed value outside of the mapper, such as TestTypes.Item1.displayValue. Would you use an implicit conversion to provide this or is the display value conceptually always part of a mapper object. Good question :-) I'm still using CRUDify generated views while prototyping, but will probably need some more sophisticated layouts at some point. Don't yet know if the display value will come from the mapper object or the underlying enum. I have a rough implementation called EnumWithDescription, that wraps (not extends) an Enumeration and provides a description method on the enumeration value without using an implicit. I'm wondering if it might be useful to combine your approach and mine? Sure. It might also be possible to make the original MappedEnum a bit more flexible instead (as Derek suggested earlier). My class is basically just a copy with very few modifications to handle the db value. I just haven't got the Scala knowledge yet to easily see how the interface should be and I needed to nail the db schema :-) /Jeppe --~--~-~--~~~---~--~~ 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: Best method to protect most menu items?
On 23 Jun 2009, David Pollak wrote: Jeppe, I just checked in code (it'll take 45 minutes to hit the Maven repo) that has global LocParams for each SiteMap. The SiteMap constructor is now: SiteMap(globalParamFuncs: List[PartialFunction[Box[Req], Loc.LocParam]], kids: Menu*) You can put your Redirect stuff in like: List({ case _ if !User.loggedIn_? = ... }) Brilliant! Works nicely. I ended up with this val menuDispatch:List[PartialFunction[Box[Req], Loc.LocParam]] = List({ case Full(Req(profile :: login :: Nil , _, _)) = Hidden case Full(Req(profile :: lost_password :: Nil , _, _)) = Hidden case Full(Req(_, _, _)) if !User.loggedIn_? = Loc.EarlyResponse(() = Full(RedirectResponse(/profile/login?returnTo=+S.uri))) }) A couple of questions: 1) Why the need for Box[Req]? When will it be Empty? 2) In the above I had to use Hidden as a dummy value to signal no Loc. It might be useful with a Box[Loc.LocParam] as return value? /Jeppe --~--~-~--~~~---~--~~ 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] Anyone working on the flot widget?
Hi, We need to do quite a lot of charting in our app and after evaluating several libraries we've settled on Flot (for now at least :-) So I was happy to discover there was already some Flot integrations in Lift. After having looked a bit at this, it seems there are some things missing that we would need: 1) Better support for barcharts (ie specifying data series as (label, value)) 2) Support for pie charts (patches exists for the JS part) But before diving into this I thought to ask if anybody is already working on the flot widget (or has other ideas for the Flot stuff) /Jeppe --~--~-~--~~~---~--~~ 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: Best method to protect most menu items?
On Wed, Jun 24, 2009 at 3:25 PM, David Pollak feeder.of.the.be...@gmail.com wrote: Oh... I get why you did the Hidden thing... I'd do the following: case Full(Req(path, _, _)) if !User.loggedIn_? path != List(profile, login) path != path != List(profile, lost_password) = Loc.EarlyResponse(() = Full(RedirectResponse(/profile/login?returnTo=+S.uri))) If you prefer to do the pattern matching thing, you can return: new Loc.LocParam{} That's a noop. Ahh yes (Note to self: Not everything needs to be pattern matched :-) Thanks for the quick solution! /Jeppe --~--~-~--~~~---~--~~ 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: Modify CRUDify XHTML
On 24 Jun 2009, Peter Robinett wrote: Hi all, I'm using CRUDify on one of my models and I'd like to display some additional data on the view template. I believe that I need to override one of the model definitions with some sort of reference to my own XHTML file. Which one? _viewTemplate? Or perhaps the viewTemplate method? If you look at the source to CRUDify, you'll see def viewTemplate(): NodeSeq = pageWrapper(_viewTemplate) where def pageWrapper(body: NodeSeq): NodeSeq = lift:surround with=default at=content { body } /lift:surround def _viewTemplate = lift:crud.view table id={viewId} class={viewClass} crud:row tr tdcrud:name//td tdcrud:value//td /tr /crud:row /table /lift:crud.view So the simplest thing is to override _viewTemplate with something similar to the above. This should be done on the companion objects where CRUDify is mixed in /Jeppe --~--~-~--~~~---~--~~ 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] New mapper class: MappedEnumString
Hi, A while ago, I asked if it was possible to use something like MappedEnum and have some sensible values inserted into the database instead of integers. I got the feeling this was not the case, so I've created MappedEnumString (attached) which maps Enumerations into string values. Example: object TestTypes extends Enumeration { val Unknown = new Val(0,??) val Item1 = new Val(XX) val Item2 = new Val(YY) } object test extends MappedEnumString(this, TestTypes, 2) This will store the values, ??, XX or YY in the db. For display purposes, it will by default lookup the resource values TestTypes.??, TestTypes.XX, TestTypes.YY You can also calculate the displayed values: object test2 extends MappedEnumString(this, TestTypes, 2) { override def _valueToDisplayString(v:Enumeration#Value) = v match { case TestTypes.Item1 = Item1Display case TestTypes.Item2 = Item2Display case _ = Unknown x ItemDisplay } } I'm by no means a Scala/Lift expert so I may have overlooked stuff, so feel free to comment :-) /Jeppe --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- MappedEnumString.scala Description: MappedEnumString.scala
[Lift] Best method to protect most menu items?
Hi, Our app is private, which means only the signin and related pages are visible without authentication. I've made this Loc to protect menu items, val loggedIn = Loc.EarlyResponse(() = Full(RedirectResponse(/profile/login?returnTo=+S.uri)).filter(ignore = !User.loggedIn_?)) and while this works, I think there must be a better solution since: 1) It's easy to forget adding this to menu items that should be protected (ie most in our case) 2) It's not easy to add this to MenuItems generated by Lift, e.g. CRUDIfy entries. So, I created this DispatchPF LiftRules.dispatch.prepend(NamedPF(Protect) { case Req(profile :: login :: Nil , , _) = () = Empty case Req(_, , _) = () = Full(RedirectResponse(/profile/login?returnTo=+S.uri)).filter(ignore = !User.loggedIn_?) }) but it doesn't seem to work since now /profile/login gives a 404. So basically, I have two questions 1) Is there a way for requests to fall through in the DispatchPF, ie /profile/login should just be processed as usual 2) Is there a better way to accomplish this? It seems the DispatchPF method would need to allow requests to javascript, css etc to be handled without authentication so you would have to maintain this whitelist (but this is less of a problem than maintaining the protected list) /Jeppe --~--~-~--~~~---~--~~ 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: Best method to protect most menu items?
On 23 Jun 2009, David Pollak wrote: I'll enhance sitemap to support global additions of parameters. Cool. Looking forward to this :-) Just out of curiosity: Is it possible to fall through in a DispatchPF, ie. do the default processing, even if the function is defined at the request? /Jeppe --~--~-~--~~~---~--~~ 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] Best way to create enum-like custom field mapping
Hi, Using mapper I have this: object FuelTypes extends Enumeration { val Diesel = new Val(1, Diesel) val Petrol = new Val(2, Benzin) } object fuelType extends MappedEnum(this, FuelTypes) This works, but the database value then becomes a meaningless number What is the best way to have some kind of enumeration-like values in the Scala code (ie Diesel Petrol) and store something sensible in the DB (ie 'D' and 'P')? /Jeppe --~--~-~--~~~---~--~~ 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 or Record?
On 16 Jun 2009, marius d. wrote: Lift Record currently is not implemented for DB interaction but it's targeted for 1.1 release. That probably explains why I couldn't find much when looking through the source :-) I'd say to start development using the Mapper and when Record is ready migrate to the Record. I would expect to be a fairly easy transition from Mapper to Record though. Ok, sounds good. Will mapper be extended in 1.1 or is it only bug fixing and all new development will happen in Record? /Jeppe --~--~-~--~~~---~--~~ 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: Difference between running from command line and from Eclipse
On 16 Jun 2009, ph wrote: I've created a test hello-world lift project and it runs fine. http://wiki.liftweb.net/index.php/HowTo_start_a_new_liftwebapp also I've imported this project to Eclipse (mvn eclipse:eclipse) and import from Eclipse. I'm currently using m2eclipse (http:// m2eclipse.codehaus.org/), but before I tried Eclipse IAM with same result: error in src/test/scala/RunWebApp.scala import _root_.org.mortbay.jetty.webapp.WebAppContext = WebAppContext is not in webapp project still runs from command line and fails in Eclipse I tried to create lift projects with maven in eclipse with same result - that error I'm on Windows I had the same problems. IIRC, it's a problem with the build path source folders/multiple output folders generated by the mvn eclipse plugin. I fixed this by manually deleting the source folders in eclipse and then adding src/main/scala src/test/scala as source folders (using the default output folder) /Jeppe --~--~-~--~~~---~--~~ 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: Difference between running from command line and from Eclipse
On 16 Jun 2009, Philippe Kirsanov wrote: Thank you for the reply, however I don't think this is the issue (I tried and that didn't work).Seems like issue in which version of Jetty is used. Maven generates pom file with jetty version [6.1.16,) and this works from command line, in Eclipse however it tries to use version 7.0.0.pre5 (I see it in dependencies). Changing jetty to version 7.0.0.pre5 in pom forces same error running from command line. The question is how to make maven plugin Eclipse use jetty v6 and not 7 pre5. Ahh sorry, didn't read the error message thoroughly :-) Why not just change jetty to 6.1.16? I went through the same steps some time ago. I'm not quite sure how I got the stuff info Eclipse, but my Eclipse project references jetty-6.1.6. Maybe something has changed in the lift plugin since then. This is from my pom: dependency groupIdorg.mortbay.jetty/groupId artifactIdjetty/artifactId version[6.1.6]/version scopetest/scope /dependency /Jeppe --~--~-~--~~~---~--~~ 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 remove leading text in Msgs.error
On Fri, Jun 5, 2009 at 6:05 PM, marius d.marius.dan...@gmail.com wrote: Committed. Let me know if that works for you. Works perfectly. Thanks /Jeppe --~--~-~--~~~---~--~~ 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 to remove leading text in Msgs.error
Hi, I'm trying to remove the Notice, Error lead in text that is displayed when using the Msgs snippet, like this: lift:snippet type=msgs lift:notice_msg class=success/lift:notice_msg lift:error_msg class=error/lift:error_msg lift:warning_msg class=notice/lift:warning_msg /lift:snippet Looking at the code, it seems the default text is used if the specified text is empty, so I tried putting a nbsp; in there but this also seems to be swallowed. Is there anyway to do this (besides changing the default property values)?? /Jeppe --~--~-~--~~~---~--~~ 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 Menu.builder li_path/li_item
On 3 Jun 2009, marius d. wrote: attribute with the same name but different prefixes should be ok as long as the prefixes are bound to namespace URL's. But the problem here is that the attributes are in an inner template, which, I presume, will be read before the outer template (with the namespace URLs). Parsing the inner template fails as shown previously. On a conceptual level I don't think the li_path, li_item namespaces should be declared in the resulting page produced by lift. It is used solely by Lift for the rendering. But it seems these kind of prefixes in xml fragments are not supported by the Scala XML parser. /Jeppe --~--~-~--~~~---~--~~ 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] Useless error messages if template parsing fails?
I'm curious: Am I the only one getting rather useless error messages in the browser when Lift fails to parse the templates? Something a long these lines: Exception occured while processing / Message: java.lang.IllegalArgumentException: line 15 does not exist scala.io.Source.getLine(Source.scala:280) scala.io.Source.report(Source.scala:368) It may just be my setup (Scala 2.7.4, Lift 1.1-SNAPSHOT, OS X), but I did a little digging in scala.io.Source and found what seems to be a bug (more details here, never mind the subject :-) http://www.nabble.com/Bug-in-java.io.Source-with-FileInputStream--td23840934.html ) Running in debug mode I saw that the original exception was '' not allowed in attrib value which seems much more helpful :-) Anyway, since I'm new to Scala/Lift I just wanted to verify if I'm the only one seeing this behaviour. /Jeppe --~--~-~--~~~---~--~~ 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 Menu.builder li_path/li_item
On 3 Jun 2009, David Pollak wrote: I've pushed up a fix Excellent, thanks! When I finally figured out how to use the li_* attributes I thought it was a very nice way to make the snippets configurable. Great was the dismay when I found it didn't work :-( /Jeppe --~--~-~--~~~---~--~~ 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] Problem with Menu.builder li_path/li_item
Running 1.1-SNAPSHOT, the following construct lift:Menu.builder li_path:class=pathclass li_item:class=itemclass/ Seems to results in an exception when Lift processes the template. The error seems related to the fact that both li_path li_item tries to set the class. If I change one to e.g. li_path:style, everything works. Is this a bug or is there a good reason why the above shouldn't be allowed? /Jeppe --~--~-~--~~~---~--~~ 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 Menu.builder li_path/li_item
On 2 Jun 2009, David Pollak wrote: Please post the exception The code is just the basic archetype with the above template changes and a new menu item as child of Home to show the path style. No exception on the console, but I get this in the browser: Exception occured while processing / Message: java.lang.IllegalArgumentException: line 61 does not exist scala.io.Source.getLine(Source.scala:280) scala.io.Source.report(Source.scala:368) scala.io.Source.reportError(Source.scala:355) scala.io.Source.reportError(Source.scala:344) scala.xml.parsing.MarkupParser$class.reportSyntaxError(MarkupParser.scala:1113) net.liftweb.util.PCDataXmlParser.reportSyntaxError(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.reportSyntaxError(MarkupParser.scala:1117) net.liftweb.util.PCDataXmlParser.reportSyntaxError(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.xAttributes(MarkupParser.scala:311) net.liftweb.util.PCDataXmlParser.xAttributes(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.xTag(MarkupParser.scala:365) net.liftweb.util.PCDataXmlParser.xTag(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:667) net.liftweb.util.PCDataXmlParser.element1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:481) net.liftweb.util.PCDataXmlParser.content1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content(MarkupParser.scala:505) net.liftweb.util.PCDataXmlParser.content(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:682) net.liftweb.util.PCDataXmlParser.element1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:481) net.liftweb.util.PCDataXmlParser.content1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content(MarkupParser.scala:505) net.liftweb.util.PCDataXmlParser.content(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:682) net.liftweb.util.PCDataXmlParser.element1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:481) net.liftweb.util.PCDataXmlParser.content1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content(MarkupParser.scala:505) net.liftweb.util.PCDataXmlParser.content(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:682) net.liftweb.util.PCDataXmlParser.element1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:481) net.liftweb.util.PCDataXmlParser.content1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content(MarkupParser.scala:505) net.liftweb.util.PCDataXmlParser.content(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.element1(MarkupParser.scala:682) net.liftweb.util.PCDataXmlParser.element1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.content1(MarkupParser.scala:481) net.liftweb.util.PCDataXmlParser.content1(PCDataMarkupParser.scala:91) scala.xml.parsing.MarkupParser$class.document(MarkupParser.scala:206) net.liftweb.util.PCDataXmlParser.document(PCDataMarkupParser.scala:91) net.liftweb.util.PCDataXmlParser$.apply(PCDataMarkupParser.scala:102) net.liftweb.http.TemplateFinder$.findAnyTemplate(LiftSession.scala:1194) net.liftweb.http.LiftSession.findTemplate(LiftSession.scala:712) net.liftweb.http.LiftSession.findAndMerge(LiftSession.scala:1068) net.liftweb.builtin.snippet.Surround$$anonfun$render$1$$anonfun$apply$2.apply(Surround.scala:36) net.liftweb.builtin.snippet.Surround$$anonfun$render$1$$anonfun$apply$2.apply(Surround.scala:31) net.liftweb.util.Full.map(Box.scala:330) net.liftweb.builtin.snippet.Surround$$anonfun$render$1.apply(Surround.scala:31) net.liftweb.builtin.snippet.Surround$$anonfun$render$1.apply(Surround.scala:30) net.liftweb.util.Full.flatMap(Box.scala:332) net.liftweb.builtin.snippet.Surround$.render(Surround.scala:30) net.liftweb.builtin.snippet.Surround$$anonfun$dispatch$1$$anonfun$apply$1.apply(Surround.scala:26) net.liftweb.builtin.snippet.Surround$$anonfun$dispatch$1$$anonfun$apply$1.apply(Surround.scala:26) net.liftweb.http.LiftSession$$anonfun$17$$anonfun$apply$47$$anonfun$apply$50$$anonfun$apply$52.apply(LiftSession.scala:843) net.liftweb.http.LiftSession$$anonfun$17$$anonfun$apply$47$$anonfun$apply$50$$anonfun$apply$52.apply(LiftSession.scala:830) net.liftweb.util.EmptyBox.openOr(Box.scala:372)
[Lift] Re: Problem with Menu.builder li_path/li_item
On 2 Jun 2009, David Pollak wrote: This is an XML parsing error. Something in your XML is non-parsable. It's not Lift, but the underlying XML parsing library. Yes, it would seem so. It looks like a bug/non-implemented feature that the parser is unable to read two attributes with the same name but in different name spaces. Not sure if this is because the fragment doesn't contain any name space decls? Unfortunately this renders the Menu.builder less useful since it is not possible to assign CSS classes to both the path items and the selected item (which, imho, is an obvious use case). Being a Lift newbie, I'm wondering if there are other parts of Lift that is influenced by this. Here's a very small test case that illustrates the problem: Given this program: import _root_.net.liftweb.util._ import _root_.java.io._ object ReadXML extends Application { val xml= PCDataXmlParser(new FileInputStream(test.xml)) } This XML fragment fails to parse: lift:surround with=base at=body lift:Menu.builder li_path:class=p li_item:class=i/ /lift:surround But this parses ok (note the slight change in attribute names): lift:surround with=base at=body lift:Menu.builder li_path:class=p li_item:clasz=i/ /lift:surround Accidentally, I think there's a problem with the error reporting when parsing fails. Looking at the code to scala.io.Source, the original exception is a double attribute syntax error, but due to what I think is a bug in Source.getLine, I always get errors reported as java.lang.IllegalArgumentException: line 1 does not exist Am I the only one seeing this? /Jeppe --~--~-~--~~~---~--~~ 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: Some questions about menu MetaMegaProtoUser
On Sun, May 24, 2009 at 12:45 AM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: On Sat, May 23, 2009 at 5:54 PM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: On Sat, May 23, 2009 at 4:52 PM, David Pollak feeder.of.the.be...@gmail.com wrote: Getting the secondary menu items: def secondaryMenuItems: Seq[MenuItem] = for { req - S.request.toList line - req.buildMenu.lines kid - line.kids } yield kid While this does get all the current secondary menu items, I need all the current secondary menu items as well as their children (and their children) since I'll be handling the structure client side. I tried various combinations and hacking of the Menu snippet but can't seem to render all the children. Part of the problem is probably that I don't really know the Menu/MenuItem/Loc structure very well and the Scaladocs are.somewhat lacking :-) I'll keep trying to decipher the source to come up with something, but any further insights will be appreciated Each MenuItem has a kids property which is the submenus. You can recurse into the kids on display. The net.liftweb.http.snippet.Menu.scala code has examples of this. I'm on it already ..and seem stuck. I have the following menu structure M1 M1.1 M1.1.1 M1.1.2 M1.2 M2 M2 etc. I can't seem to get all the third level items (M1.1.1, M1.1.2) unless the active page is M1.1. Even if I put in lift:Menu.builder expandAll=true/, they're only shown if I select M1.1. The code above which yields kid, outputs M1.1 and M1.2 when M1 is selected. When looking at the data, at seems like the kid.kids for M1.1 is empty unless I'm on page M1.1. What am I missing? Got some sleep and did a little more tinkering. The following seems to give the expected results val theKids = for { req - S.request.toList loc - req.location.toList m - loc.menu.kids.toList mi - m.makeMenuItem(List(m.loc)) } yield mi /Jeppe --~--~-~--~~~---~--~~ 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: Some questions about menu MetaMegaProtoUser
Thanks for the rapid feedback. A few comments below On Fri, May 22, 2009 at 6:12 PM, David Pollak feeder.of.the.be...@gmail.com wrote: [...] def onLoginPage: Boolean = S.request.flatMap(_.location.map(_.name == Login)) openOr false override def screenWrap: Box[NodeSeq] = Full(if (onLoginPage) lift:surround with=login_template at=contentlift:bind //lift:surround else lift:surround with=default at=contentlift:bind //lift:surround) Ahh didn't realize screenWrap was dynamically evaluated. Nice. Being new to Scala I spent some time trying to decode: def onLoginPage = S.request.flatMap(_.location.map(_.name == Login)) openOr false Am I correct in that it basically evaluates S.request.location.name == Login with proper handling of Empty/Full boxes? If yes, is there a good rule of thumb when to use flatMap/map or do I just need more Scala time before this becomes natural? 2) I would like to have a primary navigation menu at the top, and each primary menu item should have some secondary and tertiary menu items shown at the left. Only the secondary/tertiary items for the currently selected primary menu item should be visible. I believe I can render the primary menu items using a LocGroup, but how do I render the current subitems on the left sidebar? Getting the top level menu items: def topMenuItems: List[MenuItem] = S.request.toList.flatMap(_.buildMenu.lines) Works like a charm. Getting the secondary menu items: def secondaryMenuItems: Seq[MenuItem] = for { req - S.request.toList line - req.buildMenu.lines kid - line.kids } yield kid While this does get all the current secondary menu items, I need all the current secondary menu items as well as their children (and their children) since I'll be handling the structure client side. I tried various combinations and hacking of the Menu snippet but can't seem to render all the children. Part of the problem is probably that I don't really know the Menu/MenuItem/Loc structure very well and the Scaladocs are.somewhat lacking :-) I'll keep trying to decipher the source to come up with something, but any further insights will be appreciated /Jeppe --~--~-~--~~~---~--~~ 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] Problems with redirect after login and protected pages
Hi. I want to protect all pages in the app (except login :-) so if you try to access a page, you get to the login page and after successful login, you get redirected back to the requested page. I'm combining the ideas from http://groups.google.com/group/liftweb/browse_thread/thread/5d724fa1ab66a352/f27134216c81fc91 and http://groups.google.com/group/liftweb/browse_thread/thread/5d724fa1ab66a352/f27134216c81fc91 I'm running 1.1-SNAPSHOT and extending the basic example with the following: Boot.scala val entries = Menu(Loc(Home, List(index), Home, Loc.EarlyResponse( () = Full(RedirectResponse(/user_mgt/login)). filter(ignore = !User.loggedIn_?))) ) :: User.sitemap And User.scala object loginReferer extends SessionVar(/) override def homePage = { var ret = loginReferer.is loginReferer.remove() ret } override def login = { Log.info(Before Logging in S:+S + , loggedIn:+User.loggedIn_? + ref:+loginReferer.is+ S.ref: +S.referer) for (r - S.referer if loginReferer.is == /) loginReferer.set(r) super.login } Here are the issues: - When I hit http://localhost:8080/ I get to the login page ok, after login I get the homepage but with an error: already logged in. Please logout first. - If I try to access another page, I always gets redirected to the home page after login (with the same error) It seems the problems are caused by an empty referrer as seen in the logs below. This makes sense since the original request to / doesn't contain a referer, the redirect doesn't either. So the question is: is there a better way to capture the original page the user was requesting? Since the redirect happens in the EarlyResponse I was wondering if it was possible to just tack it on as a parameter in the RedirectReponse. But is there a better way? /Jeppe Navigate to / INFO - Service request (GET) / took 249 Milliseconds INFO - Before login - ref:/, S.ref: Empty INFO - Service request (GET) /user_mgt/login;jsessionid=e7pkao54lhcm took 156 Milliseconds INFO - Service request (GET) /images/ajax-loader.gif took 0 Milliseconds INFO - Service request (GET) /favicon.ico took 0 Milliseconds Enter login credentials INFO - Before login - ref:/, S.ref: Full(http://localhost:8080/user_mgt/login;jsessionid=e7pkao54lhcm) INFO - Service request (POST) /user_mgt/login took 172 Milliseconds INFO - Service request (GET) /user_mgt/login;jsessionid=e7pkao54lhcm took 0 Milliseconds INFO - Service request (GET) / took 31 Milliseconds --~--~-~--~~~---~--~~ 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: Problems with redirect after login and protected pages
On Sat, May 23, 2009 at 6:22 PM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: Hi. I want to protect all pages in the app (except login :-) so if you try to access a page, you get to the login page and after successful login, you get redirected back to the requested page. I'm combining the ideas from [...] It seems the problems are caused by an empty referrer as seen in the logs below. This makes sense since the original request to / doesn't contain a referer, the redirect doesn't either. So the question is: is there a better way to capture the original page the user was requesting? Since the redirect happens in the EarlyResponse I was wondering if it was possible to just tack it on as a parameter in the RedirectReponse. But is there a better way? Reply to self: This seems to work: override def login = { for {r - S.request ret - r.param(returnTo) if loginReferer.is == /} loginReferer.set(ret) super.login } val loggedIn = Loc.EarlyResponse( () = Full(RedirectResponse(/profile//login?returnTo=+S.uri)).filter(ignore = !User.loggedIn_?)) /Jeppe --~--~-~--~~~---~--~~ 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: Some questions about menu MetaMegaProtoUser
On Sat, May 23, 2009 at 5:54 PM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote: On Sat, May 23, 2009 at 4:52 PM, David Pollak feeder.of.the.be...@gmail.com wrote: Getting the secondary menu items: def secondaryMenuItems: Seq[MenuItem] = for { req - S.request.toList line - req.buildMenu.lines kid - line.kids } yield kid While this does get all the current secondary menu items, I need all the current secondary menu items as well as their children (and their children) since I'll be handling the structure client side. I tried various combinations and hacking of the Menu snippet but can't seem to render all the children. Part of the problem is probably that I don't really know the Menu/MenuItem/Loc structure very well and the Scaladocs are.somewhat lacking :-) I'll keep trying to decipher the source to come up with something, but any further insights will be appreciated Each MenuItem has a kids property which is the submenus. You can recurse into the kids on display. The net.liftweb.http.snippet.Menu.scala code has examples of this. I'm on it already ..and seem stuck. I have the following menu structure M1 M1.1 M1.1.1 M1.1.2 M1.2 M2 M2 etc. I can't seem to get all the third level items (M1.1.1, M1.1.2) unless the active page is M1.1. Even if I put in lift:Menu.builder expandAll=true/, they're only shown if I select M1.1. The code above which yields kid, outputs M1.1 and M1.2 when M1 is selected. When looking at the data, at seems like the kid.kids for M1.1 is empty unless I'm on page M1.1. What am I missing? /Jeppe --~--~-~--~~~---~--~~ 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] Some questions about menu MetaMegaProtoUser
Hi, A newbie running 1-1-SNAPSHOT with a few questions: 1) The entire app should be protected, so any unauthenticated access should show the login page. But I don't want the login page to use the same template as the other user pages. I guess I could override loginMenuLoc, but it would be nice if screenWrap could somehow be specified by Loc. Is this possible? 2) I would like to have a primary navigation menu at the top, and each primary menu item should have some secondary and tertiary menu items shown at the left. Only the secondary/tertiary items for the currently selected primary menu item should be visible. I believe I can render the primary menu items using a LocGroup, but how do I render the current subitems on the left sidebar? /Jeppe --~--~-~--~~~---~--~~ 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] Is Lift the right tool for us?
Hello, I've been lurking on this list for a while and trying out small things with Lift/Scala but thought I would ask the more experienced people around here before digging much deeper. First some background: I've been writing webapps for well over a decade using all kind of tools/languages ranging from Perl/PHP to ASP/.Net/Java (but never Python or Ruby in any significant way). The last 5 years I've mostly focused on Java/JEE. Over time I've, like many of you probably, grown tired of the verbose java syntax and the xml bloat that seems to be required to get any kind of real-life system up and running. I'll soon be starting on a new project where I can choose the entire technology stack and I'm currently evaulating the options. The app will not be a new Web 2.0 social platform used by millions, but rather a more boring business-type app with lots of data entry and interactive reporting :-) But it will have to stable, fast, easy to use (ie will probably need lots of Ajax functionality) as well as integrate with many external parties. One of the primary parameters for choosing a language/framework is speed of development. I know Rails excel in this and may be the sweet spot for an app like ours, but 1) I don't know ruby that well and 2) I've tried RoR and it never really clicked with me while I can easily see how you can create something, fast. Python/Django is another option I'll be looking at. I don't know Lift/Scala either but I've always liked the clean, simple syntax of SML (did a fair share of SML programming back in the CS classes :-), so FP is not uncommon to me (but a bit rusty). And I do like the JVM as platform. So some of the questions I have to the community is this: - How long time does it take for experienced developers to be 1) Productive and 2) Be hyperproducive :-) if we assume we'll start from scratch? - How about new members to a team already knowledgable about Lift/Scala? It's not likely we'll be able to hire lots of experienced Lift developers in the near future :-) - How is the productivity compared to say Rails Django for database driven apps requiring lots of Ajax? - Is Lift ready for production use? While our project is not mission critical requiring 5+ nines, it is not a consumer product either. Downtime will hurt. I've read David's statement that he will do a lot to support production installations, which is a very nice commitment. I know this depends on the app architecture, but would be nice to get some - Any input on Mapper/Record vs JPA for persistence? But basically any experience from using Lift on real, substantial projects is welcome. /Jeppe --~--~-~--~~~---~--~~ 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: Is Lift the right tool for us?
Thanks for the swift reponse. A few comments inline On Tue, Apr 21, 2009 at 7:51 PM, David Pollak feeder.of.the.be...@gmail.com wrote: [...] I don't know Lift/Scala either but I've always liked the clean, simple syntax of SML (did a fair share of SML programming back in the CS classes :-), so FP is not uncommon to me (but a bit rusty). And I do like the JVM as platform. So some of the questions I have to the community is this: - How long time does it take for experienced developers to be 1) Productive and 2) Be hyperproducive :-) if we assume we'll start from scratch? 1 - About a month 2 - About 3 months This is encouraging! - How about new members to a team already knowledgable about Lift/Scala? It's not likely we'll be able to hire lots of experienced Lift developers in the near future :-) The same as for RoR or DJango. Your curve will be similar. New language, new framework. The plus is that you don't have to worry about operations because Lift deploys as a WAR file. Learning Capistrano for Rails is non-trivial. - How is the productivity compared to say Rails Django for database driven apps requiring lots of Ajax? Better. Lift's Ajax and JavaScript abstractions are worlds better that Rails and Django. Lift abstracts away the HTTP request/response cycle. Rails puts you in the heart of it. With Lift, you need not define 3 separate files to handle a single Ajax request. Yes, the Rails way seem a bit cumbersome (but does provide a quick bang for the buck out the box). I've yet to fully understand how this works in Lift (Scala code still doesn't look very clean to me. Maybe that's just an acquired taste?) [...] - Any input on Mapper/Record vs JPA for persistence? Depends on your app. Ok, will get back to this when I've got some more details... /Jeppe --~--~-~--~~~---~--~~ 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: Is Lift the right tool for us?
On Tue, Apr 21, 2009 at 9:01 PM, Charles F. Munat c...@munat.com wrote: Yeah, it's always nice to get some... :-) As a former Rails developer, I'll say this: I don't think I'm yet quite as fast in Lift as I was in Rails, but I'm getting there. A lot of this has had to do with switching mindset from Ruby to a more Java-ish approach. Do you think you'll surpass your Rails speed? If yes, can you explain what elements contribute to this? For you, as a Java developer, I think you'll find the reverse true. With Scala, you can continue to use the same Java libraries and tools that you've used before. I think you'll learn Lift very quickly, and whenever you're stuck, you'll have all that Java background to fall back on. My thoughts exactly :-) I know I will not use Java for this project so I'm willing to take a small hit initially. But staying on the JVM at least provides som firm ground wrt to deployment, ops, runtime, tuning etc. If your project is more than a simple app (as I'm certain it is), I would go with JPA. Record is not ready yet, and Mapper is pretty limited. For example, AFAIK Mapper doesn't do many-to-many associations. I've had a lot of success with JPA/Hibernate, and it's getting pretty solid in Lift now -- there are even Maven archetypes for it. I've yet to dig into Mapper/Record. What are the main benefits of these (besides the obvious simplicity you get when not needing to use JPA)? Lift is more than ready for production use. I've been using it in production for more than six months. Nice! Any numbers you can share (users, tables, data, transactions etc)? /Jeppe --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---