Index: doc/howto.txt ================================================================== --- doc/howto.txt +++ doc/howto.txt @@ -1,32 +1,35 @@ Gotchas! ======= -1. All items for a page *must* be part of a list! +All items for a page *must* be part of a list! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OK: (list (function1 param1)(function2 param2)) NOT OK: (begin (function1 param1)(function2 param2)) Various components -================== +~~~~~~~~~~~~~~~~~~ The URL: http://the.domain.com/pagename/p1/p2/p3?param1=value1 (s:get-page-params) => '("p1" "p2") -====================================================================== -1. Create a link. +Create a link. +~~~~~~~~~~~~~~ (s:null "[" (s:a name 'href (s:link-to (string-append "location/" (string-intersperse p "/") ""))) "] "))) -====================================================================== -2. Call current page with new param + + +Call current page with new param +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In view.scm: (s:center "[" (s:a 'href (s:link-to "polls" 'id @@ -38,42 +41,46 @@ In control.scm: (let ((poll-id (s:get-param 'id))) ;; do stuff based on poll-id -====================================================================== -3. Call an action on a specific page + +Call an action on a specific page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (s:a 'href (s:link-to "polls" 'id (poll:poll 'get 'id) 'action "poll.edit") "Suggest changes to this poll") NOT TRUE! This calls fuction poll.edit (should be in control.scm). Parameter set is 'id to a poll num. -====================================================================== -4. A complex link example + +A complex link example +~~~~~~~~~~~~~~~~~~~~~~ (s:a "Reply" 'href (s:link-to (s:current-page) 'action "discussion.reply" ;; . 'reply_to (number->string (hash-table-ref row 'posts.id)) 'id (s:get "discussion.parent_object_id")) "reply") ;; use (s:get-param to get the 'id, or 'reply_to values -====================================================================== -5. Get and set a session var + +Get and set a session var +~~~~~~~~~~~~~~~~~~~~~~~~~ (s:session-var-get "keyname") (s:session-var-set! "keyname" "value") 5.1 Page local vars (s:set! key val) (s:get key) -====================================================================== -6. make a selection drop down + +make a selection drop down +~~~~~~~~~~~~~~~~~~~~~~~~~~ In view.scm: (s:select '(("World" 0)("Country" 1)("State" 2)("Town/City" 3)) 'name 'scope) @@ -80,12 +87,13 @@ In control.scm: (let ((scope (s:get-input 'scope))) .... -====================================================================== -7. Simple error reporting + +Simple error reporting +~~~~~~~~~~~~~~~~~~~~~~ In control.scm: (s:set-err "You must provide an email address") In view.scm: @@ -92,12 +100,26 @@ (s:get-err s:err-font) Or: (s:get-err (lambda (x)(s:err-font x (s:br)))) -====================================================================== -8. Misc useful stuff + +Sharing data between pages +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +NOTE: This data is *not* preserved between cgi calls. + +;; In first page called +(s:shared-set! "somekey" somevalue) + +;; In a page called later +(let ((dat (s:shared-get "somekey"))) + ( .... )) + + +Misc useful stuff +~~~~~~~~~~~~~~~~~ i. Lazy/safe string->number (s:any->number val) @@ -107,12 +129,13 @@ iii. string to number for pgint (s:any->pgint val) -====================================================================== -9. Forms and input + +Forms and input +~~~~~~~~~~~~~~~ (s:form 'action "login.login" 'method "post" (s:input-preserve 'type "text" 'name "email-address" 'size "16" 'maxlength "30") (s:input 'type "submit" 'name "form-name" 'value "login")) @@ -119,8 +142,5 @@ (s:get-input 'email-address) To preserve the input simply do a set of the value on the 'name field: (s:set! "email-address" "matt@kiatoa.com") -====================================================================== -10. - Index: setup.scm ================================================================== --- setup.scm +++ setup.scm @@ -85,19 +85,31 @@ ;; utility to get all vars as hash table (define (s:session-get-sessionvars) (sdat-get-sessionvars s:session)) ;; inputs +;; (define (s:get-input key) (session:get-input s:session key)) (define (s:load-model model) (session:load-model s:session model)) (define (s:model-path model) (session:model-path s:session model)) +;; share data between pages calls +;; +(define (s:shared-hash) + (sdat-get-shared-hash s:session)) + +(define (s:shared-set! key val) + (hash-table-set! (sdat-get-shared-hash s:session) key val)) + +(define (s:shared-get key) + (hash-table-ref (sdat-get-shared-hash s:session) key)) + ;; http://foo.bar.com/pagename/p1/p2 => '("p1" "p2") ;; (define (s:get-page-params) (sdat-get-page-params s:session)) Index: sugar.scm ================================================================== --- sugar.scm +++ sugar.scm @@ -22,18 +22,83 @@ ;; (define-syntax s:if-test ;; (syntax-rules () ;; [(_ s x) (if (string=? "yep" s) x (list "s:if not"))] ;; [(_ s x y) (if (string=? "yep" s) x y)])) - -(define-macro (s:if-param varname . dat) - (match dat - (() '()) - ((a) `(if (s:get ,varname) ,a '())) - ((a b) `(if (s:get ,varname) ,a ,b)))) - -(define-macro (s:if-sessionvar varname . dat) - (match dat - (() '()) - ((a) `(if (s:session-var-get ,varname) ,a '())) - ((a b) `(if (s:session-var-get ,varname) ,a ,b)))) - +;; Some of these routines use: +;; +;; http://www.cs.toronto.edu/~gfb/scheme/simple-macros.html +;; +;; Syntax for defining macros in a simple style similar to function definiton, +;; when there is a single pattern for the argument list and there are no keywords. +;; +;; (define-simple-syntax (name arg ...) body ...) +;; + +(define-syntax define-simple-syntax + (syntax-rules () + ((_ (name arg ...) body ...) + (define-syntax name (syntax-rules () ((name arg ...) (begin body ...))))))) + +;;====================================================================== +;; syntatic sugar items +;;====================================================================== + +;; We often seem to want to include stuff if a conditional is met +;; otherwise not include it. This routine makes that slightly cleaner +;; since using a pure if results in # objects. (admittedly they +;; should be ignored but this is slightly cleaner I think). +;; +;; NOTE: This has to be a macro or the true clause will be evaluated +;; whether "a" is true or false + +;; If a is true return b, else return '() +(define-simple-syntax (s:if a b) + (if a b '())) + + +;; Using the Simple-Syntax System +;; +;; The syntax for defining macros in this system is similar to that for defining functions. In fact if the macro has a fixed number of arguments the syntax is identical. For example: +;; +;; ; Define a simple macro to add a value to a variable. +;; ; +;; (define-simple-syntax (+= variable value) +;; (set! variable (+ variable value))) +;; +;; ; Use it. +;; ; +;; (define v 2) +;; (+= v 7) +;; v ; => 9 +;; +;; For a fixed number of arguments followed by an unknown number of arguments we use ... after a single argument to represent the unknown number (possibly zero) of arguments. For example, let's revise our definition of += to allow zero or more values to be added: +;; +;; ; Define a simple macro to add a zero or more values to a variable +;; ; +;; (define-simple-syntax (+= variable value ...) +;; (set! variable (+ variable value ...))) +;; +;; ; Use it +;; ; +;; (define v 2) +;; (+= v 7) +;; v ; => 9 +;; (+= v 3 4) +;; v ; => 16 +;; (+= v) +;; v ; => 16 +;; + + +;; (define-macro (s:if-param varname . dat) +;; (match dat +;; (() '()) +;; ((a) `(if (s:get ,varname) ,a '())) +;; ((a b) `(if (s:get ,varname) ,a ,b)))) +;; +;; (define-macro (s:if-sessionvar varname . dat) +;; (match dat +;; (() '()) +;; ((a) `(if (s:session-var-get ,varname) ,a '())) +;; ((a b) `(if (s:session-var-get ,varname) ,a ,b)))) +;;