diff options
-rw-r--r-- | src/errors.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 10 | ||||
-rw-r--r-- | src/render.rs | 34 | ||||
-rw-r--r-- | templates/index.html | 10 |
4 files changed, 45 insertions, 21 deletions
diff --git a/src/errors.rs b/src/errors.rs index c4c2be198e85..05642d0a8598 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -28,6 +28,7 @@ use actix_web::http::StatusCode; // Modules with foreign errors: use actix; use actix_web; +use askama; use diesel; use r2d2; use reqwest; @@ -50,6 +51,9 @@ pub enum ConverseError { #[fail(display = "a template rendering error occured: {}", reason)] Template { reason: String }, + #[fail(display = "a template rendering error occured: {}", reason)] + Askama { reason: String }, + #[fail(display = "error occured during request handling: {}", error)] ActixWeb { error: actix_web::Error }, @@ -88,6 +92,14 @@ impl From<tera::Error> for ConverseError { } } +impl From<askama::Error> for ConverseError { + fn from(error: askama::Error) -> ConverseError { + ConverseError::Askama { + reason: format!("{}", error), + } + } +} + impl From<actix::MailboxError> for ConverseError { fn from(error: actix::MailboxError) -> ConverseError { ConverseError::Actix { error: Box::new(error) } diff --git a/src/main.rs b/src/main.rs index 4db4ab5cc920..c68b75229f41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,16 +17,19 @@ // <http://www.gnu.org/licenses/>. #[macro_use] +extern crate askama; + +#[macro_use] extern crate diesel; #[macro_use] -extern crate log; +extern crate failure; #[macro_use] -extern crate serde_derive; +extern crate log; #[macro_use] -extern crate failure; +extern crate serde_derive; extern crate actix; extern crate actix_web; @@ -137,7 +140,6 @@ fn start_renderer() -> Addr<Syn, Renderer> { // location-dependent. // Drawback is that template changes require recompilation ... tera.add_raw_templates(vec![ - ("index.html", include_str!("../templates/index.html")), ("post.html", include_str!("../templates/post.html")), ("search.html", include_str!("../templates/search.html")), ("thread.html", include_str!("../templates/thread.html")), diff --git a/src/render.rs b/src/render.rs index 63a89d99ee31..ff8bd3ab8ee6 100644 --- a/src/render.rs +++ b/src/render.rs @@ -21,10 +21,12 @@ //! them. use actix::prelude::*; +use askama::Template; use errors::*; +use std::fmt; use md5; use models::*; -use tera::{escape_html, Context, Tera}; +use tera::{escape_html, Tera}; use chrono::prelude::{DateTime, Utc}; use comrak::{ComrakOptions, markdown_to_html}; @@ -39,11 +41,11 @@ impl Actor for Renderer { /// Represents a data formatted for human consumption #[derive(Debug, Serialize)] -struct FormattedDate(String); +struct FormattedDate(DateTime<Utc>); -impl From<DateTime<Utc>> for FormattedDate { - fn from(date: DateTime<Utc>) -> Self { - FormattedDate(format!("{}", date.format("%a %d %B %Y, %R"))) +impl fmt::Display for FormattedDate { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0.format("%a %d %B %Y, %R")) } } @@ -63,6 +65,12 @@ struct IndexThread { post_author: String, } +#[derive(Template)] +#[template(path = "index.html")] +struct IndexPageTemplate { + threads: Vec<IndexThread>, +} + impl Handler<IndexPage> for Renderer { type Result = Result<String>; @@ -71,17 +79,19 @@ impl Handler<IndexPage> for Renderer { .into_iter() .map(|thread| IndexThread { id: thread.thread_id, - title: escape_html(&thread.title), + title: thread.title, // escape_html(&thread.title), sticky: thread.sticky, - posted: thread.posted.into(), + posted: FormattedDate(thread.posted), author_name: thread.thread_author, post_author: thread.post_author, }) .collect(); - let mut ctx = Context::new(); - ctx.add("threads", &threads); - Ok(self.tera.render("index.html", &ctx)?) + let tpl = IndexPageTemplate { + threads + }; + + tpl.render().map_err(|e| e.into()) } } @@ -98,7 +108,7 @@ message!(ThreadPage, Result<String>); struct RenderablePost { id: i32, body: String, - posted: FormattedDate, + posted: String, // FormattedDate, author_name: String, author_gravatar: String, editable: bool, @@ -127,7 +137,7 @@ fn prepare_thread(comrak: &ComrakOptions, page: ThreadPage) -> RenderableThreadP RenderablePost { id: post.id, body: markdown_to_html(&post.body, comrak), - posted: post.posted.into(), + posted: format!("{}", FormattedDate(post.posted)), // post.posted.into(), author_name: post.author_name.clone(), author_gravatar: md5_hex(post.author_email.as_bytes()), editable, diff --git a/templates/index.html b/templates/index.html index c104938996e1..bff734bdab26 100644 --- a/templates/index.html +++ b/templates/index.html @@ -41,21 +41,21 @@ <div class="mdl-card__supporting-text mdl-grid"> <h4 class="mdl-cell mdl-cell--12-col">Latest threads:</h4> <ul class="mdl-list"> - {% for thread in threads -%} + {% for thread in threads %} <li class="mdl-list__item thread-list-item mdl-list__item--three-line"> <a class="thread-link mdl-color-text--grey-800" href="/thread/{{ thread.id }}"> - <span class="mdl-list__item-primary-content {% if not loop.last %}thread-divider{% endif %}"> + <span class="mdl-list__item-primary-content {% if loop.index < threads.len() %}thread-divider{% endif %}"> <button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored mdl-list__item-icon"> - <i class="material-icons">{% if thread.sticky -%} announcement {%- else -%} library_books{% endif %}</i> + <i class="material-icons">{% if thread.sticky %}announcement{% else %}library_books{% endif %}</i> </button> - <span class="thread-title">{{ thread.title | safe }}<span class="thread-author"> by {{ thread.author_name }}</span></span> + <span class="thread-title">{{ thread.title }}<span class="thread-author"> by {{ thread.author_name }}</span></span> <span class="mdl-list__item-text-body"> Last reply by {{ thread.post_author }} on {{ thread.posted }}. </span> </span> </a> </li> - {%- endfor %} + {% endfor %} </ul> </div> </div> |