1diff --git a/Cargo.lock b/Cargo.lock
2index d51075fd2fc1d0216c8a83c4629de538bf0762b3..9f33acf3c98818217ece2468b7dbc88e4f9ab63a 100644
3--- a/Cargo.lock
4+++ b/Cargo.lock
5@@ -3,6 +3,15 @@ # It is not intended for manual editing.
6 version = 3
7
8 [[package]]
9+name = "aho-corasick"
10+version = "0.7.18"
11+source = "registry+https://github.com/rust-lang/crates.io-index"
12+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
13+dependencies = [
14+ "memchr",
15+]
16+
17+[[package]]
18 name = "autocfg"
19 version = "1.1.0"
20 source = "registry+https://github.com/rust-lang/crates.io-index"
21@@ -242,6 +251,7 @@ name = "macroblog"
22 version = "0.1.0"
23 dependencies = [
24 "hyper",
25+ "regex",
26 "sailfish",
27 "tokio",
28 ]
29@@ -361,6 +371,23 @@ checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
30 dependencies = [
31 "bitflags",
32 ]
33+
34+[[package]]
35+name = "regex"
36+version = "1.5.5"
37+source = "registry+https://github.com/rust-lang/crates.io-index"
38+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
39+dependencies = [
40+ "aho-corasick",
41+ "memchr",
42+ "regex-syntax",
43+]
44+
45+[[package]]
46+name = "regex-syntax"
47+version = "0.6.25"
48+source = "registry+https://github.com/rust-lang/crates.io-index"
49+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
50
51 [[package]]
52 name = "ryu"
53diff --git a/Cargo.toml b/Cargo.toml
54index ecaba6d87d613106a7d5a542fd9e75529569d9f9..093a4d3252d590fdd23a2c4a3834b9bc0e143381 100644
55--- a/Cargo.toml
56+++ b/Cargo.toml
57@@ -7,6 +7,7 @@ [dependencies]
58 sailfish = "0.4.0"
59 hyper = { version = "0.14", features = ["full"] }
60 tokio = { version = "1", features = ["full"] }
61+regex = "1.5"
62
63 [profile.release]
64 opt-level = 'z'
65diff --git a/assets/pico.min.css b/templates/pico.min.css
66rename from assets/pico.min.css
67rename to templates/pico.min.css
68diff --git a/assets/post1.html b/assets/post1.html
69new file mode 100644
70index 0000000000000000000000000000000000000000..6eafb918836bf0d77fb26a94465247e9a58dbb6f
71--- /dev/null
72+++ b/assets/post1.html
73@@ -0,0 +1,9 @@
74+<section>
75+ <h2>Title</h2>
76+ <p>
77+ Nice content
78+ <code>
79+ My code here
80+ </code>
81+ </p>
82+</section>
83diff --git a/assets/post2.html b/assets/post2.html
84new file mode 100644
85index 0000000000000000000000000000000000000000..077734ef45473f4c25aa2d5cf58446966e6a278f
86--- /dev/null
87+++ b/assets/post2.html
88@@ -0,0 +1,9 @@
89+<section>
90+ <h2>Title</h2>
91+ <p>
92+ Nice content 2
93+ <code>
94+ My code here
95+ </code>
96+ </p>
97+</section>
98diff --git a/src/main.rs b/src/main.rs
99index 0c3565b8c097ceeabcf97b10987859bfa6e793b5..92f51a7e309faf481480fc0f6cb9329fe7978a9e 100644
100--- a/src/main.rs
101+++ b/src/main.rs
102@@ -3,38 +3,100 @@ use std::{include_str};
103 use std::net::SocketAddr;
104 use hyper::{Body, Request, Response, Server};
105 use hyper::service::{make_service_fn, service_fn};
106+use regex::Regex;
107 use sailfish::TemplateOnce;
108
109
110 #[derive(TemplateOnce)]
111 #[template(path = "index.html")]
112 struct IndexTemplate {
113- pico: &'static str,
114+ posts: [Post; 2],
115 }
116
117-const PICO_CSS: &str = include_str!("../assets/pico.min.css");
118+#[derive(TemplateOnce)]
119+#[template(path = "post.html")]
120+struct PostTemplate {
121+ content: &'static str,
122+}
123+
124+
125+struct Post(
126+ u8,
127+ &'static str,
128+ &'static str,
129+);
130+
131+const POSTS: [Post; 2] = [
132+ Post(
133+ 0,
134+ "K8S private gitlab registry using podman",
135+ include_str!("../assets/post1.html"),
136+ ),
137+ Post(
138+ 1,
139+ "Automation part 1",
140+ include_str!("../assets/post2.html"),
141+ ),
142+];
143
144-async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
145- let body = IndexTemplate { pico: PICO_CSS }
146+fn get_path_id(path: &str) -> usize {
147+ let re = Regex::new(r"(?P<id>\d+)").unwrap();
148+ let caps = re.captures(path).unwrap();
149+ let id = &caps["id"];
150+
151+ return id.parse::<usize>().unwrap();
152+}
153+
154+async fn index() -> Result<Response<Body>, Infallible> {
155+ let body = IndexTemplate { posts: POSTS }
156+ .render_once()
157+ .unwrap();
158+
159+ let resp: Response<Body> = Response::builder()
160+ .status(200)
161+ .header("posts-type", "text/html")
162+ .body(body.into())
163+ .unwrap();
164+
165+ Ok(resp)
166+}
167+
168+
169+async fn post(index: usize) -> Result<Response<Body>, Infallible> {
170+ let body = PostTemplate { content: POSTS[index].2 }
171 .render_once()
172 .unwrap();
173
174 let resp: Response<Body> = Response::builder()
175 .status(200)
176- .header("content-type", "text/html")
177+ .header("posts-type", "text/html")
178 .body(body.into())
179 .unwrap();
180
181 Ok(resp)
182 }
183
184+async fn request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
185+ let path = req.uri().path();
186+ if path == "/favicon.ico" {
187+ return index().await
188+ }
189+ if path != "/" {
190+ let index = get_path_id(&path);
191+ return post(index).await;
192+ }
193+
194+
195+ return index().await;
196+}
197+
198
199 #[tokio::main]
200 async fn main() {
201 let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
202
203 let make_svc = make_service_fn(|_conn| async {
204- Ok::<_, Infallible>(service_fn(hello_world))
205+ Ok::<_, Infallible>(service_fn(request))
206 });
207
208 let server = Server::bind(&addr).serve(make_svc);
209diff --git a/templates/head.html b/templates/head.html
210new file mode 100644
211index 0000000000000000000000000000000000000000..cc1bdb859110ca636673fbed766097ab0f81dae7
212--- /dev/null
213+++ b/templates/head.html
214@@ -0,0 +1,6 @@
215+<meta charset="UTF-8">
216+<meta name="viewport" content="width=device-width, initial-scale=1">
217+<title>Yet Another Blog</title>
218+<style>
219+ <% include!("pico.min.css"); %>
220+</style>
221diff --git a/templates/header.html b/templates/header.html
222new file mode 100644
223index 0000000000000000000000000000000000000000..e55cebef599eded1db5be972ddb071b808191601
224--- /dev/null
225+++ b/templates/header.html
226@@ -0,0 +1,18 @@
227+<header class="container">
228+ <nav class="container-fluid">
229+ <ul>
230+ <li><strong>Yet Another Blog</strong></li>
231+ </ul>
232+ <ul>
233+ <li><a class="secondary">Posts</a></li>
234+ <li><a class="secondary">Projects</a></li>
235+ <li><a class="secondary">Resume</a></li>
236+ </ul>
237+ </nav>
238+ <hgroup>
239+ <h2>
240+ A gathering of information about some things I do on my spare time. You can find me on gitlab , twitter and
241+ linkedin .
242+ </h2>
243+ </hgroup>
244+</header>
245diff --git a/templates/index.html b/templates/index.html
246index 90826de8e10534c0ce4fd7e9d947d98225630fe8..3558e0691376bc93ee0cc5e9d90ff8112e09802b 100644
247--- a/templates/index.html
248+++ b/templates/index.html
249@@ -1,48 +1,17 @@
250 <!DOCTYPE html>
251 <html data-theme="light" lang="en">
252 <head>
253- <meta charset="UTF-8">
254- <meta name="viewport" content="width=device-width, initial-scale=1">
255- <title>Yet Another Blog</title>
256- <style>
257- <%- pico %>
258- </style>
259+ <% include!("head.html"); %>
260 </head>
261 <body>
262-<header class="container">
263- <nav class="container-fluid">
264- <ul>
265- <li><strong>Yet Another Blog</strong></li>
266- </ul>
267- <ul>
268- <li><a class="secondary">Posts</a></li>
269- <li><a class="secondary">Projects</a></li>
270- <li><a class="secondary">Resume</a></li>
271- </ul>
272- </nav>
273- <hgroup>
274- <h2>
275- A gathering of information about some things I do on my spare time. You can find me on gitlab , twitter and
276- linkedin .
277- </h2>
278- </hgroup>
279-</header>
280-
281+<% include!("header.html"); %>
282 <main class="container">
283 <section>
284 <ul>
285- <li><a>K8S private gitlab registry using podman</a></li>
286- <li><a>K8S private gitlab registry using podman</a></li>
287+ <% for p in &posts { %>
288+ <li><a href="/post/<%- p.0 %>"><%- p.1 %></a></li>
289+ <% } %>
290 </ul>
291- </section>
292- <section>
293- <h2>Title</h2>
294- <p>
295- Nice content
296- <code>
297- My code here
298- </code>
299- </p>
300 </section>
301 </main>
302 </body>
303diff --git a/templates/post.html b/templates/post.html
304new file mode 100644
305index 0000000000000000000000000000000000000000..68211c1fd5b22ac6a6faa7f6dfa6b3994e52c2aa
306--- /dev/null
307+++ b/templates/post.html
308@@ -0,0 +1,13 @@
309+<!DOCTYPE html>
310+<html data-theme="light" lang="en">
311+<head>
312+ <% include!("head.html"); %>
313+</head>
314+<body>
315+<% include!("simple_header.html"); %>
316+<main class="container">
317+ <%- content %>
318+</section>
319+</main>
320+</body>
321+</html>
322diff --git a/templates/simple_header.html b/templates/simple_header.html
323new file mode 100644
324index 0000000000000000000000000000000000000000..0132334d05dc3d402fe303fc7b4f483f53e0e7fc
325--- /dev/null
326+++ b/templates/simple_header.html
327@@ -0,0 +1,12 @@
328+<header class="container">
329+ <nav class="container-fluid">
330+ <ul>
331+ <li><strong><a href="/">Yet Another Blog</a></strong></li>
332+ </ul>
333+ <ul>
334+ <li><a class="secondary">Posts</a></li>
335+ <li><a class="secondary">Projects</a></li>
336+ <li><a class="secondary">Resume</a></li>
337+ </ul>
338+ </nav>
339+</header>