Compare commits
5 Commits
178ce877bc
...
2413923b3f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2413923b3f | ||
![]() |
ab36a60545 | ||
![]() |
68cae57f16 | ||
![]() |
11bfb6836f | ||
![]() |
3ac7826d2c |
@ -1,5 +1,5 @@
|
|||||||
<div class="blog_post">
|
<div class="blog_post">
|
||||||
<div class="blog_post_intro">
|
<div class="blog_post_intro">
|
||||||
|
{?.title}{?.self_link}<a class="blog_post_title" href="{.link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,12 +1,132 @@
|
|||||||
|
use std::path::Component;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::error::CustomError;
|
||||||
|
|
||||||
use super::render_context::GlobalSettings;
|
use super::render_context::GlobalSettings;
|
||||||
use super::render_context::RenderBlogPostPage;
|
use super::render_context::RenderBlogPostPage;
|
||||||
use super::BlogPost;
|
use super::BlogPost;
|
||||||
use super::BlogPostPage;
|
use super::BlogPostPage;
|
||||||
|
|
||||||
pub(crate) fn convert_blog_post_page_to_render_context(
|
pub(crate) fn convert_blog_post_page_to_render_context<D: AsRef<Path>, F: AsRef<Path>>(
|
||||||
|
config: &Config,
|
||||||
|
output_directory: D,
|
||||||
|
output_file: F,
|
||||||
_post: &BlogPost,
|
_post: &BlogPost,
|
||||||
page: &BlogPostPage,
|
page: &BlogPostPage,
|
||||||
global_settings: GlobalSettings,
|
) -> Result<RenderBlogPostPage, CustomError> {
|
||||||
) -> RenderBlogPostPage {
|
let output_directory = output_directory.as_ref();
|
||||||
RenderBlogPostPage::new(global_settings, page.title.clone())
|
let output_file = output_file.as_ref();
|
||||||
|
let css_files = vec![get_web_path(
|
||||||
|
config,
|
||||||
|
output_directory,
|
||||||
|
output_file,
|
||||||
|
"main.css",
|
||||||
|
)?];
|
||||||
|
let js_files = vec![get_web_path(
|
||||||
|
config,
|
||||||
|
output_directory,
|
||||||
|
output_file,
|
||||||
|
"blog_post.js",
|
||||||
|
)?];
|
||||||
|
let global_settings = GlobalSettings::new(page.title.clone(), css_files, js_files);
|
||||||
|
let link_to_blog_post = get_web_path(
|
||||||
|
config,
|
||||||
|
output_directory,
|
||||||
|
output_file,
|
||||||
|
output_file.strip_prefix(output_directory)?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let ret = RenderBlogPostPage::new(global_settings, page.title.clone(), Some(link_to_blog_post));
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_web_path<D: AsRef<Path>, F: AsRef<Path>, P: AsRef<Path>>(
|
||||||
|
config: &Config,
|
||||||
|
output_directory: D,
|
||||||
|
containing_file: F,
|
||||||
|
path_from_web_root: P,
|
||||||
|
) -> Result<String, CustomError> {
|
||||||
|
let path_from_web_root = path_from_web_root.as_ref();
|
||||||
|
if config.use_relative_paths() {
|
||||||
|
let output_directory = output_directory.as_ref();
|
||||||
|
let containing_file = containing_file.as_ref();
|
||||||
|
let containing_file_relative_to_output_directory =
|
||||||
|
containing_file.strip_prefix(output_directory)?;
|
||||||
|
let shared_stem = get_shared_steps(
|
||||||
|
containing_file_relative_to_output_directory
|
||||||
|
.parent()
|
||||||
|
.ok_or("File should exist in a folder.")?,
|
||||||
|
path_from_web_root
|
||||||
|
.parent()
|
||||||
|
.ok_or("File should exist in a folder.")?,
|
||||||
|
)
|
||||||
|
.collect::<PathBuf>();
|
||||||
|
// Subtracting 1 from the depth to "remove" the file name.
|
||||||
|
let depth_from_shared_stem = containing_file_relative_to_output_directory
|
||||||
|
.strip_prefix(&shared_stem)?
|
||||||
|
.components()
|
||||||
|
.count()
|
||||||
|
- 1;
|
||||||
|
let final_path = PathBuf::from("../".repeat(depth_from_shared_stem))
|
||||||
|
.join(path_from_web_root.strip_prefix(shared_stem)?);
|
||||||
|
let final_string = final_path
|
||||||
|
.as_path()
|
||||||
|
.to_str()
|
||||||
|
.map(str::to_string)
|
||||||
|
.ok_or("Path should be valid utf-8.")?;
|
||||||
|
Ok(final_string)
|
||||||
|
} else {
|
||||||
|
let web_root = config
|
||||||
|
.get_web_root()
|
||||||
|
.ok_or("Must either use_relative_paths or set the web_root in the config.")?;
|
||||||
|
let final_path = PathBuf::from(web_root).join(path_from_web_root);
|
||||||
|
let final_string = final_path
|
||||||
|
.as_path()
|
||||||
|
.to_str()
|
||||||
|
.map(str::to_string)
|
||||||
|
.ok_or("Path should be valid utf-8.")?;
|
||||||
|
Ok(final_string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_shared_steps<'a>(left: &'a Path, right: &'a Path) -> impl Iterator<Item = Component<'a>> {
|
||||||
|
let shared_stem = left
|
||||||
|
.components()
|
||||||
|
.zip(right.components())
|
||||||
|
.take_while(|(l, r)| l == r)
|
||||||
|
.map(|(l, _r)| l);
|
||||||
|
shared_stem
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_shared_steps() {
|
||||||
|
assert_eq!(
|
||||||
|
get_shared_steps(Path::new(""), Path::new("")).collect::<PathBuf>(),
|
||||||
|
PathBuf::from("")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_shared_steps(Path::new("foo.txt"), Path::new("foo.txt")).collect::<PathBuf>(),
|
||||||
|
PathBuf::from("foo.txt")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_shared_steps(Path::new("cat/foo.txt"), Path::new("dog/foo.txt"))
|
||||||
|
.collect::<PathBuf>(),
|
||||||
|
PathBuf::from("")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
get_shared_steps(
|
||||||
|
Path::new("foo/bar/baz/lorem.txt"),
|
||||||
|
Path::new("foo/bar/ipsum/dolar.txt")
|
||||||
|
)
|
||||||
|
.collect::<PathBuf>(),
|
||||||
|
PathBuf::from("foo/bar")
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ impl BlogPost {
|
|||||||
root_dir: R,
|
root_dir: R,
|
||||||
post_dir: P,
|
post_dir: P,
|
||||||
) -> Result<BlogPost, CustomError> {
|
) -> Result<BlogPost, CustomError> {
|
||||||
async fn inner(root_dir: &Path, post_dir: &Path) -> Result<BlogPost, CustomError> {
|
async fn inner(_root_dir: &Path, post_dir: &Path) -> Result<BlogPost, CustomError> {
|
||||||
let post_id = post_dir
|
let post_id = post_dir
|
||||||
.file_name()
|
.file_name()
|
||||||
.expect("The post directory should have a name.");
|
.expect("The post directory should have a name.");
|
||||||
|
@ -5,4 +5,3 @@ mod render_context;
|
|||||||
pub(crate) use convert::convert_blog_post_page_to_render_context;
|
pub(crate) use convert::convert_blog_post_page_to_render_context;
|
||||||
pub(crate) use definition::BlogPost;
|
pub(crate) use definition::BlogPost;
|
||||||
pub(crate) use page::BlogPostPage;
|
pub(crate) use page::BlogPostPage;
|
||||||
pub(crate) use render_context::GlobalSettings;
|
|
||||||
|
@ -31,16 +31,20 @@ pub(crate) struct RenderBlogPostPage {
|
|||||||
|
|
||||||
/// The title that will be shown visibly on the page.
|
/// The title that will be shown visibly on the page.
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
|
|
||||||
|
self_link: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBlogPostPage {
|
impl RenderBlogPostPage {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
global_settings: GlobalSettings,
|
global_settings: GlobalSettings,
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
|
self_link: Option<String>,
|
||||||
) -> RenderBlogPostPage {
|
) -> RenderBlogPostPage {
|
||||||
RenderBlogPostPage {
|
RenderBlogPostPage {
|
||||||
global_settings,
|
global_settings,
|
||||||
title,
|
title,
|
||||||
|
self_link,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use include_dir::include_dir;
|
use include_dir::include_dir;
|
||||||
@ -7,7 +6,6 @@ use include_dir::Dir;
|
|||||||
|
|
||||||
use crate::blog_post::convert_blog_post_page_to_render_context;
|
use crate::blog_post::convert_blog_post_page_to_render_context;
|
||||||
use crate::blog_post::BlogPost;
|
use crate::blog_post::BlogPost;
|
||||||
use crate::blog_post::GlobalSettings;
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::render::DusterRenderer;
|
use crate::render::DusterRenderer;
|
||||||
@ -65,25 +63,14 @@ impl SiteRenderer {
|
|||||||
.join("posts")
|
.join("posts")
|
||||||
.join(&blog_post.id)
|
.join(&blog_post.id)
|
||||||
.join(blog_post_page.get_output_path());
|
.join(blog_post_page.get_output_path());
|
||||||
let css_files = vec![get_web_path(
|
|
||||||
config,
|
|
||||||
&self.output_directory,
|
|
||||||
&output_path,
|
|
||||||
"main.css",
|
|
||||||
)?];
|
|
||||||
let js_files = vec![get_web_path(
|
|
||||||
config,
|
|
||||||
&self.output_directory,
|
|
||||||
&output_path,
|
|
||||||
"blog_post.js",
|
|
||||||
)?];
|
|
||||||
let global_settings =
|
|
||||||
GlobalSettings::new(blog_post_page.title.clone(), css_files, js_files);
|
|
||||||
let render_context = convert_blog_post_page_to_render_context(
|
let render_context = convert_blog_post_page_to_render_context(
|
||||||
|
config,
|
||||||
|
&self.output_directory,
|
||||||
|
&output_path,
|
||||||
blog_post,
|
blog_post,
|
||||||
blog_post_page,
|
blog_post_page,
|
||||||
global_settings,
|
)?;
|
||||||
);
|
|
||||||
let rendered_output = renderer_integration.render(render_context)?;
|
let rendered_output = renderer_integration.render(render_context)?;
|
||||||
println!("Rendered: {}", rendered_output);
|
println!("Rendered: {}", rendered_output);
|
||||||
let parent_directory = output_path
|
let parent_directory = output_path
|
||||||
@ -110,41 +97,3 @@ fn build_name_contents_pairs<'a>(
|
|||||||
let contents = std::str::from_utf8(entry.contents())?;
|
let contents = std::str::from_utf8(entry.contents())?;
|
||||||
Ok((name, contents))
|
Ok((name, contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_web_path<D: AsRef<Path>, F: AsRef<Path>, P: AsRef<Path>>(
|
|
||||||
config: &Config,
|
|
||||||
output_directory: D,
|
|
||||||
containing_file: F,
|
|
||||||
path_from_web_root: P,
|
|
||||||
) -> Result<String, CustomError> {
|
|
||||||
let path_from_web_root = path_from_web_root.as_ref();
|
|
||||||
if config.use_relative_paths() {
|
|
||||||
let output_directory = output_directory.as_ref();
|
|
||||||
let containing_file = containing_file.as_ref();
|
|
||||||
// Subtracting 1 from the depth to "remove" the file name.
|
|
||||||
let depth_from_web_root = containing_file
|
|
||||||
.strip_prefix(output_directory)?
|
|
||||||
.components()
|
|
||||||
.count()
|
|
||||||
- 1;
|
|
||||||
let prefix = "../".repeat(depth_from_web_root);
|
|
||||||
let final_path = PathBuf::from(prefix).join(path_from_web_root);
|
|
||||||
let final_string = final_path
|
|
||||||
.as_path()
|
|
||||||
.to_str()
|
|
||||||
.map(str::to_string)
|
|
||||||
.ok_or("Path should be valid utf-8.")?;
|
|
||||||
Ok(final_string)
|
|
||||||
} else {
|
|
||||||
let web_root = config
|
|
||||||
.get_web_root()
|
|
||||||
.ok_or("Must either use_relative_paths or set the web_root in the config.")?;
|
|
||||||
let final_path = PathBuf::from(web_root).join(path_from_web_root);
|
|
||||||
let final_string = final_path
|
|
||||||
.as_path()
|
|
||||||
.to_str()
|
|
||||||
.map(str::to_string)
|
|
||||||
.ok_or("Path should be valid utf-8.")?;
|
|
||||||
Ok(final_string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user