Render page template within an HTML boilerplate

This commit is contained in:
Timothy Warren 2019-03-29 14:50:48 -04:00
parent c17b5642c0
commit 69444ebcaa
11 changed files with 93 additions and 84 deletions

View File

@ -31,19 +31,19 @@ help:
.PHONY: build run test bench doc examples graphs clean .PHONY: build run test bench doc examples graphs clean
build: build:
$(CARGO) build cargo build
run: run:
$(CARGO) run cargo run
clean: clean:
$(CARGO) clean cargo clean
doc: doc:
$(CARGO) doc cargo doc
test: test:
$(CARGO) test cargo test
graphs-png: $(GRAPH_IMG) graphs-png: $(GRAPH_IMG)
design/%.png: design/%.gv design/%.png: design/%.gv

View File

@ -1,11 +1,57 @@
use handlebars_iron as hbi; use handlebars::{Handlebars, no_escape};
use handlebars_iron::{DirectorySource, HandlebarsEngine};
use handlebars_iron::handlebars::to_json;
use handlebars_iron::Template;
use iron::prelude::{Request, Response}; use iron::prelude::{Request, Response};
use iron::{IronResult, Set, status}; use iron::{IronResult, Set, status};
use mount::Mount; use mount::Mount;
use serde::ser::Serialize as ToJson; use serde::ser::Serialize as ToJson;
use serde_json::value::Map;
use staticfile::Static; use staticfile::Static;
use std::error::Error;
use std::path::Path; use std::path::Path;
use std::sync::Arc;
pub fn template_engine() -> Arc<HandlebarsEngine> {
let views_ext = ".hbs";
let views_path = "./src/views";
let mut hbs = Handlebars::new();
// @TODO Find better solution for rendering included template file
hbs.register_escape_fn(no_escape);
let mut hbse = HandlebarsEngine::from(hbs);
hbse.add(Box::new(
DirectorySource::new(views_path, views_ext)
));
if let Err(r) = hbse.reload() {
panic!("{:?}", r.description());
}
let hbse_ref = Arc::new(hbse);
if cfg!(debug_assertions) {
println!("Templates are being watched.");
use handlebars_iron::Watchable;
hbse_ref.watch(views_path);
}
hbse_ref
}
pub fn render_page<T: ToJson>(name: &str, template_data: T) -> Template {
let template_engine = template_engine().clone();
let template_registry = template_engine.handlebars_mut();
let page = template_registry.render(name, &template_data).unwrap();
let mut data = Map::new();
data.insert("page".to_string(), to_json(page));
Template::new("layout/base", data)
}
pub struct AssetsHandler; pub struct AssetsHandler;
@ -18,15 +64,14 @@ impl AssetsHandler {
} }
} }
fn render_page<T: ToJson>(name: &str, value: T) -> hbi::Template {
unimplemented!();
}
pub fn hello_world (_request: &mut Request) -> IronResult<Response> { pub fn hello_world (_request: &mut Request) -> IronResult<Response> {
use handlebars_iron::Template; use serde_json::value::{Map, Value};
let mut data = Map::new();
data.insert("title".to_string(), to_json(&"Media Collection CRUD".to_owned()));
let mut response = Response::new(); let mut response = Response::new();
response.set_mut(Template::new("index","".to_string())) response.set_mut(render_page("index", data))
.set_mut(status::Ok); .set_mut(status::Ok);
Ok(response) Ok(response)

View File

@ -2,5 +2,5 @@ pub mod chain;
pub mod db; pub mod db;
pub mod handlers; pub mod handlers;
pub mod models; pub mod models;
// pub mod schema; // pub mod schema;

View File

@ -2,46 +2,9 @@
#[macro_use] extern crate mime; #[macro_use] extern crate mime;
use env_logger; use env_logger;
use iron::prelude::Iron;
use handlebars as hbs; use media_collection_crud::{chain, handlers, db};
use handlebars_iron as hbi;
use hbs::Handlebars;
use hbi::{DirectorySource, HandlebarsEngine};
use iron::prelude::{Chain, Iron};
use std::error::Error;
use std::sync::Arc;
use media_collection_crud::{chain, db};
fn init_templating() -> Chain {
let views_ext = ".hbs";
let views_path = "./src/views";
let hbs = Handlebars::new();
let mut hbse = HandlebarsEngine::from(hbs);
// TODO: Investigate serving the templates out of the binary using include_string!
hbse.add(Box::new(
DirectorySource::new(views_path, views_ext)
));
if let Err(r) = hbse.reload() {
panic!("{:?}", r.description());
}
let hbse_ref = Arc::new(hbse);
if cfg!(debug_assertions) {
println!("Templates are being watched.");
use hbi::Watchable;
hbse_ref.watch(views_path);
}
let mut chain = chain::init();
chain.link_after(hbse_ref);
chain
}
fn main() { fn main() {
env_logger::init(); env_logger::init();
@ -50,7 +13,11 @@ fn main() {
let port = 8000; let port = 8000;
let bind_addr = format!("localhost:{}", port); let bind_addr = format!("localhost:{}", port);
let _server_guard = Iron::new(init_templating()) let mut chain = chain::init();
let templating_engine = handlers::template_engine().clone();
chain.link_after(templating_engine);
let _server_guard = Iron::new(chain)
.http(bind_addr.as_str()) .http(bind_addr.as_str())
.unwrap(); .unwrap();
} }

View File

@ -2,7 +2,7 @@ use diesel::Queryable;
// use crate::schema::*; // use crate::schema::*;
#[derive(Queryable)] #[derive(Debug, Queryable)]
// #[table_name="media"] // #[table_name="media"]
pub struct Media { pub struct Media {
pub id: u32, pub id: u32,
@ -10,7 +10,7 @@ pub struct Media {
pub notes: String, pub notes: String,
} }
#[derive(Queryable)] #[derive(Debug, Queryable)]
// #[table_name="media_type"] // #[table_name="media_type"]
pub struct MediaType { pub struct MediaType {
pub id: u32, pub id: u32,
@ -18,7 +18,7 @@ pub struct MediaType {
pub description: String, pub description: String,
} }
#[derive(Queryable)] #[derive(Debug, Queryable)]
// #[table_name="media_format"] // #[table_name="media_format"]
pub struct MediaFormat { pub struct MediaFormat {
pub id: u32, pub id: u32,
@ -27,7 +27,7 @@ pub struct MediaFormat {
pub description: String, pub description: String,
} }
#[derive(Queryable)] #[derive(Debug, Queryable)]
pub struct MediaTypeFormatLink { pub struct MediaTypeFormatLink {
pub media_type_id: i32, pub media_type_id: i32,
pub media_format_id: i32, pub media_format_id: i32,

3
src/views/footer.hbs Normal file
View File

@ -0,0 +1,3 @@
<footer>
<p>&copy; Timothy J. Warren</p>
</footer>

3
src/views/header.hbs Normal file
View File

@ -0,0 +1,3 @@
<header>
<h1>Media Collection CRUD</h1>
</header>

View File

@ -1,13 +1,4 @@
<!DOCTYPE html> <main>
<html lang="en"> <h2>Index Page</h2>
<head> <p>Testing rendering of internal content.</p>
<meta charset="utf-8" /> </main>
<title>Rust web server</title>
<link rel="stylesheet" href="/public/css/mini-default.min.css" />
</head>
<body>
<header>
<h1>Hello, world!</h1>
</header>
</body>
</html>

View File

@ -1,15 +1,5 @@
<!DOCTYPE html> {{> layout/top}}
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{#title}}Rust web server{{/title}}</title>
<link rel="stylesheet" href="/public/css/mini-default.min.css" />
</head>
<body>
{{> header}} {{> header}}
{{#block "content"}} {{~ page}}
Some default content
{{/block}}
{{> footer}} {{> footer}}
</body> {{> layout/bottom}}
</html>

View File

@ -0,0 +1,2 @@
</body>
</html>

8
src/views/layout/top.hbs Normal file
View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{{title}}</title>
<link rel="stylesheet" href="/public/css/mini-default.min.css" />
</head>
<body>