Permalink
Browse files

importing the current leftparen

  • Loading branch information...
vegashacker committed Sep 25, 2008
1 parent d7dab74 commit f8a6c87f7df3a64d382cf710af4b38b2048d5f1e
Showing with 3,907 additions and 0 deletions.
  1. +4 −0 bootstrap.scm
  2. +74 −0 closures.scm
  3. +16 −0 compute.scm
  4. +16 −0 conventions.txt
  5. +127 −0 doc.txt
  6. +280 −0 form.scm
  7. +161 −0 generate-lib.scm
  8. +8 −0 info.ss
  9. +37 −0 js.scm
  10. +11 −0 js/.svn/all-wcprops
  11. +40 −0 js/.svn/entries
  12. +1 −0 js/.svn/format
  13. +60 −0 js/.svn/text-base/leftparen.js.svn-base
  14. +60 −0 js/leftparen.js
  15. +41 −0 layering-example.scm
  16. +238 −0 leftparen.scm
  17. +23 −0 lib-bindings.scm
  18. +15 −0 lib-export.scm
  19. +22 −0 loc.scm
  20. +6 −0 log.scm
  21. +146 −0 page.scm
  22. +100 −0 profiler.scm
  23. +132 −0 record.scm
  24. +510 −0 repository.scm
  25. +455 −0 scribble.css
  26. +129 −0 session.scm
  27. +58 −0 settings.scm
  28. +77 −0 task-queue.scm
  29. +65 −0 time.scm
  30. +251 −0 user.scm
  31. +565 −0 util.scm
  32. +32 −0 validate.scm
  33. +147 −0 web-support.scm
View
@@ -0,0 +1,4 @@
+#lang scheme/base
+
+(require "generate-lib.scm")
+(generate (current-command-line-arguments))
View
@@ -0,0 +1,74 @@
+#lang scheme/base
+
+(require (file "util.scm")
+ (planet "web.scm" ("soegaard" "web.plt" 2 1))
+ (file "web-support.scm")
+ (file "settings.scm"))
+
+(provide add-closure!
+ call-closure
+ closure-key->url
+ make-closure-key
+ body-as-closure-key
+ body-as-url
+ handle-closure-in-req
+ num-closures-in-memory
+ )
+
+(define-syntax body-as-closure-key
+ (syntax-rules ()
+ ((_ (req-identifier) body ...)
+ (add-closure! (lambda (req-identifier) body ...)))
+ ((_ (req-identifier key-identifier) body ...)
+ (let ((key-identifier (make-closure-key)))
+ (add-closure! #:key key-identifier
+ (lambda (req-identifier) body ...))))))
+
+;;
+;; body-as-url
+;;
+;; (body-as-url (req) body ...)
+;; or
+;; (body-as-url (req fn-key) body ...)
+;; In the latter form, fn-key is the key that will be used to map to body.
+;; This provides a way for the developer to reuse fns in certain situations.
+;;
+(define-syntax body-as-url
+ (syntax-rules ()
+ ((_ (identifiers ...) body ...)
+ (closure-key->url (body-as-closure-key (identifiers ...) body ...)))))
+
+(define (closure-key->url clos-key)
+ (format "~A?~A=~A"
+ (setting *WEB_APP_URL*)
+ (setting *CLOSURE_URL_KEY*)
+ clos-key))
+
+(define-syntax handle-closure-in-req
+ (syntax-rules ()
+ ((_ req no-closure-body ...)
+ (let ((url-key (setting *CLOSURE_URL_KEY*))
+ (binds (request-bindings req)))
+ (if (exists-binding? url-key binds)
+ (call-closure (extract-binding/single url-key binds) req)
+ (begin no-closure-body ...))))))
+
+(define CLOSURES (make-hash))
+
+(define (make-closure-key)
+ (random-key-string 20))
+
+;; returns the key
+(define (add-closure! clos #:key (key #f))
+ (let ((key (or key (make-closure-key))))
+ (hash-set! CLOSURES key clos)
+ key))
+
+(define (call-closure key req)
+ ((hash-ref CLOSURES key (lambda ()
+ (lambda (req)
+ (format "Expired or missing function '~A'." key))))
+ req))
+
+(define (num-closures-in-memory)
+ (hash-count CLOSURES))
View
@@ -0,0 +1,16 @@
+#lang scheme/base
+
+;; record computations
+
+(require "record.scm"
+ "util.scm")
+
+(provide
+ sum-recs
+ )
+
+(define (sum-recs recs prop-to-sum)
+ (foldl (lambda (rec acc)
+ (+ acc (rec-prop rec prop-to-sum)))
+ 0
+ recs))
View
@@ -0,0 +1,16 @@
+LP conventions:
+
+* When a macro introduces new variable identifiers which is available
+in a "body" of the form, we surround the identifiers with parens, and
+position them just before the body. For example,
+
+(sessioned-response (sesh req) body-goes-here-and-may-refer-to-sesh-and-req ...)
+
+Here sesh and req are both identifiers (not expressions bound in the
+enclosing environment. The inspiration for this convention is lambda,
+in which, in most cases at least, the first argument is a list of
+identifiers.
+
+* When a function takes a single xexpr we often use the identifier
+ "body". But if the function expects an arbitrary number of xexpr,
+ then we encourage the use of the identifier "bodies".
View
127 doc.txt
@@ -0,0 +1,127 @@
+
+LeftParen 1.2 Documentation
+
+Website: http://leftparen.com
+
+LeftParen is a framework for quickly creating web apps. It runs on
+PLT Scheme v3.99.0.23 or greater.
+
+1. Installing LeftParen
+
+You’ll need PLT Scheme v3.99.0.23 or greater installed. Note that this
+version is not officially released yet, so you you’ll need to get it from
+the pre-release
+download page.
+
+Make sure that mzscheme is in your path. You should be ready
+to go if you can do this:
+
+% mzscheme
+Welcome to MzScheme v3.99...
+>
+
+Installing LeftParen proper is done with a PLaneT
+require. See Tutorials for an example of this. When you
+first issue one of these require commands, you’ll
+automatically download the LeftParen files to your local PLaneT cache.
+This can sometimes take a few moments, so be prepared to wait a bit.
+
+2. Tutorials
+
+
+
+2.1. Hello, World
+
+We’re going to make a project called hello-world. Change to the
+directory that you’d like to make the project in. Then issue
+
+% mzscheme -e '(require (planet "bootstrap.scm" ("vegashacker" "leftparen.plt" 1 2)))' project hello-world
+
+This will create a hello-world project directory for you. In
+this directory you’ll find the script directory, which contains
+some useful scripts. All paths are relative to this project
+directory, so when calling scripts, you always want to be at the
+project root.
+
+% cd hello-world
+
+We need to make the scripts executable:
+
+% chmod u+x script/*
+
+LeftParen has automatically generated everything we need to run our
+web app—we just need to start the server (again, you should be at the project root directory):
+
+% ./script/server
+Web server started on port 8765
+Listening on IP address: 127.0.0.1
+Type stop to stop the server and exit
+Type restart to restart the server
+
+Point your browser to http://localhost:8765 and you should see a familiar greeting:
+
+Hello, World!
+
+2.2. Blogerton the Blog
+
+Now let’s try implementing the true "hello world" of web apps—a
+blog. First, execute the following commands from the directory in
+which you want to create your project directory:
+
+% mzscheme -e '(require (planet "bootstrap.scm" ("vegashacker" "leftparen.plt" 1 2)))' project blogerton
+% cd blogerton
+% chmod u+x script/*
+
+2.2.1. Changes to app.scm
+
+We need to register a couple of pages in our app. The
+index-page was already set up for you, but you’ll need to add
+a page to create new posts, and one to view them. Make the define-app call look like this:
+
+ (define-app my-app
+ (index-page (url "/"))
+ (create-post-page (url "/post"))
+ (view-post-page (url "/view/" (string-arg))))
+
+2.2.2. Changes to main.scm
+
+Now we need to define those pages that we declared in app.scm.
+
+ (define-page (index-page req)
+ `(h1 "Blogerton")
+ `(p ,(web-link "Create a new post" (page-url create-post-page)))
+ `(ul ,@(map (lambda (p) `(li ,(paint-blog-post p)))
+ (load-where '((type . blog-post))
+ #:sort-by 'created-at #:compare >))))
+
+ (define-page (create-post-page req)
+ (form '((title "Title" text) (body "Body" long-text))
+ #:init '((type . blog-post))
+ #:on-done (lambda (post) (redirect-to-page view-post-page (rec-id post)))))
+
+ (define-page (view-post-page req post-id)
+ (paint-blog-post (load-rec post-id #:ensure '((type . blog-post)))))
+
+ (define (paint-blog-post post)
+ `(div (h2 ,(rec-prop post 'title))
+ (p ,(rec-prop post 'body))))
+
+2.2.3. Launch Blogerton
+
+You’re ready for launch. Start the server with
+
+% ./script/server
+
+and you should have a basic blogging app, with persistent data, in 19 lines of code.
+
+3. About/Acknowledgements
+
+LeftParen was written by Rob Hunter,
+but it builds heavily on (and, in fact, often directly incorporates) the work of
+Untyped
+(instaservlet
+and
+dispatch),
+Jens Axel Soegaard
+(web.plt),
+and of course, PLT Scheme.
Oops, something went wrong.

0 comments on commit f8a6c87

Please sign in to comment.