about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2018-05-22T16·35+0200
committerVincent Ambo <github@tazj.in>2018-05-22T18·44+0200
commitf5badb97d333ffbc2d294cbff3afda0bd4879b56 (patch)
tree8bb9d91964f45f6d8ce944b946746512f2adab91
parentd90dc2d77fd813257e24a45456cb6b10791999e6 (diff)
refactor(templates): Use Askama for index template
-rw-r--r--src/errors.rs12
-rw-r--r--src/main.rs10
-rw-r--r--src/render.rs34
-rw-r--r--templates/index.html10
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>