forked from rabbibotton/clog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
12-tutorial.lisp
136 lines (127 loc) · 6.59 KB
/
12-tutorial.lisp
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
;;; CLOG is an excellent choice for websites as well as GUI's for applications.
;;; The first 10 tutorials focused on a single "page" application. For GUIs
;;; that works well, and combining your CLOG app embedded in an native app that
;;; provides a web control on desktop or mobile works well. CLOG apps of course
;;; are web apps right out of the box. However CLOG is also more than capable
;;; of handling things in a more traditional website manner.
;;;
;;; In the last tutorial it was demonstrated that one can take any HTML file
;;; add the boot.js file to it and then it becomes a dynamic interactive
;;; clog app. An entire site could be laid out using .html files and where
;;; desired a fully dynamic page can be created by copying the boot.html file
;;; or some styled html template etc. (Look in the next few demos for
;;; examples using templates like bootstrap with CLOG, etc).
;;;
;;; Here we demonstrate how CLOG routs to dynamic pages. Static pages are
;;; placed in the directory set on initialization.
;;;
;;; See START-TUTORIAL below.
(defpackage #:clog-tut-12
(:use #:cl #:clog)
(:export start-tutorial))
(in-package :clog-tut-12)
(defun on-main (body)
(setf (title (html-document body)) "Tutorial 12") ;; set the page title
(let ((sb (create-style-block body)))
(add-style sb :element "a" '(("color" :orange)
("text-decoration" :none)))
(add-style sb :element "a:hover" '(("background-color" :gray))))
(create-div body :content
"We are in on-main<br><br>
<h1>Pick a link</h1>
<ul>
<li><a href='/page1'>/page1</a> - a CLOG app
<li><a href='/page1.html'>/page1.html</a> - a CLOG app mascarading as a .html
<li><a href='/somepath/hi/'>/somepath/hi/</a> - deeper paths
<li><a href='/page2'>/page2</a> - a CLOG app using an alternative boot file
<li><a href='/page3'>/page3</a> - tutorial 11 as part of this tutorial
<li><a href='/tutorial/tut-11.html'>/tutorial/tut-11.html</a> - an html file using boot.js
<li><a href='/tutorial/some-file.html'>/tutorial/some-file.html</a> - an html file using boot.js
<li><a href='/tutorial/regular-file.html'>/tutorial/regular-file.html</a> - a regular html file
</ul>"))
(defun on-page1 (body)
(create-div body :content
(format nil "You are in on-page1 and got here using ~A"
(path-name (location body)))))
(defun on-page2 (body)
(create-div body :content "You are in on-page2")
(log-console (window body) "A message in the browser's log"))
(defun on-tutorial11 (body)
(let* ((form (attach-as-child body "form1" :clog-type 'clog-form))
(good-button (attach-as-child body "button1id"))
(scary-button (attach-as-child body "button2id")))
(flet ((on-click-good (obj)
(declare (ignore obj))
(let ((alert-div (create-div body)))
(place-before form alert-div)
(setf (hiddenp form) t)
;; Bootstrap specific markup
(setf (css-class-name alert-div) "alert alert-success")
(setf (attribute alert-div "role") "alert")
(setf (inner-html alert-div)
(format nil "<pre>radios value : ~A</pre><br>
<pre>textinput value : ~A</pre><br>"
(radio-value form "radios")
(name-value form "textinput")))))
(on-click-scary (obj)
(declare (ignore obj))
(reset form)))
;; We need to override the boostrap default to submit the form html style
(set-on-submit form (lambda (obj)(declare (ignore obj))()))
(set-on-click good-button #'on-click-good)
(set-on-click scary-button #'on-click-scary))))
(defun on-default (body)
(cond ((equalp (path-name (location body))
"/tutorial/tut-11.html")
(on-tutorial11 body))
(t
(create-div body :content "No dice! What do I do with you?"))))
(defun add-search-optimizations (path content)
;; The default boot.html that comes with CLOG has template
;; markers inside of the meta section and body section
;; that are set to be transparent to the user but show to
;; search engines and text browser. This allows setting
;; custom data for search engine optimizations which are
;; aware of these type of dynamic sites.
(if (equal path "/")
(funcall (cl-template:compile-template content)
(list :meta "<meta name='description' content='CLOG Tutorial 12'>"
:body "Tutorial 12 for CLOG"))
content))
(defun start-tutorial ()
"Start turtorial."
;; Setup the default route / to on-main
;; :boot-function allows us to add or modify our boot-files content
;; for search engine optimization. We choose long-polling-first so
;; our website can be crawled for content by google
(initialize 'on-main
:long-poll-first t
:boot-function 'add-search-optimizations
:extended-routing t)
;; Navigating to http://127.0.0.1:8080/page1 executes on-page1
;; Since extended-routing is t /page1/any/thing/else also routes to /page1
(set-on-new-window 'on-page1 :path "/page1")
;; Navigating to http://127.0.0.1:8080/page1.html executes on-page1
;; There is no .html file - it is just a route to CLOG handler
;; but the user thinks it is like any other html file.
(set-on-new-window 'on-page1 :path "/page1.html")
;; Navigating to http://127.0.0.1:8080/somepath/page1/ executes on-page1
;; the path set can be any valid html path and has no meaning.
(set-on-new-window 'on-page1 :path "/somepath/hi/")
;; Here we add another page, page2. It uses a boot file that turns
;; on debugging to the browser console of communications with the
;; server.
(set-on-new-window 'on-page2 :path "/page2" :boot-file "/debug.html")
;; Here we add another page, page3. But this time we use the html file
;; from tutorial 11 and make it the boot-file and execute the same code
;; in (on-tutorial11) as in tutorial 11.
(set-on-new-window 'on-tutorial11 :path "/page3"
:boot-file "/tutorial/tut-11.html")
;; Setting a "default" path says that any use of an included boot.js
;; file by static html file will route to this function, in this case on-default
;; which will determine if this is coming from the path used in tutorial
;; 11 - "http://127.0.0.1:8080/tutorial/tut-11.html" and if it does
;; use on-tutorial11, and if not say "No Dice!" such as when one pics
;; some-file.html which also loads boot.js
(set-on-new-window 'on-default :path :default)
(open-browser))