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:
|
||||
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) }
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -16,18 +16,21 @@
|
|||
// License along with this program. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#[macro_use]
|
||||
extern crate askama;
|
||||
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
|
||||
extern crate actix;
|
||||
extern crate actix_web;
|
||||
extern crate chrono;
|
||||
|
@ -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")),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue