I'm on board with this vision as well. In my current java framework I do 2 distinct passes against any url.
the first pass connects a url to a data model packageMap "^/sports/video/(.*)" "/sports/video/doc.xml" (this is Groovy by the way) That is an xml file that expands into a larger xml file. It has entries like <module name="videofeed" uri="mapped://videofeed" cache="0" /> <module name="channelnews" uri="midgard://cachesvc/api/data/sports/channelnews.xml" cache="0" /> the second pass is to pull the freemaker template viewMap "^/sports/video/.*/" "channels/sports/video" The beauty of this is that the fully formatted XML is available for developers to look at and ops to monitor. Adding new data to the page means adding a 'module' to the doc.xml. Since I'm interested in scale most of the doc.xml is continually regenerated on the server keeping down the number of network calls to the middleware. There are warts here, but this system has served my team well and allows us to onboard new front end guys fast and reuse data heavily. The downside (or upside!) is that the rendering framework has almost no native datastore, it sucks in REST resources and spits our text (HTML, Json, XML etc...). I can imagine something where we do 2 passes on a template and rather then binding the snipped data to the snipped node just build up list of the 'needed data', assemble it, and then pass it to the template. In freemarker it is easy to namespace the XML node to keep things clean, and easy to grab data that exists in any other module. <#list doc.package.latestCoolVideos as video> ${doc.config.sitename} <!-- pull stuff from server config --> <h1>${doc.package.channel.name}</h1> <!-- pull stuff from anywhere in the model --> <dl> ... <!-- common HTML module for showing a list of videos --> <dd class="source">${video.own...@prettyname}</dd> </#list> You can even treat the first pass as a web page itself. Our initial prototype had the 'doc.xml' as a webpage. (the load model function itself can just call out the http server that returns a XML) I know we all hate XML, but there are benefits here. I can easily test the templates by feeding in known XML data and validate the data layer against schemas or any number of XML libraries. So I guess my ask here is to make the 'data' model easily visible without having to open a debugger or mess with logging. The nut I have not been able to crack is how to keep this easy to code and maintain. Now we have another set of files to deal with, a mapping file, a template and data. -Aaron On Thu, May 7, 2009 at 3:45 PM, Charles F. Munat <c...@munat.com> wrote: > > Gotta go to a meeting, but I'll post more later. (I was planning to > anyway.) And I've been working on something along these lines in Lift, > but the need to make a living keeps interfering, dammit. > > Chas. > > Meredith Gregory wrote: > > Chas, > > > > Oooh! i love miracles, as in how we get from 'here' to 'there' is 'and > > then a miracle occurs'. > > > > On the other hand, another way to accomplish a miracle of this type is > > by fiat. There's nothing to prevent lift from providing a code path that > > works like this, along side a code path that includes the current HTML > > nightmare. If there is genuine value in the vision, eventually people > > will start to gravitate to the other way of doing things -- especially, > > if there are some compelling examples that match what they are trying to > > do in their immediate concerns. > > > > Can you lay out the necessary pieces in more detail (for an idiot, like > > myself)? Can we make one sample site that works like this? > > > > Best wishes, > > > > --greg > > > > On Thu, May 7, 2009 at 10:46 AM, Charles F. Munat <c...@munat.com > > <mailto:c...@munat.com>> wrote: > > > > > > Oh, it's a pretty vision. The part that's missing, though, is the > part > > where we get there from here. Still working on that part... > > > > Chas. > > > > David Pollak wrote: > > > > > > > > > On Wed, May 6, 2009 at 7:13 PM, Charles F. Munat <c...@munat.com > > <mailto:c...@munat.com> > > > <mailto:c...@munat.com <mailto:c...@munat.com>>> wrote: > > > > > > > > > Yeah, the whole thing is kind of a joke. > > > > > > Long ago we should have abandoned HTML for XML. The server > > should send > > > the content (data) in one file with full semantic markup. > > Another file > > > should contain a stylesheet that controls full page layout, > > plus vector > > > graphics and raster images with on-the-fly resizing. > > > > > > Page layout should be rule-based and dynamic. The graphic > > designer > > > creates a set of rules, sectioning the content and selecting > > colors, > > > proportioning, alignment, etc. Then the browser reflows and > > updates the > > > view as the user resizes the window or changes type size. > > > > > > As a user, I should be able to grab sections of a page and > > drag them out > > > to become new pages, or pull them back in again. I should be > > able to > > > hide or show any part of a page, or rearrange the parts. I > > should be > > > able to resize type and images so they're clear to me. And > > the site > > > navigation should show up as a "site" toolbar on the browser, > > not in the > > > pages themselves. Chrome missed the boat on this because > > they're too > > > busy thinking of the page as the atomic unit. > > > > > > Now the database developer worries only about the data model. > The > > > application programmer worries only about business logic and > > sending > > > semantically-marked-up data to the browser. The information > > architect > > > worries only about which pages will need what information and > > how the > > > navigation system will work (with navigation delivered as a > > separate XML > > > file), and the graphic designer worries only about the layout > of > > > individual pages, making sure that they look great at any > > resolution, > > > window size/shape, or type size. > > > > > > > > > I love this vision! > > > > > > > > > > > > HTML is a mess, combining semantic information with structural > > > information, metadata, and even some presentation. > > > > > > But I guess we're stuck with it. Under the current > > circumstances, my > > > opinion is that we should do the best we can to separate > > concerns, but > > > not be too totalitarian about it. > > > > > > Chas. > > > > > > > > > Aaron wrote: > > > > Thanks, > > > > > > > > I missed the power of the passing the binding back and > > forth for the > > > > snippet. This gives me something to chew on. > > > > > > > > I understand the bit about 'html not being presentation', > > that is > > > > becoming more prevalent these days. > > > > > > > > So the convention about not putting logic in the template > > is more > > > > important then templates in the controller, and that does > > make a lot > > > > of sence. > > > > > > > > thanks! > > > > > > > > -Aaron > > > > > > > > On May 6, 12:51 pm, David Pollak > > <feeder.of.the.be...@gmail.com <mailto:feeder.of.the.be...@gmail.com > > > > > <mailto:feeder.of.the.be...@gmail.com > > <mailto:feeder.of.the.be...@gmail.com>>> > > > > wrote: > > > >> Aaron, > > > >> > > > >> Short answer: Lift's templating makes it nearly impossible > to > > > put business > > > >> logic into the view, but it is possible to put view logic > > into > > > your Scala > > > >> code. Using Lift's bind'ing mechanism, it's possible to > > > completely separate > > > >> the view logic from the business logic. > > > >> > > > >> Longer answer: > > > >> Lift's templating mechanism is a non-type-safe interface > > between > > > XHTML > > > >> template files and Scala code. Lift finds tags of the > format > > > <lift:xxx> and > > > >> uses xxx to look up a snippet which generates dynamic > > content. > > > Lift looks > > > >> up the snippets in a number of ways including "by > > convention" (using > > > >> reflection to look for classes and methods that match the > > > snippet name) and > > > >> by registering PartialFunctions as a lookup mechanism for > > snippets. > > > >> Snippets may also be registered on a page-by-page basis > using > > > SiteMap. > > > >> > > > >> "by-convention" snippets may be of two forms: methods > > that take no > > > >> parameters (e.g., HelloWorld.howdy) and methods that take > the > > > snippet > > > >> invocation body as a parameter. All other snippets must > take > > > the snippet > > > >> invocation body as a parameter. > > > >> > > > >> If we have a case where the snippet takes the invocation > > body is a > > > >> parameter, we can bind dynamically generated content to > view > > > information. > > > >> For example: > > > >> > > > >> <lift:HelloWorld.howdy> > > > >> <span>Welcome to helloworld at <b:time/></span> > > > >> </lift:HelloWorld> > > > >> > > > >> The snippet would look like: > > > >> > > > >> class HelloWorld { > > > >> def howdy(xhtml: NodeSeq): NodeSeq = Helpers.bind("b", > > xhtml, > > > "time" -> > > > >> (new java.util.Date).toString) > > > >> > > > >> } > > > >> > > > >> In this case, we have complete view/logic separation. > > The body > > > of the > > > >> snippet tag (in this case <span>Welcome to helloworld at > > > <b:time/></span>) > > > >> is passed to the snippet and the snippet merely binds the > > > dynamic content to > > > >> the view template. In this way, you are guaranteed that > > there's > > > no logic in > > > >> the view and if you follow good practices in terms of > > binding, > > > there will be > > > >> no view code in your business logic. > > > >> > > > >> So, when does it *not* make sense to put all your view > > code in > > > the view > > > >> templates? > > > >> > > > >> - When I do quick prototyping, I put view code in my > > business > > > logic. > > > >> There is an extra step to do best practices binding > > and when > > > I'm knocking > > > >> something together, I find that it's quicker to use XML > > > literals in my Scala > > > >> code. > > > >> - Some of Lift's "scafolding" code (e.g., ProtoUser, > > CRUDify) has > > > >> embedded view code. This is so that all the code is > > > self-contained. I view > > > >> ProtoUser and CRUDify as tools for prototyping, not > > for long > > > term production > > > >> code. I expect that as projects expand from 1 to 3 > people > > > putting together > > > >> a proof of concept to a team with clear deliniation of > > tasks > > > that these > > > >> traits will be extracted from the code and that the > > view code > > > will be > > > >> extracted to templates. > > > >> - Sometimes HTML is not view code. In Buy A Feature's > > game > > > play grid, > > > >> there are a lot of HTML literals in the comet code. > These > > > literals are > > > >> things like <span id={....}>{content}</span>. The id > > of the > > > span is > > > >> important because it relates to the place on the game > grid > > > where the cell > > > >> goes. The fact that it's an HTML tag is overshadowed > > by the > > > fact that it's > > > >> a small nugget of something that needs to be put in a > > > particular place on > > > >> the browser page. The actually layout of the browser > > page is > > > controlled by > > > >> the CSS. One might argue that all the data should go > from > > > the server app to > > > >> the browser via JSON and then the update should take > > place in > > > JavaScript. > > > >> We did this for Prune the Product Tree (another > Innovation > > > Game.) Turns out > > > >> that JavaScript is not type-safe which led to a bunch > of > > > errors. Further, > > > >> generating view code in JavaScript is error-prone (what > do > > > with HTML > > > >> encode?) and it's logic anyway. So, having the logic > > stick > > > in on the server > > > >> in a higher performance, strongly typed language is a > > better > > > choice. > > > >> > > > >> I've revised the archetypes to use better practices. > Also, > > > please look at > > > >> the Getting Started guide. The ToDo example uses all > > binding. > > > >> Additionally, the sites/example code is almost all > view/logic > > > separated > > > >> (except in cases demonstrating that view code can appear > > in the > > > Scala). > > > >> > > > >> Thanks, > > > >> > > > >> David > > > >> > > > >> > > > >> > > > >> On Wed, May 6, 2009 at 8:11 AM, Aaron > > <aarondh...@gmail.com <mailto:aarondh...@gmail.com> > > > <mailto:aarondh...@gmail.com <mailto:aarondh...@gmail.com>>> > > wrote: > > > >> > > > >>> So far I'm impressed with Lift and have gone through the > > > toy-app stage > > > >>> of experimenting. I have my own framework in production > > > powering large > > > >>> scale sites likehttp://www.comcast.netand real > > experience with > > > >>> Django. > > > >>> I'm a little sketchy on the thinking behind this type of > > > display logic > > > >>> deep in the code. For example > > > >>> Snippet: > > > >>> class HelloWorld { > > > >>> def howdy: NodeSeq = <span>Welcome to helloworld at {new > > > >>> java.util.Date}</span> > > > >>> } > > > >>> In Model: > > > >>> override def loginXhtml = > > > >>> <lift:surround with="default" at="content"> > > > >>> { super.loginXhtml } > > > >>> </lift:surround> > > > >>> In real applications are people delegating this type of > > > rendering to > > > >>> template files? In a freemarker world I have template > > macros > > > >>> (snippets) that would look like > > > >>> <#macro helloWord> > > > >>> <span>Welcome to helloworld at > > ${exec.RunCustomDateFunction} > > > >>> </#macro> > > > >>> or server code that would look like > > > >>> (In horrible python/java psudocode) > > > >>> function(){ > > > >>> render_and_return(template('helloWorld', {date: new > > > >>> java.util.Date} ) > > > >>> } > > > >>> I have strict rules about who gets to edit templates and > who > > > gets to > > > >>> edit server code. Template code should NEVER affect > server > > > profiles > > > >>> (of course it can with bad javascript/ajax) and server > > code should > > > >>> never have display data. > > > >>> (In my world...) Display / presentation changes should > > NOT require > > > >>> a .war deployment > > > >>> I'm basically asking for other people's thoughts in this > > > direction. I > > > >>> have multiple HTML/CSS/JS experts and multiple Server > > devs. Is > > > this > > > >>> something that will 'people scale' in the way I need it > to? > > > >>> We currently have Groovy embedded in places and were > > looking at > > > >>> Grails. The problem is that it is groovy is not as fast > to > > > code in as > > > >>> Ruby and Grails is not much easier to deploy then a .war > > > (because we > > > >>> have automation). Lift solves some real problems for us > > and Scala > > > >>> seems like a language with real benefits. > > > >>> Besides SpringSource is offering Grails support so we > don't > > > want to be > > > >>> too mainstream ;) > > > >>> Thanks, > > > >>> -Aaron > > > >>> http://www.aaronheld.com > > > >> -- > > > >> Lift, the simply functional web > > frameworkhttp://liftweb.net <http://liftweb.net> > > > <http://liftweb.net> > > > >> Beginning Scalahttp://www.apress.com/book/view/1430219890 > > <http://www.apress.com/book/view/1430219890> > > > <http://www.apress.com/book/view/1430219890> > > > >> Follow me:http://twitter.com/dpp > > > >> Git some:http://github.com/dpp > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > 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 > > > > > > > > > > > > > > > > > > > -- > > L.G. Meredith > > Managing Partner > > Biosimilarity LLC > > 1219 NW 83rd St > > Seattle, WA 98117 > > > > +1 206.650.3740 > > > > http://biosimilarity.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 -~----------~----~----~----~------~----~------~--~---