diff options
author | Martin Ashby <martin@ashbysoft.com> | 2022-12-30 00:45:57 +0000 |
---|---|---|
committer | Martin Ashby <martin@ashbysoft.com> | 2022-12-30 00:45:57 +0000 |
commit | 671f850c4fb72941c111edb6dff1030839b0dd55 (patch) | |
tree | e2e066891c85aba3eff5bb76c8e0d81a658a2cb9 | |
parent | 9be5acc275711d0a6a717ac5564a86185ec1d613 (diff) | |
download | mfashby.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-- | Caddyfile | 6 | ||||
-rw-r--r-- | comments/src/main.rs | 45 | ||||
-rw-r--r-- | comments/templates/comments.html | 10 | ||||
-rw-r--r-- | comments/templates/form.html | 6 | ||||
-rw-r--r-- | themes/XMin/layouts/partials/foot_custom.html | 21 | ||||
-rw-r--r-- | themes/XMin/static/css/style.css | 12 |
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 +} |