Skip to content

Commit

Permalink
fix: made build paths possible on index page
Browse files Browse the repository at this point in the history
I think there's one issue left here...
  • Loading branch information
arctic-hen7 committed Nov 4, 2022
1 parent a329952 commit 18bd1bf
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 25 deletions.
6 changes: 6 additions & 0 deletions examples/core/basic/src/templates/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub fn get_template<G: Html>() -> Template<G> {
.build_state_fn(get_build_state)
.template(index_page)
.head(head)
.build_paths_fn(build_paths)
}

#[perseus::head]
Expand All @@ -37,3 +38,8 @@ pub async fn get_build_state(
greeting: "Hello World!".to_string(),
})
}

#[perseus::build_paths]
async fn build_paths() -> perseus::prelude::RenderFnResult<Vec<String>> {
Ok(vec!["".to_string(), "a test".to_string()])
}
19 changes: 17 additions & 2 deletions packages/perseus/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,25 @@ async fn gen_state_for_path(
// save it as a file
let full_path_without_locale = match template.uses_build_paths() {
true => format!("{}/{}", &template_path, path),
// // If we're using build paths on the root template, make sure we don't end up with `index/...`
// true => if template_path == "index" {
// path.to_string()
// } else {
// format!("{}/{}", &template_path, path)
// },
// We don't want to concatenate the name twice if we don't have to
false => template_path.clone(),
};
// Strip trailing `/`s for the reasons described above
// Strip leading/trailing `/`s for the reasons described above
// Leading is to handle index pages with build paths
let full_path_without_locale = match full_path_without_locale.strip_suffix('/') {
Some(stripped) => stripped.to_string(),
None => full_path_without_locale,
};
let full_path_without_locale = match full_path_without_locale.strip_prefix('/') {
Some(stripped) => stripped.to_string(),
None => full_path_without_locale,
};
// Add the current locale to the front of that and encode it as a URL so we can
// store a flat series of files BUG: insanely nested paths won't work
// whatsoever if the filename is too long, maybe hash instead?
Expand Down Expand Up @@ -287,11 +298,15 @@ pub async fn build_template_and_get_cfg(
// Add each page that the template explicitly generated (ignoring ISR for now)
for page in pages {
let path = format!("{}/{}", &template_root_path, &page);
// Remove any trailing `/`s for the reasons described above
// Remove any leading/trailing `/`s for the reasons described above
let path = match path.strip_suffix('/') {
Some(stripped) => stripped.to_string(),
None => path,
};
let path = match path.strip_prefix('/') {
Some(stripped) => stripped.to_string(),
None => path,
};
render_cfg.insert(path, template_root_path.clone());
}
// Now if the page uses ISR, add an explicit `/*` in there after the template
Expand Down
15 changes: 8 additions & 7 deletions packages/perseus/src/router/get_subsequent_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,14 @@ pub(crate) async fn get_subsequent_view(
// We only have one part of the puzzle (or nothing at all), and no guarantee that the other
// doesn't exist, so we'll have to check with the server to be safe
PssContains::State | PssContains::Head | PssContains::None => {
// If we're getting data about the index page, explicitly set it to that
// This can be handled by the Perseus server (and is), but not by static
// exporting
let path_norm = match path.is_empty() {
true => "index".to_string(),
false => path.to_string(),
};
// // If we're getting data about the index page, explicitly set it to that
// // This can be handled by the Perseus server (and is), but not by static
// // exporting
// let path_norm = match path.is_empty() {
// true => "index".to_string(),
// false => path.to_string(),
// };
let path_norm = path.to_string();
// Get the static page data (head and state)
let asset_url = format!(
"{}/.perseus/page/{}/{}.json?template_name={}&was_incremental_match={}",
Expand Down
22 changes: 11 additions & 11 deletions packages/perseus/src/router/match_route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ use std::rc::Rc;
/// `Arc` and `Rc` versions.
macro_rules! get_template_for_path {
($raw_path:expr, $render_cfg:expr, $templates:expr) => {{
let mut path = $raw_path;
// If the path is empty, we're looking for the special `index` page
if path.is_empty() {
path = "index";
}
let path = $raw_path;
// // If the path is empty, we're looking for the special `index` page
// if path.is_empty() {
// path = "index";
// }

let mut was_incremental_match = false;
// Match the path to one of the templates
let mut template_name = String::new();
let mut template_name = None;
// We'll try a direct match first
if let Some(template_root_path) = $render_cfg.get(path) {
template_name = template_root_path.to_string();
template_name = Some(template_root_path.to_string());
}
// Next, an ISR match (more complex), which we only want to run if we didn't get
// an exact match above
if template_name.is_empty() {
if template_name.is_none() {
// We progressively look for more and more specificity of the path, adding each
// segment That way, we're searching forwards rather than backwards,
// which is more efficient
Expand All @@ -36,20 +36,20 @@ macro_rules! get_template_for_path {
// If we find something, keep going until we don't (maximize specificity)
if let Some(template_root_path) = $render_cfg.get(&path_to_try) {
was_incremental_match = true;
template_name = template_root_path.to_string();
template_name = Some(template_root_path.to_string());
} else {
break;
}
}
}
// If we still have nothing, then the page doesn't exist
if template_name.is_empty() {
if template_name.is_none() {
return (None, was_incremental_match);
}

// Return the necessary info for the caller to get the template in a form it
// wants (might be an `Rc` of a reference)
(template_name, was_incremental_match)
(template_name.unwrap(), was_incremental_match)
}};
}

Expand Down
9 changes: 5 additions & 4 deletions packages/perseus/src/state/page_state_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,11 @@ impl PageStateStore {
// If we're getting data about the index page, explicitly set it to that
// This can be handled by the Perseus server (and is), but not by static
// exporting
let path_norm = match path.is_empty() {
true => "index".to_string(),
false => path.to_string(),
};
// let path_norm = match path.is_empty() {
// true => "index".to_string(),
// false => path.to_string(),
// };
let path_norm = path.to_string();
// Get the static page data (head and state)
let asset_url = format!(
"{}/.perseus/page/{}/{}.json?template_name={}&was_incremental_match={}",
Expand Down
8 changes: 7 additions & 1 deletion packages/perseus/src/template/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,14 @@ impl<G: Html> Template<G> {
/// Gets the path of the template. This is the root path under which any
/// generated pages will be served. In the simplest case, there will
/// only be one page rendered, and it will occupy that root position.
///
/// Note that this will automatically transform `index` to an empty string.
pub fn get_path(&self) -> String {
self.path.clone()
if self.path == "index" {
String::new()
} else {
self.path.clone()
}
}
/// Gets the interval after which the template will next revalidate.
#[cfg(not(target_arch = "wasm32"))]
Expand Down

0 comments on commit 18bd1bf

Please sign in to comment.