Overview
Comment:Reworked howto. Added s:shared-hash, added s:if to sugar.scm
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | selfcontained
Files: files | file ages | folders
SHA1: 9cde8a89e86d4ba210d63cb5c2fc50879dfea43e
User & Date: matt on 2013-09-22 17:35:20
Other Links: branch diff | manifest | tags
Context
2013-10-26
04:26
Added some sugar; a default to s:shared-get and s:label check-in: 53f9eeed61 user: matt tags: selfcontained
2013-09-22
17:35
Reworked howto. Added s:shared-hash, added s:if to sugar.scm check-in: 9cde8a89e8 user: matt tags: selfcontained
05:25
Added some document snippets. Improved page handling/loading logic to provide message if page not found and option to not compile pages check-in: 886293086d user: matt tags: selfcontained
Changes

Modified doc/howto.txt from [cc3668b264] to [9ad6dc4f19].

1
2
3
4

5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21

22
23
24
25
26

27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97













98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
Gotchas!
=======

1. 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.


(s:null "[" (s:a name 'href 
               (s:link-to (string-append "location/" (string-intersperse p "/") ""))) "] ")))

======================================================================

2. Call current page with new param


In view.scm:

 (s:center "[" (s:a 'href (s:link-to "polls"
                           'id
                            (begin
                              (poll:poll 'fill-polls)
                              (poll:poll 'get-next-poll)))
                          "Go to the next poll")  "]")

In control.scm:

(let ((poll-id (s:get-param 'id)))
 ;; do stuff based on poll-id

======================================================================
3. 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


(s:a "Reply" 'href (s:link-to (s:current-page) 
	           'action "discussion.reply" ;; <page>.<action>
	           '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


(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


In view.scm: 

(s:select '(("World" 0)("Country" 1)("State" 2)("Town/City" 3)) 'name 'scope)

In control.scm:

(let ((scope (s:get-input 'scope)))
  ....

======================================================================
7. Simple error reporting


In control.scm:
(s:set-err "You must provide an email address")

In view.scm:
(s:get-err s:err-font)

Or:
(s:get-err (lambda (x)(s:err-font x (s:br))))

======================================================================













8. Misc useful stuff


  i. Lazy/safe string->number 

(s:any->number val)

  ii. Random string

(session:make-rand-string len)

 iii. string to number for pgint
 
(s:any->pgint val)

======================================================================
9. 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"))

(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. 




|
>






<
>








<
|
>




|
>
|
>















|
|
>







|
|
>








|
|
>









|
|
>










|
|
>










|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>













|
|
>










<
<
<
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146



Gotchas!
=======

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")



Create a link.
~~~~~~~~~~~~~~

(s:null "[" (s:a name 'href 
               (s:link-to (string-append "location/" (string-intersperse p "/") ""))) "] ")))



Call current page with new param
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In view.scm:

 (s:center "[" (s:a 'href (s:link-to "polls"
                           'id
                            (begin
                              (poll:poll 'fill-polls)
                              (poll:poll 'get-next-poll)))
                          "Go to the next poll")  "]")

In control.scm:

(let ((poll-id (s:get-param 'id)))
 ;; do stuff based on poll-id


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.


A complex link example
~~~~~~~~~~~~~~~~~~~~~~

(s:a "Reply" 'href (s:link-to (s:current-page) 
	           'action "discussion.reply" ;; <page>.<action>
	           '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


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)


make a selection drop down
~~~~~~~~~~~~~~~~~~~~~~~~~~

In view.scm: 

(s:select '(("World" 0)("Country" 1)("State" 2)("Town/City" 3)) 'name 'scope)

In control.scm:

(let ((scope (s:get-input 'scope)))
  ....


Simple error reporting
~~~~~~~~~~~~~~~~~~~~~~

In control.scm:
(s:set-err "You must provide an email address")

In view.scm:
(s:get-err s:err-font)

Or:
(s:get-err (lambda (x)(s:err-font x (s:br))))


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)

  ii. Random string

(session:make-rand-string len)

 iii. string to number for pgint
 
(s:any->pgint val)


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"))

(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")




Modified setup.scm from [370e79d111] to [b6762fc909].

83
84
85
86
87
88
89

90
91
92
93
94
95
96
97
98











99
100
101
102
103
104
105
  (session:del! s:session "*sessionvars*" key))

;; 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))












;; http://foo.bar.com/pagename/p1/p2 => '("p1" "p2")
;;
(define (s:get-page-params)
  (sdat-get-page-params s:session))

(define (s:db)
  (sdat-get-conn s:session))







>









>
>
>
>
>
>
>
>
>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  (session:del! s:session "*sessionvars*" key))

;; 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))

(define (s:db)
  (sdat-get-conn s:session))

Modified sugar.scm from [08f3dbeadf] to [8c9838f5ec].

20
21
22
23
24
25
26









27
























































28
29
30
31
32
33
34
35
36
37
38
39
;;     [(_ s x y) (if (s:get s) x y)]))
;; ;; 
;; (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))))








>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
;;     [(_ s x y) (if (s:get s) x y)]))
;; ;; 
;; (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)]))

;; 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 #<undefined> 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))))
;;