Skip to content

Commit 5c988c4

Browse files
committed
Building Blocks, more topics: organize per task
1 parent adc80fa commit 5c988c4

File tree

11 files changed

+300
-144
lines changed

11 files changed

+300
-144
lines changed

content/_index.md

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
## Web apps in Lisp
2+
## Web Apps in Lisp: Know-how
33

44
You want to write a web application in Common Lisp and you don't know
55
where to start? Or you don't want to re-invent the wheel? Follow the guide.
@@ -92,7 +92,13 @@ We will learn:
9292

9393
Your feedback and contributions are appreciated!
9494

95-
Now let's start with a [frameworks overview](/frameworks).
95+
**In [part 1](/part-1/), we will get to know a classical stack: Hunchentoot, easy-routes for easier routing and Djula templates.**
96+
97+
In part 2, we will add interactivity on the client side, with or without JavaScript.
98+
99+
In part 3, we will build an interactive Ajax-based Todo-app without writing any JavaScript, thanks to ISSR and Weblocks.
100+
101+
Now let's start with a [libraries overview](/part 1/).
96102

97103

98104
{{% notice note %}}
@@ -106,6 +112,15 @@ If you find similar content from the Cookbook, this is normal. I am the main con
106112
{{% /notice %}}
107113

108114

115+
{{% notice info %}}
116+
117+
Here's a 5 minutes refresh on how to create a project, how to run it from sources, how to build a binary and how to load everything in SLIME:
118+
119+
{{% /notice %}}
120+
121+
{{< youtube XFc513MJjos >}}
122+
123+
109124
[hunchentoot]: https://edicl.github.io/hunchentoot
110125
[clack]: https://github.com/fukamachi/clack
111126
[caveman]: https://github.com/fukamachi/caveman

content/frameworks/_index.md renamed to content/building-blocks/_index.md

+16-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1+
12
+++
2-
title = "Frameworks overview"
3-
weight = 10
3+
title = "Building blocks"
4+
weight = 1
45
+++
56

7+
In this chapter we'll start by creating our first route, we'll serve
8+
local files and we'll run more than one web app in the same running
9+
image.
10+
11+
Let's install the libraries we'll use:
612

7-
[Hunchentoot][hunchentoot] and [Clack][clack] are two projects that
8-
you'll often hear about.
13+
~~~lisp
14+
(ql:quickload '("hunchentoot" "easy-routes" "djula" "spinneret"))
15+
~~~
916

1017
{{% notice info %}}
18+
You can create a web project with our project generator: [cl-cookieweb](https://github.com/vindarel/cl-cookieweb).
19+
{{% /notice %}}
1120

12-
CL-USER> `(ql:quickload "hunchentoot")`
1321

14-
{{% /notice %}}
22+
We will use the [Hunchentoot][hunchentoot] web server, but we should say a few words about [Clack][clack] too.
1523

16-
Hunchentoot is
24+
**Hunchentoot** is
1725

1826
> a web server and at the same time a toolkit for building dynamic websites. As a stand-alone web server, Hunchentoot is capable of HTTP/1.1 chunking (both directions), persistent connections (keep-alive), and SSL. It provides facilities like automatic session handling (with and without cookies), logging, customizable error handling, and easy access to GET and POST parameters sent by the client.
1927
@@ -26,7 +34,7 @@ write a function for the `:uri` parameter that does the check, when it
2634
is a built-in keyword in other frameworks. We will use
2735
the `easy-routes` library for that.
2836

29-
Clack is
37+
**Clack** is
3038

3139
> a web application environment for Common Lisp inspired by Python's WSGI and Ruby's Rack.
3240
@@ -69,11 +77,6 @@ For a full list of libraries for the web, please see the [awesome-cl list
6977
#network-and-internet](https://github.com/CodyReichert/awesome-cl#network-and-internet)
7078
and [Cliki](https://www.cliki.net/Web).
7179

72-
**In [part 1](/part-1/), we will use a classical stack: Hunchentoot, easy-routes for easier routing and Djula templates.**
73-
74-
In part 2, we will add Ajax interactivity on the client side with some pure JavaScript and some Vue.js.
75-
76-
In part 3, we will build an interactive Ajax-based Todo-app without writing any JavaScript, thanks to ISSR, and Weblocks.
7780

7881

7982
[hunchentoot]: https://edicl.github.io/hunchentoot

content/part 1/database.md renamed to content/building-blocks/database.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
+++
33
title = "Connecting to a database"
4-
weight = 17
4+
weight = 170
55
+++
66

77
Please see the [databases section](databases.html). The Mito ORM
@@ -138,4 +138,3 @@ library.
138138
~~~
139139

140140
*Credit: `/u/arvid` on [/r/learnlisp](https://www.reddit.com/r/learnlisp/comments/begcf9/can_someone_give_me_an_eli5_on_hiw_to_encrypt_and/)*.
141-

content/deployment/_index.md renamed to content/building-blocks/deployment.md

+2-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
+++
22
title = "Deployment"
3-
weight = 100
3+
weight = 200
44
+++
55

66

@@ -17,16 +17,7 @@ We must ensure:
1717
- to install the required dependencies (this demands we have installed Quicklisp previously)
1818
- and to run our application's entry point.
1919

20-
{{% notice info %}}
21-
22-
Here's a 5 minutes refresh on how to create a project, how to run it from sources, how to build a binary, how to load everything in SLIME:
23-
24-
{{% /notice %}}
25-
26-
{{< youtube XFc513MJjos >}}
27-
28-
29-
So, the recipe to run our project from sources can look like this:
20+
So, the recipe to run our project from sources can look like this (you can find such a recipe in our project generator):
3021

3122
~~~lisp
3223
;; run.lisp
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
+++
2+
title = "Error handling"
3+
weight = 150
4+
+++
5+
6+
In all frameworks, we can choose the level of interactivity. The web
7+
framework can return a 404 page and print output on the repl, it can
8+
catch errors and invoke the interactive lisp debugger, or it can show
9+
the lisp backtrace on the html page.
10+
11+
### Hunchentoot
12+
13+
The global variables to set are `*catch-errors-p*`,
14+
`*show-lisp-errors-p*` and `*show-lisp-backtraces-p*`.
15+
16+
Hunchentoot also defines condition classes.
17+
18+
See the documentation: [https://edicl.github.io/hunchentoot/#conditions](https://edicl.github.io/hunchentoot/#conditions).

content/part 1/_index.md renamed to content/building-blocks/routing.md

+4-113
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,16 @@
1-
21
+++
3-
title = "Part 1: first project"
2+
title = "Routing"
43
weight = 15
54
+++
65

7-
Let's install the libraries we'll use:
8-
9-
~~~lisp
10-
(ql:quickload '("hunchentoot" "easy-routes" "spinneret" "djula"))
11-
~~~
12-
13-
We'll start by creating our first route, we'll serve local files and
14-
we'll run more than one web app in the same running image.
156

167
{{% notice info %}}
178

18-
You can create a web project with our project generator: [cl-cookieweb](https://github.com/vindarel/cl-cookieweb).
9+
I prefer the easy-routes library than pure Hunchentoot to define routes, skip to its section if you want.
1910

2011
{{% /notice %}}
2112

22-
23-
## Simple webserver
24-
25-
### Serve local files
26-
27-
Create and start a webserver like this:
28-
29-
~~~lisp
30-
(defvar *acceptor* (make-instance 'hunchentoot:easy-acceptor :port 4242))
31-
(hunchentoot:start *acceptor*)
32-
~~~
33-
34-
We create an instance of `easy-acceptor` on port 4242 and we start
35-
it. We can now access [http://127.0.0.1:4242/](http://127.0.0.1:4242/). You should get a welcome
36-
screen with a link to the documentation and logs to the console.
37-
38-
By default, Hunchentoot serves the files from the `www/` directory in
39-
its source tree. Thus, if you go to the source of
40-
`easy-acceptor` (`M-.` in Slime), which is probably
41-
`~/quicklisp/dists/quicklisp/software/hunchentoot-v1.2.38/`, you'll
42-
find the `root/` directory. It contains:
43-
44-
- an `errors/` directory, with the error templates `404.html` and `500.html`,
45-
- an `img/` directory,
46-
- an `index.html` file.
47-
48-
To serve another directory, we give the option `document-root` to
49-
`easy-acceptor`. We can also set the slot with its accessor:
50-
51-
~~~lisp
52-
(setf (hunchentoot:acceptor-document-root *acceptor*) #p"path/to/www")
53-
~~~
54-
55-
Let's create our `index.html` first. Put this in a new
56-
`www/index.html` at the current directory (of the lisp repl):
57-
58-
~~~html
59-
<html>
60-
<head>
61-
<title>Hello!</title>
62-
</head>
63-
<body>
64-
<h1>Hello local server!</h1>
65-
<p>
66-
We just served our own files.
67-
</p>
68-
</body>
69-
</html>
70-
~~~
71-
72-
Let's start a new acceptor on a new port:
73-
74-
~~~lisp
75-
(defvar *my-acceptor* (make-instance 'hunchentoot:easy-acceptor :port 4444
76-
:document-root #p"www/"))
77-
(hunchentoot:start *my-acceptor*)
78-
~~~
79-
80-
go to [http://127.0.0.1:4444/](http://127.0.0.1:4444/) and see the difference.
81-
82-
Note that we just created another web application on a different port on
83-
the same lisp image. This is already pretty cool.
84-
85-
86-
## Access your server from the internet
87-
88-
With Hunchentoot we have nothing to do, we can see the server from the
89-
internet right away.
90-
91-
If you evaluate this on your VPS:
92-
93-
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))
94-
95-
You can see it right away on your server's IP.
96-
97-
Stop it with `(hunchentoot:stop *)`.
98-
99-
## Routing
100-
101-
> Note: you can skip to the easy-routes part if you want.
13+
## Hunchentoot
10214

10315
### The dispatch table
10416

@@ -182,7 +94,7 @@ It also has a `default-parameter-type` which we'll use in a minute to get url pa
18294
There are also keys to know for the lambda list. Please see the documentation.
18395

18496

185-
### Easy-routes
97+
## Easy-routes
18698

18799
[easy-routes](https://github.com/mmontone/easy-routes) is a route
188100
handling extension on top of Hunchentoot. It provides:
@@ -310,24 +222,3 @@ or a compound list:
310222
- `'(:hash-table <type>)`
311223

312224
where `<type>` is a simple type.
313-
314-
315-
<!-- ## Sessions -->
316-
317-
<!-- ## Cookies -->
318-
319-
## Error handling
320-
321-
In all frameworks, we can choose the level of interactivity. The web
322-
framework can return a 404 page and print output on the repl, it can
323-
catch errors and invoke the interactive lisp debugger, or it can show
324-
the lisp backtrace on the html page.
325-
326-
### Hunchentoot
327-
328-
The global variables to set are `*catch-errors-p*`,
329-
`*show-lisp-errors-p*` and `*show-lisp-backtraces-p*`.
330-
331-
Hunchentoot also defines condition classes.
332-
333-
See the documentation: [https://edicl.github.io/hunchentoot/#conditions](https://edicl.github.io/hunchentoot/#conditions).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
2+
+++
3+
title = "Simple web server"
4+
weight = 10
5+
+++
6+
7+
Before dwelving into web development, we might want to do something simple: serve some files we have on disk.
8+
9+
### Serve local files
10+
11+
Create and start a webserver like this:
12+
13+
~~~lisp
14+
(defvar *acceptor* (make-instance 'hunchentoot:easy-acceptor :port 4242))
15+
(hunchentoot:start *acceptor*)
16+
~~~
17+
18+
We create an instance of `easy-acceptor` on port 4242 and we start
19+
it. We can now access [http://127.0.0.1:4242/](http://127.0.0.1:4242/). You should get a welcome
20+
screen with a link to the documentation and logs to the console.
21+
22+
{{% notice info %}}
23+
24+
You can also use Roswell's [http.server](https://github.com/roswell/http.server/) from the command line:
25+
26+
$ ros install roswell/http.server
27+
$ ros -s http.server
28+
Hunchentoot server is going to start.
29+
Listening on 127.0.0.1:5000.
30+
31+
{{% /notice %}}
32+
33+
By default, Hunchentoot serves the files from the `www/` directory in
34+
its source tree. Thus, if you go to the source of
35+
`easy-acceptor` (`M-.` in Slime), which is probably
36+
`~/quicklisp/dists/quicklisp/software/hunchentoot-v1.2.38/`, you'll
37+
find the `root/` directory. It contains:
38+
39+
- an `errors/` directory, with the error templates `404.html` and `500.html`,
40+
- an `img/` directory,
41+
- an `index.html` file.
42+
43+
To serve another directory, we give the option `document-root` to
44+
`easy-acceptor`. We can also set the slot with its accessor:
45+
46+
~~~lisp
47+
(setf (hunchentoot:acceptor-document-root *acceptor*) #p"path/to/www")
48+
~~~
49+
50+
Let's create our `index.html` first. Put this in a new
51+
`www/index.html` at the current directory (of the lisp repl):
52+
53+
~~~html
54+
<html>
55+
<head>
56+
<title>Hello!</title>
57+
</head>
58+
<body>
59+
<h1>Hello local server!</h1>
60+
<p>
61+
We just served our own files.
62+
</p>
63+
</body>
64+
</html>
65+
~~~
66+
67+
Let's start a new acceptor on a new port:
68+
69+
~~~lisp
70+
(defvar *my-acceptor* (make-instance 'hunchentoot:easy-acceptor :port 4444
71+
:document-root #p"www/"))
72+
(hunchentoot:start *my-acceptor*)
73+
~~~
74+
75+
go to [http://127.0.0.1:4444/](http://127.0.0.1:4444/) and see the difference.
76+
77+
Note that we just created another web application on a different port on
78+
the same lisp image. This is already pretty cool.
79+
80+
81+
## Access your server from the internet
82+
83+
With Hunchentoot we have nothing to do, we can see the server from the
84+
internet right away.
85+
86+
If you evaluate this on your VPS:
87+
88+
(hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port 4242))
89+
90+
You can see it right away on your server's IP.
91+
92+
Stop it with `(hunchentoot:stop *)`.
93+
94+
Now on the next section, we'll create some routes to build a dynamic website.
95+
96+
97+
<!-- ## Sessions -->
98+
99+
<!-- ## Cookies -->

0 commit comments

Comments
 (0)