refactor(templates): Use Askama for index template
This commit is contained in:
parent
d90dc2d77f
commit
f5badb97d3
4 changed files with 45 additions and 21 deletions
|
@ -28,6 +28,7 @@ use actix_web::http::StatusCode;
|
||||||
// Modules with foreign errors:
|
// Modules with foreign errors:
|
||||||
use actix;
|
use actix;
|
||||||
use actix_web;
|
use actix_web;
|
||||||
|
use askama;
|
||||||
use diesel;
|
use diesel;
|
||||||
use r2d2;
|
use r2d2;
|
||||||
use reqwest;
|
use reqwest;
|
||||||
|
@ -50,6 +51,9 @@ pub enum ConverseError {
|
||||||
#[fail(display = "a template rendering error occured: {}", reason)]
|
#[fail(display = "a template rendering error occured: {}", reason)]
|
||||||
Template { reason: String },
|
Template { reason: String },
|
||||||
|
|
||||||
|
#[fail(display = "a template rendering error occured: {}", reason)]
|
||||||
|
Askama { reason: String },
|
||||||
|
|
||||||
#[fail(display = "error occured during request handling: {}", error)]
|
#[fail(display = "error occured during request handling: {}", error)]
|
||||||
ActixWeb { error: actix_web::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 {
|
impl From<actix::MailboxError> for ConverseError {
|
||||||
fn from(error: actix::MailboxError) -> ConverseError {
|
fn from(error: actix::MailboxError) -> ConverseError {
|
||||||
ConverseError::Actix { error: Box::new(error) }
|
ConverseError::Actix { error: Box::new(error) }
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -16,18 +16,21 @@
|
||||||
// License along with this program. If not, see
|
// License along with this program. If not, see
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate askama;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate failure;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate failure;
|
|
||||||
|
|
||||||
extern crate actix;
|
extern crate actix;
|
||||||
extern crate actix_web;
|
extern crate actix_web;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
@ -137,7 +140,6 @@ fn start_renderer() -> Addr<Syn, Renderer> {
|
||||||
// location-dependent.
|
// location-dependent.
|
||||||
// Drawback is that template changes require recompilation ...
|
// Drawback is that template changes require recompilation ...
|
||||||
tera.add_raw_templates(vec![
|
tera.add_raw_templates(vec![
|
||||||
("index.html", include_str!("../templates/index.html")),
|
|
||||||
("post.html", include_str!("../templates/post.html")),
|
("post.html", include_str!("../templates/post.html")),
|
||||||
("search.html", include_str!("../templates/search.html")),
|
("search.html", include_str!("../templates/search.html")),
|
||||||
("thread.html", include_str!("../templates/thread.html")),
|
("thread.html", include_str!("../templates/thread.html")),
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
//! them.
|
//! them.
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
use askama::Template;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
use std::fmt;
|
||||||
use md5;
|
use md5;
|
||||||
use models::*;
|
use models::*;
|
||||||
use tera::{escape_html, Context, Tera};
|
use tera::{escape_html, Tera};
|
||||||
use chrono::prelude::{DateTime, Utc};
|
use chrono::prelude::{DateTime, Utc};
|
||||||
use comrak::{ComrakOptions, markdown_to_html};
|
use comrak::{ComrakOptions, markdown_to_html};
|
||||||
|
|
||||||
|
@ -39,11 +41,11 @@ impl Actor for Renderer {
|
||||||
|
|
||||||
/// Represents a data formatted for human consumption
|
/// Represents a data formatted for human consumption
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct FormattedDate(String);
|
struct FormattedDate(DateTime<Utc>);
|
||||||
|
|
||||||
impl From<DateTime<Utc>> for FormattedDate {
|
impl fmt::Display for FormattedDate {
|
||||||
fn from(date: DateTime<Utc>) -> Self {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
FormattedDate(format!("{}", date.format("%a %d %B %Y, %R")))
|
write!(f, "{}", self.0.format("%a %d %B %Y, %R"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,12 @@ struct IndexThread {
|
||||||
post_author: String,
|
post_author: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "index.html")]
|
||||||
|
struct IndexPageTemplate {
|
||||||
|
threads: Vec<IndexThread>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Handler<IndexPage> for Renderer {
|
impl Handler<IndexPage> for Renderer {
|
||||||
type Result = Result<String>;
|
type Result = Result<String>;
|
||||||
|
|
||||||
|
@ -71,17 +79,19 @@ impl Handler<IndexPage> for Renderer {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|thread| IndexThread {
|
.map(|thread| IndexThread {
|
||||||
id: thread.thread_id,
|
id: thread.thread_id,
|
||||||
title: escape_html(&thread.title),
|
title: thread.title, // escape_html(&thread.title),
|
||||||
sticky: thread.sticky,
|
sticky: thread.sticky,
|
||||||
posted: thread.posted.into(),
|
posted: FormattedDate(thread.posted),
|
||||||
author_name: thread.thread_author,
|
author_name: thread.thread_author,
|
||||||
post_author: thread.post_author,
|
post_author: thread.post_author,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut ctx = Context::new();
|
let tpl = IndexPageTemplate {
|
||||||
ctx.add("threads", &threads);
|
threads
|
||||||
Ok(self.tera.render("index.html", &ctx)?)
|
};
|
||||||
|
|
||||||
|
tpl.render().map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +108,7 @@ message!(ThreadPage, Result<String>);
|
||||||
struct RenderablePost {
|
struct RenderablePost {
|
||||||
id: i32,
|
id: i32,
|
||||||
body: String,
|
body: String,
|
||||||
posted: FormattedDate,
|
posted: String, // FormattedDate,
|
||||||
author_name: String,
|
author_name: String,
|
||||||
author_gravatar: String,
|
author_gravatar: String,
|
||||||
editable: bool,
|
editable: bool,
|
||||||
|
@ -127,7 +137,7 @@ fn prepare_thread(comrak: &ComrakOptions, page: ThreadPage) -> RenderableThreadP
|
||||||
RenderablePost {
|
RenderablePost {
|
||||||
id: post.id,
|
id: post.id,
|
||||||
body: markdown_to_html(&post.body, comrak),
|
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_name: post.author_name.clone(),
|
||||||
author_gravatar: md5_hex(post.author_email.as_bytes()),
|
author_gravatar: md5_hex(post.author_email.as_bytes()),
|
||||||
editable,
|
editable,
|
||||||
|
|
|
@ -41,21 +41,21 @@
|
||||||
<div class="mdl-card__supporting-text mdl-grid">
|
<div class="mdl-card__supporting-text mdl-grid">
|
||||||
<h4 class="mdl-cell mdl-cell--12-col">Latest threads:</h4>
|
<h4 class="mdl-cell mdl-cell--12-col">Latest threads:</h4>
|
||||||
<ul class="mdl-list">
|
<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">
|
<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 }}">
|
<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">
|
<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>
|
</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">
|
<span class="mdl-list__item-text-body">
|
||||||
Last reply by {{ thread.post_author }} on {{ thread.posted }}.
|
Last reply by {{ thread.post_author }} on {{ thread.posted }}.
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{%- endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue