Custom 404 page now template driven.

Since we are using a builtin template, we can be assured to have the
target file in place. Middleware renamed since it is bound directly to
the concept of handling 404s.
This commit is contained in:
Owen Nelson 2018-06-25 23:24:57 -07:00
parent 7ab22528a5
commit 8f460dc28b
4 changed files with 34 additions and 14 deletions

View file

@ -526,6 +526,7 @@ impl Site {
if self.config.generate_rss { if self.config.generate_rss {
self.render_rss_feed()?; self.render_rss_feed()?;
} }
self.render_404()?;
self.render_robots()?; self.render_robots()?;
// `render_categories` and `render_tags` will check whether the config allows // `render_categories` and `render_tags` will check whether the config allows
// them to render or not // them to render or not
@ -660,6 +661,15 @@ impl Site {
Ok(()) Ok(())
} }
/// Renders 404.html
pub fn render_404(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?;
create_file(
&self.output_path.join("404.html"),
&render_template("404.html", &self.tera, &Context::new(), &self.config.theme)?
)
}
/// Renders robots.txt /// Renders robots.txt
pub fn render_robots(&self) -> Result<()> { pub fn render_robots(&self) -> Result<()> {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;

View file

@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<title>File Not Found: 404.</title>
</head>
<body>
<h1>Oops!</h1>
<h2>File Not Found: 404.</h2>
</body>
</html>

View file

@ -24,6 +24,7 @@ lazy_static! {
pub static ref GUTENBERG_TERA: Tera = { pub static ref GUTENBERG_TERA: Tera = {
let mut tera = Tera::default(); let mut tera = Tera::default();
tera.add_raw_templates(vec![ tera.add_raw_templates(vec![
("404.html", include_str!("builtins/404.html")),
("rss.xml", include_str!("builtins/rss.xml")), ("rss.xml", include_str!("builtins/rss.xml")),
("sitemap.xml", include_str!("builtins/sitemap.xml")), ("sitemap.xml", include_str!("builtins/sitemap.xml")),
("robots.txt", include_str!("builtins/robots.txt")), ("robots.txt", include_str!("builtins/robots.txt")),

View file

@ -59,9 +59,11 @@ enum ChangeKind {
// errors // errors
const LIVE_RELOAD: &'static str = include_str!("livereload.js"); const LIVE_RELOAD: &'static str = include_str!("livereload.js");
struct ErrCatcher; struct NotFoundHandler {
rendered_template: PathBuf,
}
impl<S> Middleware<S> for ErrCatcher { impl<S> Middleware<S> for NotFoundHandler {
fn start(&self, _req: &mut HttpRequest<S>) -> actix_web::Result<Started> { fn start(&self, _req: &mut HttpRequest<S>) -> actix_web::Result<Started> {
Ok(Started::Done) Ok(Started::Done)
} }
@ -72,17 +74,14 @@ impl<S> Middleware<S> for ErrCatcher {
mut resp: HttpResponse, mut resp: HttpResponse,
) -> actix_web::Result<Response> { ) -> actix_web::Result<Response> {
if http::StatusCode::NOT_FOUND == resp.status() { if http::StatusCode::NOT_FOUND == resp.status() {
let not_found_page = "static/error/404.html"; let mut fh = File::open(&self.rendered_template)?;
if let Ok(mut fh) = File::open(&not_found_page) { let mut buf: Vec<u8> = vec![];
println!("Using {} to handle missing file.", &not_found_page); let _ = fh.read_to_end(&mut buf)?;
let mut buf: Vec<u8> = vec![]; resp.replace_body(buf);
let _ = fh.read_to_end(&mut buf)?; resp.headers_mut().insert(
resp.replace_body(buf); http::header::CONTENT_TYPE,
resp.headers_mut().insert( http::header::HeaderValue::from_static("text/html"),
http::header::CONTENT_TYPE, );
http::header::HeaderValue::from_static("text/html"),
);
}
} }
Ok(Response::Done(resp)) Ok(Response::Done(resp))
} }
@ -184,7 +183,7 @@ pub fn serve(interface: &str, port: &str, output_dir: &str, base_url: &str, conf
let sys = actix::System::new("http-server"); let sys = actix::System::new("http-server");
server::new(move || { server::new(move || {
App::new() App::new()
.middleware(ErrCatcher) .middleware(NotFoundHandler { rendered_template: static_root.join("404.html") })
.resource(r"/livereload.js", |r| r.f(livereload_handler)) .resource(r"/livereload.js", |r| r.f(livereload_handler))
// Start a webserver that serves the `output_dir` directory // Start a webserver that serves the `output_dir` directory
.handler(r"/", fs::StaticFiles::new(&static_root) .handler(r"/", fs::StaticFiles::new(&static_root)