diff --git a/src/view.lisp b/src/view.lisp
index 6061f53..1b91d5d 100644
--- a/src/view.lisp
+++ b/src/view.lisp
@@ -46,6 +46,26 @@
:developmentp
:productionp)
(:import-from :caveman2
- :url-for))
+ :url-for)
+ (:export #:title!) ; Added in Chapter 3 (Mockup section).
+ )
+;; in-package and let code added in Chapter 3, also. This is
+;; preperation for Switching Layout Templates section.
+(in-package
+ :rails-to-caveman.djula) ; Make sure this states your app name.
+(let(title)
+ (defun title! (&optional sub)
+ (if sub
+ (format nil "~@[~A - ~]~:(~A~)"
+ (setf title sub)
+ ;; Make sure find-system states your app name.
+ #.(asdf:coerce-name(asdf:find-system :rails-to-caveman)))
+ title))) ; End of Chapter 3 additional code.
(setf djula:*djula-execute-package* (find-package :rails-to-caveman.djula))
+
+;;; This is a custom filter which is was added in Chapter 3
+;;; (Routing). Apparently, this is a filter which is part of the djula
+;;; project's TODOs. This filter is used in 'step13.html' (in
+;;; /templates directory).
+(djula::def-filter :break(it) (cl-ppcre:regex-replace-all #\newline it "
"))
diff --git a/src/web.lisp b/src/web.lisp
index 306457b..30e2de7 100644
--- a/src/web.lisp
+++ b/src/web.lisp
@@ -1,11 +1,11 @@
(in-package :cl-user)
(defpackage rails-to-caveman.web
(:use :cl
- :caveman2
+ :caveman2
:rails-to-caveman.config
- :rails-to-caveman.view
+ :rails-to-caveman.view
:rails-to-caveman.db
- :datafly
+ :datafly
:sxql)
(:export :*web*))
(in-package :rails-to-caveman.web)
@@ -24,13 +24,22 @@
;; Routing rules
(defroute "/" ()
- (render #P"index.html"))
+ (render #P"index.html"
+ ;; Use to pass message to view -- it is expecting a
+ ;; `MESSAGE' item. You do not need to add it, though. Or,
+ ;; you can pass it an empty value/string if you do not want
+ ;; to leave the code commented out.
+
+ ;; '(:message "This is not a message") ; Added Chapter 3.
+ '(:numbers (1 2 3 4 5))
+ ))
(defroute "/about" ()
+ ;; about.html should be in the /templates directory.
(render #P"about.html" '(:page-title "About")))
(defroute "/hello/:name" (&key name)
- ;; Substitutes `:name' with `name'.
+ ;; Substitutes ':name' with `NAME'.
(format nil "Hello, ~A" name))
(defroute "/say/*/to/*" (&key splat)
@@ -42,7 +51,7 @@
(defroute ("/hello/([\\w]+)" :regexp t) (&key captures)
;; Parse the second part of the URL via a regular expression
;; (regexp). The result of the parsed regexp text is stored in
- ;; `captures', hence the use of 'first' in the format string.
+ ;; `CAPTURES', hence the use of 'first' in the format string.
(format nil "Hello, ~A!" (first captures)))
(defroute "/hello/?:name?" (&key name)
@@ -51,7 +60,7 @@
;; 1. /hello/earth
;; 2. /hello?NAME=earth
- ;; The query string must be in UPPERCASE. Otherwise, the `name' will
+ ;; The query string must be in UPPERCASE. Otherwise, the `NAME' will
;; be bound to `nil'.
(format nil "Hello, ~A" name))
@@ -59,7 +68,7 @@
;; If you want the query string in lowercase, enclose `name' (in
;; this case) with vertical bars '|'. This will force you to have
;; only one route (unlike the route above). `NAME' will now bind to
- ;; `nil'.
+ ;; `NIL'.
;; 1. /hello?name=earth
;; 2. /hello?NAME=earth <--- no longer works ('earth' binds to nil).
@@ -75,7 +84,7 @@
(defroute "/lesson/step*" (&key splat (|name| "Anonymous"))
;; 'Anonymous' is the default value for `|name|'.
;; Query style: Working with Parameters.
- ;; Example URL: lesson/step1?name=Sato
+ ;; Example URL: /lesson/step1?name=Sato
(case (parse-integer (car splat) :junk-allowed t)
(1 (format nil "Hello, ~A" |name|))))
@@ -83,16 +92,91 @@
;; If /lesson/step1 is used, it will be redirected to /lesson/step2,
;; then /lesson/step3 and finally /lesson/step4. No matter where you
;; start (along as it is below 4), the redirects will always take
- ;; you wot /lesson/step4.
+ ;; you to /lesson/step4.
- ;; The example includes `name' but it is never used. I am keeping it
+ ;; The example includes `NAME' BUT it is never used. I am keeping it
;; here for consistency between the reference material and this code
;; base.
(case (parse-integer (car splat) :junk-allowed t)
(1 '(302 (:location "/lesson/step2")))
(2 '(302 (:location "/lesson/step3")))
(3 '(302 (:location "/lesson/step4")))
- (4 "Moved to step4")))
+ (4 "Moved to step4")
+
+ ;; To be honest, I do not know what this is actually doing. It is
+ ;; mentioned in 'STEP5 Flash' in Chapter 3 (I.E. Tutorial 3:
+ ;; Routing). This applies to case's 5 and 6.
+ (5 (setf (gethash :notice *session*) "Move to step6")
+ `(302 (:location "/lesson/step6")))
+ (6 (let((notice (gethash :notice *session*)))
+ (remhash :notice *session*) notice))
+
+ ;; This is part of an example about using djula (which is a
+ ;; template engine used by Caveman2. djula is a port of Python's
+ ;; Django template engine.
+ ;; step7.html should be in the /templates directory.
+ (7 (render "step7.html"
+ `(:price ,(floor(* 2000 1.08)))))
+ (8 (render "step7.html" '(:price 1000)))
+ (9 (render "step9.html"
+ '(:comment "Hello")))
+ ;; If you dare to embed HTML, add safe after the variable
+ ;; reference on the View side (step10.html).
+ (10 (render "step10.html"
+ '(:comment "safe html")))
+ (11 `(200 (:content-type "text/html; charset=utf-8")
+ (, (let ((population 704414) (surface 141.31))
+ (render "step11.html"
+ `(:contents
+ ,(format nil
+ ;; ~D = Decimal
+
+ ;; ~,,2F = Fixed-Format
+ ;; Floating-Point
+
+ ;; ~,,2F = Print exactly two
+ ;; digits after the decimal
+ ;; point and many as necessary
+ ;; before the decimal point.
+ "Population: ~D Floor Surface: ~D Population/Surface: ~,,2F"
+ population
+ (floor surface)
+ (/ population surface))))))))
+ (12 (render "step11.html"
+ `(:contents ,(local-time:format-timestring
+ nil
+ (local-time:now)
+ :format '((:year 4)"/"(:month 2)"/"(:day 2)"(" :short-weekday ") "
+ (:hour 2)":"(:min 2)":"(:sec 2))))))
+ (13 `(200 (:content-type "text/html; charset=utf-8")
+ ;; This view uses 'format' in step13.html (view in
+ ;; /templates directory).
+ (,(render "step13.html" '(:population 127767944)))))
+ (14 (render "step14.html"
+ ;; The view uses a custom filter which was added to
+ ;; view.lisp.
+ `(:contents ,(format nil "foo~%bar~%bazz"))))
+ ;; The view demonstrates how to form links.
+ (15 (render "step15.html"))
+ ;; The view demonstrates how to display images.
+ ;; Images are stored in the /static/images directory.
+ (16 (render "step16.html"))
+ ;; Provides control branches which you can navigate via djula in
+ ;; step17.html (/templates directory).
+ (17 `(200 (:content-type "text/html; charset=utf-8")
+ ;; Adjust `STOCK' to adjust what is viewed in step17.html.
+ (,(let((stock 10))
+ (render "step17.html"
+ `(:stock-zerop ,(< 0 stock) :stock ,stock))))))
+ ;; This creates a list (cons list) which is then cycled through in
+ ;; /templates/step18.html using the djula template engine..
+ (18 (render "step18.html"
+ '(:items
+ ((:pan . 2680)
+ (:glass . 2550)
+ (:pepper-mill . 4515)
+ (:peeler . 945)))))
+ ))
;;
;; Error pages
diff --git a/static/css/main.css b/static/css/main.css
index 2e05864..a0d04e0 100644
--- a/static/css/main.css
+++ b/static/css/main.css
@@ -1,21 +1,45 @@
-@charset "UTF-8";
-
+/* whole pages */
body {
- font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
+ background-color: white;
+ color: black;
+ margin: 0; padding: 0;
+ font-family: Meiryo, sans-serif;
}
-a:link {
- color: #005585;
- text-decoration: none;
-}
-a:visited {
- color: #485270;
+/* link */
+a:link { color: #00c; }
+a:visited { color: #00c; }
+a:hover { color: #f00; }
+a img { border: none; }
+
+/* whole border */
+div#container {
+ margin: 0 auto;
+ padding-top: 5px;
+ width: 780px;
}
-a:hover {
- color: #b83800;
- text-decoration: underline;
+
+/* left pane */
+main {
+ float: left;
+ width: 530px;
+ padding: 10px, 10px, 10px, 0;
}
-#main {
- text-align: center;
+/* right pane */
+aside#sidebar {
+ float: left;
+ width: 230px;
+ background-color: #e8ffff;
+ padding: 5px;
+ font-size: 86%;
}
+
+/* link of menubar */
+nav.menubar a { text-decoration: none; }
+
+/* link of menubar (not visited) */
+nav.menubar a:link { color: #ccc; }
+
+/* link of menubar (visited) */
+nav.menubar a:visited { color: #ccc; }
diff --git a/static/images/lisplogo.svg b/static/images/lisplogo.svg
new file mode 100644
index 0000000..75c4f9b
--- /dev/null
+++ b/static/images/lisplogo.svg
@@ -0,0 +1,406 @@
+
+
+
diff --git a/templates/index.html b/templates/index.html
index 6a3c687..3fa348d 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,7 +1,24 @@
-{% extends "layouts/default.html" %}
-{% block title %}Welcome to Caveman2{% endblock %}
+{% extends "layouts/app.html" %}
+
+{% comment "Set title using title function." %}
+
+{%block title %}{% lisp (title! "Bitchin!") %}{% endblock %}
+{% endcomment %}
+
+
+{% block title %}Rails to Caveman2 Demo.{% endblock %}
+
{% block content %}
-
Here we go!
{% endblock %} diff --git a/templates/layouts/app.html b/templates/layouts/app.html new file mode 100644 index 0000000..5bf206b --- /dev/null +++ b/templates/layouts/app.html @@ -0,0 +1,25 @@ + + + + +{{comment | safe}}
diff --git a/templates/step11.html b/templates/step11.html new file mode 100644 index 0000000..d74c626 --- /dev/null +++ b/templates/step11.html @@ -0,0 +1 @@ +{{contents}}
diff --git a/templates/step13.html b/templates/step13.html new file mode 100644 index 0000000..a2f34a6 --- /dev/null +++ b/templates/step13.html @@ -0,0 +1,7 @@ + +Step 13 | Population: {{population | format: "~D"}}
diff --git a/templates/step14.html b/templates/step14.html new file mode 100644 index 0000000..50ff8d3 --- /dev/null +++ b/templates/step14.html @@ -0,0 +1,3 @@ + +{{contents|break|safe}}
diff --git a/templates/step15.html b/templates/step15.html new file mode 100644 index 0000000..19750a7 --- /dev/null +++ b/templates/step15.html @@ -0,0 +1,2 @@ + +Home diff --git a/templates/step16.html b/templates/step16.html new file mode 100644 index 0000000..3efcbf8 --- /dev/null +++ b/templates/step16.html @@ -0,0 +1,8 @@ +Powered by + + +
diff --git a/templates/step17.html b/templates/step17.html new file mode 100644 index 0000000..61bcc3f --- /dev/null +++ b/templates/step17.html @@ -0,0 +1,14 @@ + + +{% if stock-zerop %} +Stock: {{stock}} +{% else %} +This is no stock. +{% endif %} diff --git a/templates/step18.html b/templates/step18.html new file mode 100644 index 0000000..ab4b1b3 --- /dev/null +++ b/templates/step18.html @@ -0,0 +1,30 @@ + + ++
{{ key }} | +{{ val | format: ~:D }} Currency Points | +
---|
{{price}}
diff --git a/templates/step9.html b/templates/step9.html new file mode 100644 index 0000000..52ad2e2 --- /dev/null +++ b/templates/step9.html @@ -0,0 +1 @@ +{{comment}}