Introduce base href

This commit is contained in:
Magnus Hoff 2017-10-13 16:05:22 +02:00
parent f2de8111c9
commit b5bcd66011
6 changed files with 25 additions and 4 deletions

View file

@ -65,6 +65,7 @@ impl Resource for ArticleResource {
.and_then(move |(data, head)| { .and_then(move |(data, head)| {
Ok(head Ok(head
.with_body(Layout { .with_body(Layout {
base: None, // Hmm, should perhaps accept `base` as argument
title: &data.title, title: &data.title,
body: &Template { body: &Template {
article_id: data.article_id, article_id: data.article_id,

View file

@ -73,6 +73,7 @@ impl Resource for ChangesResource {
Ok(head Ok(head
.with_body(Layout { .with_body(Layout {
base: None, // Hmm, should perhaps accept `base` as argument
title: "Changes", title: "Changes",
body: &Template { changes }, body: &Template { changes },
style_css_checksum: StyleCss::checksum(), style_css_checksum: StyleCss::checksum(),

View file

@ -72,6 +72,7 @@ impl Resource for NewArticleResource {
.and_then(move |head| { .and_then(move |head| {
Ok(head Ok(head
.with_body(Layout { .with_body(Layout {
base: None, // Hmm, should perhaps accept `base` as argument
title: &title, title: &title,
body: &Template { body: &Template {
article_id: NDASH, article_id: NDASH,

View file

@ -60,6 +60,7 @@ impl Resource for SitemapResource {
Ok(head Ok(head
.with_body(Layout { .with_body(Layout {
base: None, // Hmm, should perhaps accept `base` as argument
title: "Sitemap", title: "Sitemap",
body: &Template { articles }, body: &Template { articles },
style_css_checksum: StyleCss::checksum(), style_css_checksum: StyleCss::checksum(),

View file

@ -20,6 +20,7 @@ lazy_static! {
#[derive(BartDisplay)] #[derive(BartDisplay)]
#[template = "templates/layout.html"] #[template = "templates/layout.html"]
pub struct Layout<'a, T: 'a + fmt::Display> { pub struct Layout<'a, T: 'a + fmt::Display> {
pub base: Option<&'a str>,
pub title: &'a str, pub title: &'a str,
pub body: &'a T, pub body: &'a T,
pub style_css_checksum: &'a str, pub style_css_checksum: &'a str,
@ -42,10 +43,11 @@ impl Site {
Site { root } Site { root }
} }
fn not_found() -> 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(Layout {
base: base,
title: "Not found", title: "Not found",
body: &NotFound, body: &NotFound,
style_css_checksum: StyleCss::checksum(), style_css_checksum: StyleCss::checksum(),
@ -53,12 +55,13 @@ impl Site {
.with_status(hyper::StatusCode::NotFound) .with_status(hyper::StatusCode::NotFound)
} }
fn internal_server_error(err: Box<::std::error::Error + Send + Sync>) -> Response { fn internal_server_error(base: Option<&str>, err: Box<::std::error::Error + Send + Sync>) -> Response {
eprintln!("Internal Server Error:\n{:#?}", err); eprintln!("Internal Server Error:\n{:#?}", err);
Response::new() Response::new()
.with_header(ContentType(TEXT_HTML.clone())) .with_header(ContentType(TEXT_HTML.clone()))
.with_body(Layout { .with_body(Layout {
base,
title: "Internal server error", title: "Internal server error",
body: &InternalServerError, body: &InternalServerError,
style_css_checksum: StyleCss::checksum(), style_css_checksum: StyleCss::checksum(),
@ -67,6 +70,16 @@ impl Site {
} }
} }
fn root_base_from_request_uri(path: &str) -> Option<String> {
assert!(path.starts_with("/"));
let slashes = path[1..].matches('/').count();
match slashes {
0 => None,
n => Some(::std::iter::repeat("../").take(n).collect())
}
}
impl Service for Site { impl Service for Site {
type Request = Request; type Request = Request;
type Response = Response; type Response = Response;
@ -77,6 +90,9 @@ impl Service for Site {
let (method, uri, _http_version, _headers, body) = req.deconstruct(); let (method, uri, _http_version, _headers, body) = req.deconstruct();
println!("{} {}", method, uri); println!("{} {}", method, uri);
let base = root_base_from_request_uri(uri.path());
let base2 = base.clone(); // Bah, stupid clone
Box::new(self.root.lookup(uri.path(), uri.query()) Box::new(self.root.lookup(uri.path(), uri.query())
.and_then(move |resource| match resource { .and_then(move |resource| match resource {
Some(resource) => { Some(resource) => {
@ -89,9 +105,9 @@ impl Service for Site {
_ => Box::new(futures::finished(resource.method_not_allowed())) _ => Box::new(futures::finished(resource.method_not_allowed()))
} }
}, },
None => Box::new(futures::finished(Self::not_found())) None => Box::new(futures::finished(Self::not_found(base.as_ref().map(|x| &**x))))
}) })
.or_else(|err| Ok(Self::internal_server_error(err))) .or_else(move |err| Ok(Self::internal_server_error(base2.as_ref().map(|x| &**x), err)))
) )
} }
} }

View file

@ -3,6 +3,7 @@
<head> <head>
<title>{{title}}</title> <title>{{title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
{{#base}}<base href="{{.}}">{{/base}}
<link rel=preload href="_assets/amatic-sc-v9-latin-regular.woff" as=font crossorigin> <link rel=preload href="_assets/amatic-sc-v9-latin-regular.woff" as=font crossorigin>
<link href="_assets/style-{{style_css_checksum}}.css" rel="stylesheet"> <link href="_assets/style-{{style_css_checksum}}.css" rel="stylesheet">
</head> </head>