diff --git a/ekc3/ekc3.c b/ekc3/ekc3.c
index c210b3e..df9649f 100644
--- a/ekc3/ekc3.c
+++ b/ekc3/ekc3.c
@@ -450,8 +450,9 @@ sw ekc3_render_buf (s_buf *in)
return r;
}
-sw ekc3_render_file (const s_str *path)
+s_str * ekc3_render_file (const s_str *path, s_str *dest)
{
+ s_buf buf;
s_tag *file_dir;
s_tag file_dir_save;
s_tag *file_path;
@@ -460,6 +461,7 @@ sw ekc3_render_file (const s_str *path)
s_buf in;
char in_data[BUF_SIZE];
sw r;
+ s_str tmp;
buf_init(&in, false, BUF_SIZE, in_data);
fp = file_open(path->ptr.pchar, "rb");
if (! fp)
@@ -474,7 +476,7 @@ sw ekc3_render_file (const s_str *path)
file_path = frame_get_w(&g_kc3_env.global_frame, &g_sym___FILE__);
file_path_save = *file_path;
file_path->data.str = *path;
- r = ekc3_render_buf(&in);
+ if (! ekc3_render_buf(&in, &tmp))
tag_clean(file_dir);
*file_dir = file_dir_save;
*file_path = file_path_save;
diff --git a/lib/kc3/0.1/ekc3.kc3 b/lib/kc3/0.1/ekc3.kc3
index 5e69e2e..625c6a9 100644
--- a/lib/kc3/0.1/ekc3.kc3
+++ b/lib/kc3/0.1/ekc3.kc3
@@ -2,6 +2,6 @@ defmodule EKC3 do
dlopen(__DIR__ + "ekc3.so")
- def render_file = cfn Sw "ekc3_render_file" (Str)
+ def render_file = cfn Str "ekc3_render_file" (Str, Result)
end
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 21c7344..26c9977 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -57,22 +57,30 @@ defmodule HTTPd do
end
Socket.close(socket)
}
-
+
+ def load_app = fn () {
+ HTTP.mime_type_load("config/mime.types")
+ controllers_dir = "app/controllers/"
+ controllers = File.list(controllers_dir)
+ List.each(controllers, fn (c) {
+ load(controllers_dir + c)
+ })
+ if (File.exists?("config/routes.kc3")) do
+ load("config/routes.kc3")
+ end
+ }
+
def main = fn {
() {
host = getenv("KC3_HTTPD_HOST")
port = getenv("KC3_HTTPD_PORT")
event_base = Event.base_new()
- HTTP.mime_type_load("config/mime.types")
- if (File.exists?("config/routes.kc3")) do
- load("config/routes")
- end
+ load_app()
server(host, port)
}
(host, port) {
- HTTP.mime_type_load("mime.types")
event_base = Event.base_new()
- load("config/routes")
+ load_app()
server(host, port)
}
}
diff --git a/lib/kc3/0.1/list.kc3 b/lib/kc3/0.1/list.kc3
index 7dc5b80..b4d5d53 100644
--- a/lib/kc3/0.1/list.kc3
+++ b/lib/kc3/0.1/list.kc3
@@ -4,6 +4,11 @@ defmodule List do
def cast = cfn List "list_init_cast" (Result, Sym, Tag)
+ def each = fn {
+ ([], _) { :ok }
+ ([a | b], f) { f(a); each(b, f) }
+ }
+
def has? = cfn Bool "list_has" (List, Tag, Result)
def map = fn {
diff --git a/test/ekc3/title.html.ekc3 b/test/ekc3/title.html.ekc3
index 7175a13..f692951 100644
--- a/test/ekc3/title.html.ekc3
+++ b/test/ekc3/title.html.ekc3
@@ -1,3 +1,4 @@
+<!doctype html>
<html>
<head>
<title><%= title %></title>
diff --git a/test/httpd/app/controllers/doc_controller.kc3 b/test/httpd/app/controllers/doc_controller.kc3
new file mode 100644
index 0000000..0df7bd5
--- /dev/null
+++ b/test/httpd/app/controllers/doc_controller.kc3
@@ -0,0 +1,18 @@
+defmodule DocController do
+
+ def route = fn (request) {
+ if (request.method == :get) do
+ path_md = ".#{request.url}.md"
+ if File.exists?(path_md) do
+ md = File.read(path_md)
+ body = Markdown.to_html_str(md)
+ %HTTP.Response{body: body}
+ else
+ HTTPd.error_404_page(request)
+ end
+ else
+ HTTPd.error_404_page(request)
+ end
+ }
+
+end
diff --git a/test/httpd/app/templates/layout.html.ekc3 b/test/httpd/app/templates/layout.html.ekc3
new file mode 100644
index 0000000..afb6e97
--- /dev/null
+++ b/test/httpd/app/templates/layout.html.ekc3
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+ <head>
+ <title><%= title %></title>
+ </head>
+ <body>
+ <%= raw EKC3.render_file("app/templates/nav.html.ekc3") %>
+ <div class="col-3">
+ </div>
+ <div class="col-9">
+ <%= raw md_html %>
+ </div>
+ </body>
+</html>
diff --git a/test/httpd/app/templates/nav.html.ekc3 b/test/httpd/app/templates/nav.html.ekc3
new file mode 100644
index 0000000..7cb3598
--- /dev/null
+++ b/test/httpd/app/templates/nav.html.ekc3
@@ -0,0 +1,17 @@
+<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
+ <div class="container">
+ <a class="navbar-brand" href="/">
+ <div class="doc-logo">
+ <span><b>⬢</b></span> kc3-lang
+ </div>
+ </a>
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
+ <ul class="navbar-text me-auto mb-2 mb-sm-0">
+ <div class="nav-item">v0.1.13</div>
+ </ul>
+ </div>
+ </div>
+</nav>
diff --git a/test/httpd/config/routes.kc3 b/test/httpd/config/routes.kc3
new file mode 100644
index 0000000..1834cf5
--- /dev/null
+++ b/test/httpd/config/routes.kc3
@@ -0,0 +1,4 @@
+def HTTPd.routes = []
+
+def_route("/doc/", DocController.route)
+def_route("/", static_controller)