Cody, Thanks for such a thoughtful set of feedback.
On Thu, Dec 24, 2009 at 1:11 PM, cody koeninger <c...@koeninger.org> wrote: > We recently implemented a small, mostly static content site (http:// > www.goldenfrog.com/) using Lift. Thought I'd offer up a postmortem on > what worked well and what didn't, in case it's useful to anyone > considering Lift. We're a small team with essentially no prior Scala > experience, so take this with a grain of salt & feel free to offer > suggestions. > > The good: > > We went with Lift mainly because we wanted: 1. clean separation of > code from html; 2. easy localization. With a few minor caveats (see > below), we got that. > > An html designer was able to work on templates & commit directly to > our repo without touching any scala code. When he broke things, it > was usually immediately obvious because the xml stopped parsing > correctly and the page would no longer render (even though it usually > took a programmer to interpret the stacktrace & fix the xml). > > Regarding localization, the use of separate templates (instead of e.g. > java properties file references for every single sentence) was a big > help. Because everything in templates is well-formed xml, I was able > to write less than 100 lines of code to automatically extract > translatable text and generate a translated version of all the > templates. This is done during build, so essentially duplicate html > doesn't get into our repo, until some point when translated templates > need to actually be structurally different. > > The bad: > > Dreamweaver doesn't deal with head merge, it will automatically move > the head tags outside of the lift:surround. Not really a lift issue. > Is there a way we could do something to make Lift stuff more DW friendly? > > PCDataXmlParser converts entity references to actual utf-8 > characters. This means templates with entity references won't round- > trip correctly through view source, nor through localization > properties files / gettext files. > Hmmm... is this worth a flag someplace to disable this behavior? > > Jetty seems to do questionable things with filehandles, opening > multiple copies of the same template file and keeping them open too > long. Setting ulimit "fixes" the issue of "Too many open files" > exceptions & failed requests, but it still seems like at most > templates should need 1 access to check mtime. Not really a lift > issue, and not a deal breaker for us to switch to a different servlet > container, but I am curious to see what the eventual solution for > comet performance is. > If you can put together a reproducible case on this, we'll see what we can do to close stuff that Jetty hands us more explicitly. > > Lift doesn't seem to have any central place to handle URL issues > related to servlet context paths and domains / subdomains. We're > currently running lift as a root servlet to avoid forcing context path > to be visible in urls; this is fine for us but I can see it being > useful for lift to know that the frontend proxy is taking care of > mapping foo.com/ to the context /foo-lift-app/, instead of always > adding the context path to urls. Similarly, we're running multiple > subdomains from a single lift instance, because it's all basically > common code and templates. The way we ended up making this work was > to have 1 folder per subdomain, and subclass Link so that it knows how > to createLink correctly based on headers the frontend is sending; e.g. > the link for http://foo.bar.com/baz is put into the sitemap as / > foo.bar/baz and will be rendered as /baz if the request is already in > the foo subdomain, or fully qualified http://foo.bar.com/baz > otherwise. In one sense, it was nice that we were even able to do > this without modifying Lift. However, we already ran into the issue > of default form redirects wanting to go to /foo.bar/baz, not just / > baz, and there doesnt seem to be a clean place to handle that. > Yeah. I agree this is a problem. I opened a ticket on it forever ago: http://github.com/dpp/liftweb/issues#issue/68 If you have any thoughts on how to deal with this, input would help formulate a solution. > > The public face of 1.0 vs snapshot could be handled a little better, > in terms of website / liftbook / documentation. If the intention is > for all users to track snapshot for now, that should be made explicit > and the docs updated. > Yep. > > The ugly: > > There are aspects of the API that are frankly quite difficult for > developers to take seriously - > "object User extends User with MetaMegaProtoUser[User]" is a common > whipping boy around the office, and leads to jokes about giant robots. > I guess I shouldn't name things when I'm in a goofy mood. > > Similarly, there are a number of places that seem to force syntactic > overhead instead of catering to concise default usage, eg the first > time I saw the liftbook example of > > case RewriteRequest( > ParsePath(List("account",acctName),_,_,_),_,_) => > RewriteResponse("viewAcct" :: Nil, Map("name" -> acctName)) > > I thought how often are you actually going to fill in those > underscores? This particular construct was the subject of a lot of debate, both on-list and with some folks on a given project. I think the best way to deal with it is to have a bunch of helper objects w/unapply to do better matching. > One of the things we did as part of our link subclass > was an implicit conversion to allow writing links in the sitemap as > "foo.bar/baz/quux/*" rather than ("foo.bar" :: "baz" :: "quux" :: Nil) > -> true. I don't know if that's bad style or not, but it certainly > makes the sitemap more scannable as a list of urls. I know > conciseness isn't this framework's top priority, but it seems like > some judicious use of implicits would help. > Yep. If you care to contribute your various implicits and object.unapply stuff into Lift, we'd love to have them. > > > Thanks to the devs for writing lift, and like I said, please offer any > suggestions or counterpoints. > These issues were specific, well reasoned and actionable (well, except for the MetaMegaUsertron issue... ;-) ) This is the kind of feedback that helps make Lift better. Thanks, David PS -- Concise code is a goal of Lift. > > -- > > 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<liftweb%2bunsubscr...@googlegroups.com> > . > For more options, visit this group at > http://groups.google.com/group/liftweb?hl=en. > > > -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://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.