[parenscript-devel] best practice for developing a JS-only HTML5 webapp?

Kelly McDonald kelly at fammcdonald.net
Sat Jan 8 23:57:30 UTC 2011


Let me describe my setup to you,

I have written a product (currently not released and currently only on
mac) that combines a web-browser with a webserver. The webserver
accepts a call containing the javascript you want to evaluate and
returns the evaluation of it.

This works very well with parenscript. I have written a macro that
essentially 1) translates the Parenscript code to JS 2) sends this
stuff to the web-browser and 3) returns the evaluated code

Because I am working with cappuccino, and that uses 'objective-j', my
macro name is 'oj'

so if I evaluate from lisp

(oj (+ 1 2))

I get '3' back in my repl (no going to the browser, but it was
actually computed in the browser)

likewise, when I have my js application loaded in the browser I can do this:

(set-frame emailtable 20 20 330 240)
(set-frame subject 20 20 350 32)
(set-frame body 20 20 350 190)

(next-to emailtable subject)
(below subject body)
(below emailtable reset-email-button)
(next-to reset-email-button save-email-button))

the macro runs a bunch of parenscript macros to generate the stuff
that plays nice with the cappuccino framework, which gets evaluated in
the browser.

The effect is immediate - Lets say I change the size of emailtable (in
lisp), and re-evaluate it ( in emacs C-M-x), everything adjusts on the
screen of the browser - no reload.

This way, I get the stuff that we all love about lisp when I am
working with javascript.

Now there are times when I need to reload the whole enchelada (sp??) -
for this I wrote a maco that steps through all of the 'oj' macros and
sends it a peice at a time to the browser. (otherwise I'd send it 90k
of stuff all in one request, which currently breaks somewhere)

Finally, I have one more macro that I can wrap all of the other 'oj'
macros with that will write it to a file if I want to push it to an
external website.

If you are using mac and want to try my little browser, please let me
know. Even though I consider it 'pre-alpha' it is really quite useful.

Hope this helps,

On Sat, Jan 8, 2011 at 4:44 PM, Jon Rosebaugh <chairos at gmail.com> wrote:
> As I said in the subject, I'm working on a JS-only (no server-side
> code) HTML5 webapp in Parenscript with jQuery. I have extensive JS
> experience, but I'm really new to Common Lisp.
> I wanted a setup where I could edit a Parenscript file, hit save, then
> hit refresh in my browser and immediately see the new code, just as if
> I were working in Javascript. I built a little server using
> Hunchentoot and cl-who that runs ps-compile-file on my parenscript
> source file as needed. This works fairly well, but maybe is not the
> best way to accomplish this.
> However, there's a problem; I wanted to use parenscript functions
> without the namespace, so I defined a package in serve.lisp that uses
> parenscript, then put (in-package :innkeeper) at the top of my
> parenscript file. This doesn't work properly in the 2.2 release of
> Parenscript (which is what Quicklisp provides). It _does_ work in the
> git repo version (as of commit
> 0e01e555f404a7dcb8befb7587288c38abf526c2), but it's annoying to not be
> able to use Quicklisp for everything.
> Once I have a release version I'll want to come up with some lisp
> program that compiles the parenscript to javascript, minifies it, and
> sticks it in an also-minified html file from cl-who, so the whole
> thing is compiled down to a single file. I'd appreciate any
> best-practice tips on that too.
> Just in case my description was unclear, here's what I think are the
> relevant bits. If needed, I can provide the entire files off-list.
> ; relevant bits of serve.lisp
> (defpackage "INNKEEPER"
>  (:export :start-innserver :stop-innserver))
> (in-package :innkeeper)
> (define-easy-handler (jsgen :uri "/innkeeper.js") ()
>  (setf (content-type*) "application/javascript")
>  (ps-compile-file "/Users/jon/code/innkeeper/innkeeper.lisp"))
> ; beginning (and a few representative lines) of innkeeper.lisp
> (in-package :innkeeper)
> (defmacro immediate (&body body)
>  `((lambda () , at body)))
> (var *inn*
>     (create
>             setup (lambda () ((@ ($ "#top-tabs") tabs)))))
> (j-query #'(@ *inn* setup))
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel

More information about the parenscript-devel mailing list