Refactor rendering of pages to centralize header layout.
Convert all pages to new layout
This commit is contained in:
parent
2b27e27a9b
commit
e4629d8edb
16 changed files with 117 additions and 182 deletions
|
@ -5,7 +5,7 @@ use hyper::server::*;
|
||||||
|
|
||||||
use build_config;
|
use build_config;
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
#[derive(Licenses)]
|
#[derive(Licenses)]
|
||||||
|
@ -81,14 +81,13 @@ impl Resource for AboutResource {
|
||||||
|
|
||||||
Box::new(head
|
Box::new(head
|
||||||
.and_then(move |head| {
|
.and_then(move |head| {
|
||||||
Ok(head
|
Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
None, // Hmm, should perhaps accept `base` as argument
|
||||||
base: None, // Hmm, should perhaps accept `base` as argument
|
"About Sausagewiki",
|
||||||
title: "About Sausagewiki",
|
Template {
|
||||||
body: &Template {
|
deps: &*LICENSE_INFOS
|
||||||
deps: &*LICENSE_INFOS
|
},
|
||||||
},
|
).to_string()))
|
||||||
}.to_string()))
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use hyper::server::*;
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use models;
|
use models;
|
||||||
use rendering::render_markdown;
|
use rendering::render_markdown;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
use super::changes_resource::QueryParameters;
|
use super::changes_resource::QueryParameters;
|
||||||
|
@ -81,8 +81,6 @@ impl Resource for ArticleRevisionResource {
|
||||||
link_current: &'a str,
|
link_current: &'a str,
|
||||||
timestamp_and_author: &'a str,
|
timestamp_and_author: &'a str,
|
||||||
diff_link: Option<String>,
|
diff_link: Option<String>,
|
||||||
|
|
||||||
title: &'a str,
|
|
||||||
rendered: String,
|
rendered: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,34 +89,32 @@ impl Resource for ArticleRevisionResource {
|
||||||
|
|
||||||
Box::new(head
|
Box::new(head
|
||||||
.and_then(move |head|
|
.and_then(move |head|
|
||||||
Ok(head
|
Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
Some("../../"), // Hmm, should perhaps accept `base` as argument
|
||||||
base: Some("../../"), // Hmm, should perhaps accept `base` as argument
|
&data.title,
|
||||||
title: &data.title,
|
&Template {
|
||||||
body: &Template {
|
link_current: &format!("_by_id/{}", data.article_id),
|
||||||
link_current: &format!("_by_id/{}", data.article_id),
|
timestamp_and_author: ×tamp_and_author(
|
||||||
timestamp_and_author: ×tamp_and_author(
|
data.sequence_number,
|
||||||
data.sequence_number,
|
data.article_id,
|
||||||
data.article_id,
|
&Local.from_utc_datetime(&data.created),
|
||||||
&Local.from_utc_datetime(&data.created),
|
data.author.as_ref().map(|x| &**x)
|
||||||
data.author.as_ref().map(|x| &**x)
|
),
|
||||||
),
|
diff_link:
|
||||||
diff_link:
|
if data.revision > 1 {
|
||||||
if data.revision > 1 {
|
Some(format!("_diff/{}?{}",
|
||||||
Some(format!("_diff/{}?{}",
|
data.article_id,
|
||||||
data.article_id,
|
diff_resource::QueryParameters::new(
|
||||||
diff_resource::QueryParameters::new(
|
data.revision as u32 - 1,
|
||||||
data.revision as u32 - 1,
|
data.revision as u32,
|
||||||
data.revision as u32,
|
)
|
||||||
)
|
))
|
||||||
))
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
},
|
||||||
},
|
rendered: render_markdown(&data.body),
|
||||||
title: &data.title,
|
},
|
||||||
rendered: render_markdown(&data.body),
|
).to_string()))
|
||||||
},
|
|
||||||
}.to_string()))
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use serde_urlencoded;
|
||||||
|
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use schema::article_revisions;
|
use schema::article_revisions;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use state::State;
|
use state::State;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
|
@ -352,18 +352,17 @@ impl Resource for ChangesResource {
|
||||||
}
|
}
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok(head
|
Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
None, // Hmm, should perhaps accept `base` as argument
|
||||||
base: None, // Hmm, should perhaps accept `base` as argument
|
"Changes",
|
||||||
title: "Changes",
|
Template {
|
||||||
body: &Template {
|
resource: &self,
|
||||||
resource: &self,
|
show_authors: self.show_authors,
|
||||||
show_authors: self.show_authors,
|
newer,
|
||||||
newer,
|
older,
|
||||||
older,
|
changes
|
||||||
changes
|
}
|
||||||
},
|
).to_string()))
|
||||||
}.to_string()))
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use hyper::header::ContentType;
|
||||||
use hyper::server::*;
|
use hyper::server::*;
|
||||||
|
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
pub struct HtmlResource {
|
pub struct HtmlResource {
|
||||||
|
@ -19,13 +19,6 @@ impl HtmlResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BartDisplay)]
|
|
||||||
#[template="templates/simple.html"]
|
|
||||||
struct Template<'a> {
|
|
||||||
title: &'a str,
|
|
||||||
html_body: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Resource for HtmlResource {
|
impl Resource for HtmlResource {
|
||||||
fn allow(&self) -> Vec<hyper::Method> {
|
fn allow(&self) -> Vec<hyper::Method> {
|
||||||
use hyper::Method::*;
|
use hyper::Method::*;
|
||||||
|
@ -44,15 +37,11 @@ impl Resource for HtmlResource {
|
||||||
|
|
||||||
Box::new(head
|
Box::new(head
|
||||||
.and_then(move |head| {
|
.and_then(move |head| {
|
||||||
Ok(head
|
Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
self.base,
|
||||||
base: self.base,
|
self.title,
|
||||||
title: self.title,
|
self.html_body
|
||||||
body: &Template {
|
).to_string()))
|
||||||
title: self.title,
|
|
||||||
html_body: self.html_body,
|
|
||||||
},
|
|
||||||
}.to_string()))
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use serde_urlencoded;
|
||||||
|
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use models::SearchResult;
|
use models::SearchResult;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use state::State;
|
use state::State;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
|
@ -198,19 +198,18 @@ impl Resource for SearchResource {
|
||||||
next,
|
next,
|
||||||
}).expect("Should never fail"))
|
}).expect("Should never fail"))
|
||||||
),
|
),
|
||||||
&ResponseType::Html => Ok(head
|
&ResponseType::Html => Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
None, // Hmm, should perhaps accept `base` as argument
|
||||||
base: None, // Hmm, should perhaps accept `base` as argument
|
"Search",
|
||||||
title: "Search",
|
&Template {
|
||||||
body: &Template {
|
query: self.query.as_ref().map(|x| &**x).unwrap_or(""),
|
||||||
query: self.query.as_ref().map(|x| &**x).unwrap_or(""),
|
hits: &data.iter()
|
||||||
hits: &data.iter()
|
.enumerate()
|
||||||
.enumerate()
|
.collect::<Vec<_>>(),
|
||||||
.collect::<Vec<_>>(),
|
prev,
|
||||||
prev,
|
next,
|
||||||
next,
|
},
|
||||||
},
|
).to_string())),
|
||||||
}.to_string())),
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use hyper::server::*;
|
||||||
|
|
||||||
use mimes::*;
|
use mimes::*;
|
||||||
use models::ArticleRevisionStub;
|
use models::ArticleRevisionStub;
|
||||||
use site::Layout;
|
use site::system_page;
|
||||||
use state::State;
|
use state::State;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
|
@ -44,14 +44,13 @@ impl Resource for SitemapResource {
|
||||||
|
|
||||||
Box::new(data.join(head)
|
Box::new(data.join(head)
|
||||||
.and_then(move |(articles, head)| {
|
.and_then(move |(articles, head)| {
|
||||||
Ok(head
|
Ok(head.with_body(system_page(
|
||||||
.with_body(Layout {
|
None, // Hmm, should perhaps accept `base` as argument
|
||||||
base: None, // Hmm, should perhaps accept `base` as argument
|
"Sitemap",
|
||||||
title: "Sitemap",
|
Template {
|
||||||
body: &Template {
|
articles: &articles,
|
||||||
articles: &articles,
|
},
|
||||||
},
|
).to_string()))
|
||||||
}.to_string()))
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
src/site.rs
42
src/site.rs
|
@ -31,7 +31,7 @@ header! { (XIdentity, "X-Identity") => [String] }
|
||||||
pub struct Layout<'a, T: 'a + fmt::Display> {
|
pub struct Layout<'a, T: 'a + fmt::Display> {
|
||||||
pub base: Option<&'a str>,
|
pub base: Option<&'a str>,
|
||||||
pub title: &'a str,
|
pub title: &'a str,
|
||||||
pub body: &'a T,
|
pub body: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a + fmt::Display> Layout<'a, T> {
|
impl<'a, T: 'a + fmt::Display> Layout<'a, T> {
|
||||||
|
@ -47,6 +47,28 @@ impl<'a, T: 'a + fmt::Display> Layout<'a, T> {
|
||||||
pub fn version(&self) -> &str { build_config::VERSION.as_str() }
|
pub fn version(&self) -> &str { build_config::VERSION.as_str() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(BartDisplay)]
|
||||||
|
#[template="templates/system_page_layout.html"]
|
||||||
|
pub struct SystemPageLayout<'a, T: 'a + fmt::Display> {
|
||||||
|
title: &'a str,
|
||||||
|
html_body: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn system_page<'a, T>(base: Option<&'a str>, title: &'a str, body: T)
|
||||||
|
-> Layout<'a, SystemPageLayout<'a, T>>
|
||||||
|
where
|
||||||
|
T: 'a + fmt::Display
|
||||||
|
{
|
||||||
|
Layout {
|
||||||
|
base,
|
||||||
|
title,
|
||||||
|
body: SystemPageLayout {
|
||||||
|
title,
|
||||||
|
html_body: body,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(BartDisplay)]
|
#[derive(BartDisplay)]
|
||||||
#[template = "templates/error/404.html"]
|
#[template = "templates/error/404.html"]
|
||||||
struct NotFound;
|
struct NotFound;
|
||||||
|
@ -68,11 +90,11 @@ impl Site {
|
||||||
fn not_found(base: Option<&str>) -> Response {
|
fn not_found(base: Option<&str>) -> Response {
|
||||||
Response::new()
|
Response::new()
|
||||||
.with_header(ContentType(TEXT_HTML.clone()))
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
.with_body(Layout {
|
.with_body(system_page(
|
||||||
base: base,
|
base,
|
||||||
title: "Not found",
|
"Not found",
|
||||||
body: &NotFound,
|
NotFound,
|
||||||
}.to_string())
|
).to_string())
|
||||||
.with_status(hyper::StatusCode::NotFound)
|
.with_status(hyper::StatusCode::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,11 +103,11 @@ impl Site {
|
||||||
|
|
||||||
Response::new()
|
Response::new()
|
||||||
.with_header(ContentType(TEXT_HTML.clone()))
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
.with_body(Layout {
|
.with_body(system_page(
|
||||||
base,
|
base,
|
||||||
title: "Internal server error",
|
"Internal server error",
|
||||||
body: &InternalServerError,
|
InternalServerError,
|
||||||
}.to_string())
|
).to_string())
|
||||||
.with_status(hyper::StatusCode::InternalServerError)
|
.with_status(hyper::StatusCode::InternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
<div class="container">
|
|
||||||
<div class="hero">
|
|
||||||
<header>
|
|
||||||
<h1>About Sausagewiki</h1>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<p>This site is running Sausagewiki, a simple, self-contained wiki engine,
|
<p>This site is running Sausagewiki, a simple, self-contained wiki engine,
|
||||||
version {{version()}}.</p>
|
version {{version()}}.</p>
|
||||||
<p>Copyright © 2017 Magnus Hovland Hoff.</p>
|
<p>Copyright © 2017 Magnus Hovland Hoff.</p>
|
||||||
|
@ -41,7 +33,3 @@ copyright holders and distributed under various licenses:
|
||||||
{{/deps}}
|
{{/deps}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>footer/default.html}}
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<p>
|
<p>
|
||||||
You are viewing an historical version of <a href="{{link_current}}">this article</a>,
|
You are viewing an historical version of <a href="{{link_current}}">this article</a>,
|
||||||
|
@ -11,11 +9,4 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rendered">
|
{{{rendered}}}
|
||||||
{{>article_contents.html}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
{{>footer/items.html}}
|
|
||||||
</footer>
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<h1>Changes</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<p>
|
<p>
|
||||||
These are the {{^newer}}most recent{{/newer}} changes
|
These are the {{^newer}}most recent{{/newer}} changes
|
||||||
made to{{{subject_clause()}}}{{#author()}} by {{.}}{{/author()}}.
|
made to{{{subject_clause()}}}{{#author()}} by {{.}}{{/author()}}.
|
||||||
|
@ -44,7 +38,3 @@
|
||||||
><li><a rel="last" href="{{.end}}">First changes</a></li
|
><li><a rel="last" href="{{.end}}">First changes</a></li
|
||||||
></ul></nav>{{/older}}
|
></ul></nav>{{/older}}
|
||||||
{{#changes?}}{{^older}}<p>There are no older changes.</p>{{/older}}{{/changes}}
|
{{#changes?}}{{^older}}<p>There are no older changes.</p>{{/older}}{{/changes}}
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>footer/default.html}}
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="hero">
|
||||||
|
<header>
|
||||||
|
<h1>{{#title}}{{#.removed}}<span class="removed">{{.}}</span>{{/.removed}}{{#.same}}{{.}}{{/.same}}{{#.added}}<span class="added">{{.}}</span>{{/.added}}{{/title}}</h1>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="notice">
|
<div class="notice">
|
||||||
<p>
|
<p>
|
||||||
You are viewing the difference between two {{#consecutive?}}consecutive{{/consecutive}}
|
You are viewing the difference between two {{#consecutive?}}consecutive{{/consecutive}}
|
||||||
|
@ -12,10 +18,6 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<header>
|
|
||||||
<h1>{{#title}}{{#.removed}}<span class="removed">{{.}}</span>{{/.removed}}{{#.same}}{{.}}{{/.same}}{{#.added}}<span class="added">{{.}}</span>{{/.added}}{{/title}}</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
<pre class="diff">{{#lines}}{{#.removed}}<span class="removed">{{.}}
|
<pre class="diff">{{#lines}}{{#.removed}}<span class="removed">{{.}}
|
||||||
</span>{{/.removed}}{{#.same}}<span class="same">{{.}}
|
</span>{{/.removed}}{{#.same}}<span class="same">{{.}}
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
<div class="container">
|
<p>This page was not found.</p>
|
||||||
<header>
|
|
||||||
<h1>Not found</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<p>This page was not found.</p>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>../footer/default.html}}
|
|
||||||
|
|
|
@ -1,11 +1 @@
|
||||||
<div class="container">
|
<p>An error has occurred.</p>
|
||||||
<header>
|
|
||||||
<h1>Internal server error</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<p>An error has occurred.</p>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>../footer/default.html}}
|
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<h1>Search</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
{{#hits?}}
|
{{#hits?}}
|
||||||
<p>Search results for the query <b>{{query}}</b>:</p>
|
<p>Search results for the query <b>{{query}}</b>:</p>
|
||||||
|
|
||||||
|
@ -25,8 +19,3 @@
|
||||||
{{^hits?}}
|
{{^hits?}}
|
||||||
<p>Your search for <b>{{query}}</b> gave no results.</p>
|
<p>Your search for <b>{{query}}</b> gave no results.</p>
|
||||||
{{/hits}}
|
{{/hits}}
|
||||||
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>footer/default.html}}
|
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
<div class="container">
|
|
||||||
<header>
|
|
||||||
<h1>Sitemap</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<ul class="dense"
|
<ul class="dense"
|
||||||
{{#articles}}
|
{{#articles}}
|
||||||
><li><a href="{{.link()}}">{{.title}}</a></li
|
><li><a href="{{.link()}}">{{.title}}</a></li
|
||||||
{{/articles}}
|
{{/articles}}
|
||||||
></ul>
|
></ul>
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{>footer/default.html}}
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div class="hero">
|
||||||
<header>
|
<header>
|
||||||
<h1>{{title}}</h1>
|
<h1>{{title}}</h1>
|
||||||
</header>
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
{{{html_body}}}
|
{{{html_body}}}
|
Loading…
Reference in a new issue