diff --git a/default_environment/templates/html/blog_post_page.dust b/default_environment/templates/html/blog_post_page.dust
new file mode 100644
index 0000000..eac6770
--- /dev/null
+++ b/default_environment/templates/html/blog_post_page.dust
@@ -0,0 +1,5 @@
+
diff --git a/default_environment/templates/html/main.dust b/default_environment/templates/html/main.dust
index 2d07f56..eba851f 100644
--- a/default_environment/templates/html/main.dust
+++ b/default_environment/templates/html/main.dust
@@ -2,8 +2,16 @@
+ {#global_settings.css_files}{/global_settings.css_files}
+ {#global_settings.js_files}{/global_settings.js_files}
+ {?global_settings.page_title}{global_settings.page_title}{/global_settings.page_title}
- Hello world!
+
+ {@select key=.type}
+ {@eq value="blog_post_page"}{>blog_post_page/}{/eq}
+ {@none}{!TODO: make this panic!}ERROR: Unrecognized page content type{/none}
+ {/select}
+
diff --git a/src/blog_post/convert.rs b/src/blog_post/convert.rs
index 8c17621..7d2dcaa 100644
--- a/src/blog_post/convert.rs
+++ b/src/blog_post/convert.rs
@@ -1,3 +1,4 @@
+use super::render_context::GlobalSettings;
use super::render_context::RenderBlogPostPage;
use super::BlogPost;
use super::BlogPostPage;
@@ -5,6 +6,7 @@ use super::BlogPostPage;
pub(crate) fn convert_blog_post_page_to_render_context(
_post: &BlogPost,
page: &BlogPostPage,
+ global_settings: GlobalSettings,
) -> RenderBlogPostPage {
- RenderBlogPostPage::new(page.title.clone())
+ RenderBlogPostPage::new(global_settings, page.title.clone())
}
diff --git a/src/blog_post/mod.rs b/src/blog_post/mod.rs
index bd4e010..2b6790c 100644
--- a/src/blog_post/mod.rs
+++ b/src/blog_post/mod.rs
@@ -5,3 +5,4 @@ mod render_context;
pub(crate) use convert::convert_blog_post_page_to_render_context;
pub(crate) use definition::BlogPost;
pub(crate) use page::BlogPostPage;
+pub(crate) use render_context::GlobalSettings;
diff --git a/src/blog_post/render_context.rs b/src/blog_post/render_context.rs
index fb56b61..8015ece 100644
--- a/src/blog_post/render_context.rs
+++ b/src/blog_post/render_context.rs
@@ -1,14 +1,46 @@
use serde::Serialize;
+/// The settings that a "global" to a single dustjs render.
+#[derive(Debug, Serialize)]
+pub(crate) struct GlobalSettings {
+ /// The title that goes in the html tag in the .
+ page_title: Option,
+ css_files: Vec,
+ js_files: Vec,
+}
+
+impl GlobalSettings {
+ pub(crate) fn new(
+ page_title: Option,
+ css_files: Vec,
+ js_files: Vec,
+ ) -> GlobalSettings {
+ GlobalSettings {
+ page_title,
+ css_files,
+ js_files,
+ }
+ }
+}
+
#[derive(Debug, Serialize)]
#[serde(tag = "type")]
#[serde(rename = "blog_post_page")]
pub(crate) struct RenderBlogPostPage {
+ global_settings: GlobalSettings,
+
+ /// The title that will be shown visibly on the page.
title: Option,
}
impl RenderBlogPostPage {
- pub(crate) fn new(title: Option) -> RenderBlogPostPage {
- RenderBlogPostPage { title }
+ pub(crate) fn new(
+ global_settings: GlobalSettings,
+ title: Option,
+ ) -> RenderBlogPostPage {
+ RenderBlogPostPage {
+ global_settings,
+ title,
+ }
}
}
diff --git a/src/command/build/render.rs b/src/command/build/render.rs
index 1ce1d82..1acd6af 100644
--- a/src/command/build/render.rs
+++ b/src/command/build/render.rs
@@ -1,4 +1,5 @@
use std::ffi::OsStr;
+use std::path::Path;
use std::path::PathBuf;
use include_dir::include_dir;
@@ -6,6 +7,8 @@ use include_dir::Dir;
use crate::blog_post::convert_blog_post_page_to_render_context;
use crate::blog_post::BlogPost;
+use crate::blog_post::GlobalSettings;
+use crate::config::Config;
use crate::error::CustomError;
use crate::render::DusterRenderer;
use crate::render::RendererIntegration;
@@ -27,7 +30,7 @@ impl SiteRenderer {
blog_posts,
}
}
- pub(crate) async fn render_blog_posts(&self) -> Result<(), CustomError> {
+ pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> {
let mut renderer_integration = DusterRenderer::new();
let sources: Vec<_> = MAIN_TEMPLATES
@@ -62,9 +65,25 @@ impl SiteRenderer {
.join("posts")
.join(&blog_post.id)
.join(blog_post_page.get_output_path());
- println!("Output path: {:?}", output_path);
- let render_context =
- convert_blog_post_page_to_render_context(blog_post, blog_post_page);
+ 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(
+ blog_post,
+ blog_post_page,
+ global_settings,
+ );
let rendered_output = renderer_integration.render(render_context)?;
println!("Rendered: {}", rendered_output);
let parent_directory = output_path
@@ -91,3 +110,41 @@ fn build_name_contents_pairs<'a>(
let contents = std::str::from_utf8(entry.contents())?;
Ok((name, contents))
}
+
+fn get_web_path, F: AsRef, P: AsRef>(
+ config: &Config,
+ output_directory: D,
+ containing_file: F,
+ path_from_web_root: P,
+) -> Result {
+ 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)
+ }
+}
diff --git a/src/command/build/runner.rs b/src/command/build/runner.rs
index 7f970bd..bb267f6 100644
--- a/src/command/build/runner.rs
+++ b/src/command/build/runner.rs
@@ -10,7 +10,7 @@ pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> {
let config = Config::load_from_file(args.config).await?;
let blog_posts = load_blog_posts(&config).await?;
let renderer = SiteRenderer::new(get_output_directory(&config).await?, blog_posts);
- renderer.render_blog_posts().await?;
+ renderer.render_blog_posts(&config).await?;
Ok(())
}
diff --git a/src/config/full.rs b/src/config/full.rs
index 0e499f7..0f962aa 100644
--- a/src/config/full.rs
+++ b/src/config/full.rs
@@ -59,4 +59,12 @@ impl Config {
pub(crate) fn get_output_directory(&self) -> PathBuf {
self.get_root_directory().join("output")
}
+
+ pub(crate) fn use_relative_paths(&self) -> bool {
+ self.raw.use_relative_paths.unwrap_or(true)
+ }
+
+ pub(crate) fn get_web_root(&self) -> Option<&str> {
+ self.raw.web_root.as_deref()
+ }
}
diff --git a/src/config/raw.rs b/src/config/raw.rs
index 3d43bd5..b0d95cf 100644
--- a/src/config/raw.rs
+++ b/src/config/raw.rs
@@ -7,6 +7,8 @@ pub(crate) struct RawConfig {
site_title: String,
author: Option,
email: Option,
+ pub(super) use_relative_paths: Option,
+ pub(super) web_root: Option,
}
impl Default for RawConfig {
@@ -15,6 +17,8 @@ impl Default for RawConfig {
site_title: "My super awesome website".to_owned(),
author: None,
email: None,
+ use_relative_paths: None,
+ web_root: None,
}
}
}