aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2022-12-30 00:45:57 +0000
committerMartin Ashby <martin@ashbysoft.com>2022-12-30 00:45:57 +0000
commit671f850c4fb72941c111edb6dff1030839b0dd55 (patch)
treee2e066891c85aba3eff5bb76c8e0d81a658a2cb9
parent9be5acc275711d0a6a717ac5564a86185ec1d613 (diff)
downloadmfashby.net-671f850c4fb72941c111edb6dff1030839b0dd55.tar.gz
mfashby.net-671f850c4fb72941c111edb6dff1030839b0dd55.tar.bz2
mfashby.net-671f850c4fb72941c111edb6dff1030839b0dd55.tar.xz
mfashby.net-671f850c4fb72941c111edb6dff1030839b0dd55.zip
Comments are basically functional.
Added example config.
-rw-r--r--Caddyfile6
-rw-r--r--comments/src/main.rs45
-rw-r--r--comments/templates/comments.html10
-rw-r--r--comments/templates/form.html6
-rw-r--r--themes/XMin/layouts/partials/foot_custom.html21
-rw-r--r--themes/XMin/static/css/style.css12
6 files changed, 71 insertions, 29 deletions
diff --git a/Caddyfile b/Caddyfile
new file mode 100644
index 0000000..cef71f9
--- /dev/null
+++ b/Caddyfile
@@ -0,0 +1,6 @@
+http://localhost:8080 {
+ root * public
+ reverse_proxy /api/* localhost:5678
+ file_server
+}
+
diff --git a/comments/src/main.rs b/comments/src/main.rs
index 95cd9ae..2bc11fa 100644
--- a/comments/src/main.rs
+++ b/comments/src/main.rs
@@ -10,7 +10,7 @@
use askama::Template;
use axum::{
extract::{Query, Form, State},
- response::Redirect,
+ response::{Redirect,Html},
http::StatusCode,
routing::get,
Router,
@@ -29,14 +29,17 @@ use std::{net::SocketAddr, time::Duration};
#[derive(Clone)]
struct Ctx {
pool: PgPool,
+ base_path: String,
}
#[tokio::main]
async fn main() {
+ let base_path = std::env::var("BASE_PATH")
+ .unwrap_or_else(|_| "/api".to_string());
+
let db_connection_str = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://postgres:password@localhost".to_string());
- // setup connection pool
let pool = PgPoolOptions::new()
.max_connections(5)
.connect_timeout(Duration::from_secs(3))
@@ -48,22 +51,21 @@ async fn main() {
.await
.expect("failed to run migrations");
- let ctx = Ctx {pool};
+ let ctx = Ctx {pool, base_path: base_path.clone()};
- // build our application with some routes
let app = Router::new()
- .route(
- "/form",
- get(get_form),
- )
- .route(
- "/comment",
- get(get_comments).post(post_comments),
- )
- .with_state(ctx);
+ .nest(&base_path, Router::new()
+ .route(
+ "/form",
+ get(get_form),
+ )
+ .route(
+ "/comment",
+ get(get_comments).post(post_comments),
+ )
+ .with_state(ctx));
- // run it with hyper
- let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
+ let addr = SocketAddr::from(([127, 0, 0, 1], 5678));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
@@ -81,19 +83,20 @@ struct CommentForm {
url: String,
capcha_question: String,
capcha_id: Uuid,
+ base_path: String,
}
async fn get_form(
State(ctx): State<Ctx>,
Query(uq): Query<UrlQuery>
-) -> Result<String, (StatusCode, String)> {
+) -> Result<Html<String>, (StatusCode, String)> {
let capcha = sqlx::query!("select id, question from capchas order by random() limit 1")
.fetch_one(&ctx.pool)
.await
.map_err(internal_error)?;
- let c = CommentForm{url: uq.url, capcha_question: capcha.question, capcha_id: capcha.id};
+ let c = CommentForm{url: uq.url, capcha_question: capcha.question, capcha_id: capcha.id, base_path: ctx.base_path};
let res = c.render().map_err(internal_error)?;
- Ok(res)
+ Ok(Html(res))
}
#[derive(Template)]
@@ -109,8 +112,8 @@ struct Comment {
async fn get_comments(
State(ctx): State<Ctx>,
- Query(uq): Query<UrlQuery>) -> Result<String, (StatusCode,String)> {
- let comments = sqlx::query!("select author,comment,ts from comments where url = $1", uq.url)
+ Query(uq): Query<UrlQuery>) -> Result<Html<String>, (StatusCode,String)> {
+ let comments = sqlx::query!("select author,comment,ts from comments where url = $1 order by ts", uq.url)
.fetch_all(&ctx.pool)
.await
.map_err(internal_error)?;
@@ -123,7 +126,7 @@ async fn get_comments(
}).collect();
let c = Comments{comments: render_comments};
let res = c.render().map_err(internal_error)?;
- Ok(res)
+ Ok(Html(res))
}
#[derive(Deserialize)]
diff --git a/comments/templates/comments.html b/comments/templates/comments.html
index 72c4a46..e64ba1c 100644
--- a/comments/templates/comments.html
+++ b/comments/templates/comments.html
@@ -1,9 +1,9 @@
-<ul>
+<ul class="comments">
{% for comment in comments -%}
- <li>
- <span>{{ comment.author }}</span>
- <p>{{ comment.comment }}</p>
- <span>{{ comment.ts }}</span>
+ <li class="comment">
+ <span class="comment author">{{ comment.author }}</span>
+ <p class="comment content">{{ comment.comment }}</p>
+ <span class="comment timestamp">{{ comment.ts }}</span>
</li>
{%- endfor %}
</ul>
diff --git a/comments/templates/form.html b/comments/templates/form.html
index 09fc81f..1f1692c 100644
--- a/comments/templates/form.html
+++ b/comments/templates/form.html
@@ -1,11 +1,11 @@
-<form action="/api/comments">
+<form action="{{ base_path }}/comment" method="post">
<input type="hidden" name="url" value="{{ url }}"><br>
<input type="hidden" name="capcha_id" value="{{ capcha_id }}"><br>
<label for="author">Name:</label><br>
<input type="text" id="author" name="author"><br>
<label for="comment">Comment:</label><br>
- <input type="text" id="comment" name="lname">
- <label for="capcha">{{ capcha_question }}</label>
+ <input type="text" id="comment" name="comment"><br>
+ <label for="capcha">{{ capcha_question }}</label><br>
<input type="text" id="capcha" name="capcha_answer"><br>
<input type="submit" value="Submit">
</form>
diff --git a/themes/XMin/layouts/partials/foot_custom.html b/themes/XMin/layouts/partials/foot_custom.html
index 73b86a3..754b722 100644
--- a/themes/XMin/layouts/partials/foot_custom.html
+++ b/themes/XMin/layouts/partials/foot_custom.html
@@ -11,3 +11,24 @@
<title>RSS</title>
<path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg>
</a>
+
+<h2>comments</h2>
+<div style="visibility: hidden" id="comments">comments go here</div>
+<div style="visibility: hidden" id="comment_form">comment form goes here</div>
+<script>
+ let comments = document.getElementById("comments");
+ fetch(document.location.origin + "/api/comment?url=" + document.location.href)
+ .then((response) => response.text())
+ .then((data) => {
+ comments.innerHTML = data;
+ comments.style.visibility = "visible";
+ });
+ let form = document.getElementById("comment_form");
+ fetch(document.location.origin + "/api/form?url=" + document.location.href)
+ .then((response) => response.text())
+ .then((data) => {
+ form.innerHTML = data;
+ form.style.visibility = "visible";
+ });
+</script>
+<noscript>Comments disabled without javascript!</noscript>
diff --git a/themes/XMin/static/css/style.css b/themes/XMin/static/css/style.css
index 48b563e..6288f17 100644
--- a/themes/XMin/static/css/style.css
+++ b/themes/XMin/static/css/style.css
@@ -49,3 +49,15 @@ table {
table thead th { border-bottom: 1px solid #ddd; }
th, td { padding: 5px; }
thead, tfoot, tr:nth-child(even) { background: #eee; }
+
+ul.comments {
+ list-style: square inside
+ margin: 0;
+ padding: 0;
+}
+span.comment.author {
+ font-weight: bold
+}
+span.comment.timestamp {
+ color: grey
+}