Skip to content

Commit b0791ef

Browse files
committed
templates and ++
1 parent 7fef44c commit b0791ef

File tree

4 files changed

+68
-28
lines changed

4 files changed

+68
-28
lines changed

content/building-blocks/routing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
+++
22
title = "Routing"
3-
weight = 15
3+
weight = 16
44
+++
55

66
I prefer the easy-routes library than pure Hunchentoot to define

content/building-blocks/simple-web-server.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,15 @@ internet right away.
8585

8686
If you evaluate this on your VPS:
8787

88-
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))
88+
```lisp
89+
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))
90+
```
8991

9092
You can see it right away on your server's IP.
9193

94+
You can use the `:address` parameter of Hunchentoot's easy-acceptor to
95+
bind it and restrict it to 127.0.0.1 (or any address) if you wish.
96+
9297
Stop it with `(hunchentoot:stop *)`.
9398

9499
Now on the next section, we'll create some routes to build a dynamic website.

content/building-blocks/static.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,39 @@
11
+++
22
title = "Static assets"
3-
weight = 25
3+
weight = 15
44
+++
55

6+
How can we serve static assets?
7+
8+
Remember from [simple web server](/building-blocks/simple-web-server/)
9+
how Hunchentoot serves files from a `www/` directory by default. We can change that.
610

711
## Hunchentoot
812

9-
With Hunchentoot, use `create-folder-dispatcher-and-handler prefix directory`.
13+
Use the `create-folder-dispatcher-and-handler prefix directory` function.
1014

1115
For example:
1216

1317
~~~lisp
1418
(defun serve-static-assets ()
15-
"Let Hunchentoot serve static assets under the /src/static/ directory of your :myproject system.
16-
Reference static assets with the /static/ URL prefix."
19+
"Let Hunchentoot serve static assets under the /src/static/ directory
20+
of your :myproject system.
21+
Then reference static assets with the /static/ URL prefix."
1722
(push (hunchentoot:create-folder-dispatcher-and-handler
18-
"/static/" (merge-pathnames "src/static" ;; starts without a /
19-
(asdf:system-source-directory :myproject))) ;; <- myproject
20-
hunchentoot:*dispatch-table*))
23+
"/static/"
24+
(merge-pathnames "src/static" ;; starts without a /
25+
(asdf:system-source-directory :myproject))) ;; <- myproject
26+
hunchentoot:*dispatch-table*))
27+
~~~
28+
29+
and call it in the function that starts your application:
2130

31+
```lisp
2232
(serve-static-assets)
23-
~~~
33+
```
2434

25-
Now our project's static files located under
26-
`/path/to/myproject/src/static/` are served with the `/static/` prefix:
35+
Now our project's static files located under `src/static/` are served
36+
with the `/static/` prefix, access them like this:
2737

2838
```html
2939
<img src="/static/img/banner.jpg" />

content/building-blocks/templates.md

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,83 @@ weight = 30
99
[Djula](https://github.com/mmontone/djula) is a port of Python's
1010
Django template engine to Common Lisp. It has [excellent documentation](https://mmontone.github.io/djula/djula/).
1111

12-
Install it if you didn't already do it:
12+
Install it if you didn't already:
1313

1414
~~~lisp
1515
(ql:quickload "djula")
1616
~~~
1717

18-
19-
Caveman uses it by default, but otherwise it is not difficult to
18+
The Caveman framework uses it by default, but otherwise it is not difficult to
2019
setup. We must declare where our templates live with something like:
2120

2221
~~~lisp
23-
(djula:add-template-directory (asdf:system-relative-pathname "webapp" "templates/"))
22+
(djula:add-template-directory (asdf:system-relative-pathname "myproject" "templates/"))
2423
~~~
2524

2625
and then we can declare and compile the ones we use, for example::
2726

2827
~~~lisp
2928
(defparameter +base.html+ (djula:compile-template* "base.html"))
30-
(defparameter +welcome.html+ (djula:compile-template* "welcome.html"))
29+
(defparameter +products.html+ (djula:compile-template* "products.html"))
3130
~~~
3231

3332
A Djula template looks like this:
3433

3534
```html
3635
{% extends "base.html" %}
37-
{% block title %}Memberlist{% endblock %}
36+
{% block title %} Products page {% endblock %}
3837
{% block content %}
3938
<ul>
40-
{% for user in users %}
41-
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
39+
{% for product in products %}
40+
<li><a href="{{ product.id }}">{{ product.name }}</a></li>
4241
{% endfor %}
4342
</ul>
4443
{% endblock %}
4544
```
4645

46+
This template actually inherits a first one, `base.html`, which can be:
47+
48+
```html
49+
<html>
50+
<head>
51+
<meta charset="utf-8">
52+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
53+
54+
<title>{% block title %} My Lisp app {% endblock %}</title>
55+
56+
</head>
57+
<body>
58+
<div class="container">
59+
{% block content %} {% endblock %}
60+
</div>
61+
</body>
62+
</html>
63+
```
64+
65+
This base template defines two blocks: one for the page title, one for
66+
the page content. A template that wants to inherit this base template
67+
will use `{% extends "base.html" %}` and replace each blocks with `{% block
68+
content %} … {‰ endblock %}`.
69+
70+
4771
At last, to render the template, call `djula:render-template*` inside a route.
4872

4973
~~~lisp
5074
(easy-routes:defroute root ("/" :method :get) ()
51-
(djula:render-template* +welcome.html+ nil
52-
:users (get-users)
75+
(djula:render-template* +products.html+
76+
nil
77+
:products (products)
5378
~~~
5479

55-
Note that for efficiency Djula compiles the templates before rendering them.
56-
57-
It is, along with its companion
80+
Djula is, along with its companion
5881
[access](https://github.com/AccelerationNet/access/) library, one of
5982
the most downloaded libraries of Quicklisp.
6083

6184
#### Djula filters
6285

63-
Filters allow to modify how a variable is displayed. Djula comes with
86+
Filters are only waiting for the developers to define their own, so we should have a work about them.
87+
88+
They allow to modify how a variable is displayed. Djula comes with
6489
a good set of built-in filters and they are [well documented](https://mmontone.github.io/djula/djula/Filters.html#Filters). They are not to be confused with [tags](https://mmontone.github.io/djula/djula/Tags.html#Tags).
6590

6691
They look like this: `{{ var | lower }}`, where `lower` is an
@@ -112,8 +137,8 @@ HTML5 generator. It looks like this:
112137
(:footer ("Last login: ~A" *last-login*)))
113138
~~~
114139

115-
I find it is easier to compose the HTML than with the more famous
116-
cl-who, but I personnally prefer to use HTML templates.
140+
I find Spinneret easier to use than the more famous cl-who, but I
141+
personnally prefer to use HTML templates.
117142

118143
Spinneret has nice features under it sleeves:
119144

0 commit comments

Comments
 (0)