diff --git a/Cargo.lock b/Cargo.lock index 549773fe..5003e5b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1900,6 +1900,12 @@ version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +[[package]] +name = "relative-path" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65aff7c83039e88c1c0b4bedf8dfa93d6ec84d5fc2945b37c1fa4186f46c5f94" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -2179,6 +2185,7 @@ dependencies = [ "link_checker", "minify-html", "rayon", + "relative-path", "sass-rs", "search", "serde", @@ -2981,6 +2988,7 @@ dependencies = [ "lazy_static", "notify", "open", + "relative-path", "site", "termcolor", "tokio", diff --git a/Cargo.toml b/Cargo.toml index e0e217f3..6fc4a8cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ ws = "0.9" ctrlc = "3" open = "1.2" globset = "0.4" +relative-path = "1" site = { path = "components/site" } errors = { path = "components/errors" } diff --git a/components/site/Cargo.toml b/components/site/Cargo.toml index 53001d75..ceda391d 100644 --- a/components/site/Cargo.toml +++ b/components/site/Cargo.toml @@ -14,6 +14,7 @@ serde = "1" serde_derive = "1" sass-rs = "0.2" lazy_static = "1.1" +relative-path = "1" errors = { path = "../errors" } config = { path = "../config" } diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index 8084ef47..01e0c97b 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -19,6 +19,7 @@ use config::{get_config, Config}; use errors::{bail, Error, Result}; use front_matter::InsertAnchor; use library::{find_taxonomies, Library, Page, Paginator, Section, Taxonomy}; +use relative_path::RelativePathBuf; use templates::render_redirect_template; use utils::fs::{ copy_directory, copy_file_if_needed, create_directory, create_file, ensure_directory_exists, @@ -28,7 +29,7 @@ use utils::templates::render_template; lazy_static! { /// The in-memory rendered map content - pub static ref SITE_CONTENT: Arc>> = Arc::new(RwLock::new(HashMap::new())); + pub static ref SITE_CONTENT: Arc>> = Arc::new(RwLock::new(HashMap::new())); } /// Where are we building the site @@ -513,10 +514,12 @@ impl Site { let write_dirs = self.build_mode == BuildMode::Disk || create_dirs; ensure_directory_exists(&self.output_path)?; + let mut site_path = RelativePathBuf::new(); let mut current_path = self.output_path.to_path_buf(); for component in components { current_path.push(component); + site_path.push(component); if !current_path.exists() && write_dirs { create_directory(¤t_path)?; @@ -542,17 +545,10 @@ impl Site { create_file(&end_path, &final_content)?; } BuildMode::Memory => { - let path = if filename != "index.html" { - let p = current_path.join(filename); - p.as_os_str().to_string_lossy().replace("public/", "/") - } else { - // TODO" remove unwrap - let p = current_path.strip_prefix(&self.output_path).unwrap(); - p.as_os_str().to_string_lossy().into_owned() - } - .trim_end_matches('/') - .to_owned(); - &SITE_CONTENT.write().unwrap().insert(path, final_content); + let site_path = + if filename != "index.html" { site_path.join(filename) } else { site_path }; + + &SITE_CONTENT.write().unwrap().insert(site_path, final_content); } } @@ -568,12 +564,8 @@ impl Site { let output = page.render_html(&self.tera, &self.config, &self.library.read().unwrap())?; let content = self.inject_livereload(output); let components: Vec<&str> = page.path.split('/').collect(); - let current_path = self.write_content( - &components, - "index.html", - content, - !page.assets.is_empty(), - )?; + let current_path = + self.write_content(&components, "index.html", content, !page.assets.is_empty())?; // Copy any asset we found previously into the same directory as the index.html for asset in &page.assets { @@ -932,11 +924,7 @@ impl Site { if section.meta.generate_feed { let library = &self.library.read().unwrap(); - let pages = section - .pages - .iter() - .map(|k| library.get_page_by_key(*k)) - .collect(); + let pages = section.pages.iter().map(|k| library.get_page_by_key(*k)).collect(); self.render_feed( pages, Some(&PathBuf::from(§ion.path[1..])), diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 654fb374..3dcd55db 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -38,6 +38,7 @@ use ws::{Message, Sender, WebSocket}; use errors::{Error as ZolaError, Result}; use globset::GlobSet; +use relative_path::{RelativePath, RelativePathBuf}; use site::sass::compile_sass; use site::{Site, SITE_CONTENT}; use utils::fs::copy_file; @@ -69,7 +70,12 @@ static NOT_FOUND_TEXT: &[u8] = b"Not Found"; const LIVE_RELOAD: &str = include_str!("livereload.js"); async fn handle_request(req: Request, root: PathBuf) -> Result> { - let path = req.uri().path().trim_end_matches('/').trim_start_matches('/'); + let mut path = RelativePathBuf::new(); + + for c in req.uri().path().split('/') { + path.push(c); + } + // livereload.js is served using the LIVE_RELOAD str, not a file if path == "livereload.js" { if req.method() == Method::GET { @@ -79,7 +85,7 @@ async fn handle_request(req: Request, root: PathBuf) -> Result, root: PathBuf) -> Result return Ok(method_not_allowed()), ResolveResult::NotFound | ResolveResult::UriNotMatched => { - let content_404 = SITE_CONTENT.read().unwrap().get("404.html").map(|x| x.clone()); + let not_found_path = RelativePath::new("404.html"); + let content_404 = SITE_CONTENT.read().unwrap().get(not_found_path).map(|x| x.clone()); return Ok(not_found(content_404)); } _ => (),